From 27d2848e0096d31cb42cb258a89ed276ec26434e Mon Sep 17 00:00:00 2001 From: Krzysztof Wolicki Der Teufel Date: Tue, 7 Mar 2023 00:22:48 +0100 Subject: [PATCH 001/216] autodoc: Add struct to tryResolveRefPath fix rendering of fieldRef in exprName --- lib/docs/main.js | 6 +++--- src/Autodoc.zig | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/docs/main.js b/lib/docs/main.js index fc99b2f861..4b946eb963 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1139,9 +1139,9 @@ const NAV_MODES = { return exprName(switchIndex, opts); } case "fieldRef": { - const enumObj = exprName({ type: expr.fieldRef.type }, opts); - const field = - getAstNode(enumObj.src).fields[expr.fieldRef.index]; + const field_idx = expr.fieldRef.index; + const type = getType(expr.fieldRef.type); + const field = getAstNode(type.src).fields[field_idx]; const name = getAstNode(field).name; return name; } diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 15d90b104b..47b0c8d3c2 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -3616,6 +3616,25 @@ fn tryResolveRefPath( continue :outer; }, }, + .@"struct" => |st| { + for (st) |field| { + if (std.mem.eql(u8, field.name, child_string)) { + path[i + 1] = field.val.expr; + continue :outer; + } + } + + // if we got here, our search failed + printWithContext( + file, + inst_index, + "failed to match `{s}` in struct", + .{child_string}, + ); + + path[i + 1] = (try self.cteTodo("match failure")).expr; + continue :outer; + }, } } From 6d74c0d1b41b52bca3d66092a48660f2ee4ae4f8 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 8 Mar 2023 00:57:39 -0800 Subject: [PATCH 002/216] Add comments explaining BUFFER_OVERFLOW during NtQueryInformationFile calls --- lib/std/fs/file.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index bf93a61239..5306909aea 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -379,6 +379,9 @@ pub const File = struct { const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation); switch (rc) { .SUCCESS => {}, + // Buffer overflow here indicates that there is more information available than was able to be stored in the buffer + // size provided. This is treated as success because the type of variable-length information that this would be relevant for + // (name, volume name, etc) we don't care about. .BUFFER_OVERFLOW => {}, .INVALID_PARAMETER => unreachable, .ACCESS_DENIED => return error.AccessDenied, @@ -830,6 +833,9 @@ pub const File = struct { const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation); switch (rc) { .SUCCESS => {}, + // Buffer overflow here indicates that there is more information available than was able to be stored in the buffer + // size provided. This is treated as success because the type of variable-length information that this would be relevant for + // (name, volume name, etc) we don't care about. .BUFFER_OVERFLOW => {}, .INVALID_PARAMETER => unreachable, .ACCESS_DENIED => return error.AccessDenied, From 93b35c69998398e962bff84f3e5006afa122fbde Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 8 Mar 2023 01:18:33 -0800 Subject: [PATCH 003/216] os.isCygwinPty: Fix a bug, replace kernel32 call, and optimize - Fixes the first few code units of the name being omitted (it was using `@sizeOf(FILE_NAME_INFO)` as the start of the name bytes, but that includes the length of the dummy [1]u16 field and padding; instead the start should be the offset of the dummy [1]u16 field) - Replaces kernel32.GetFileInformationByHandleEx call with ntdll.NtQueryInformationFile + Contributes towards #1840 - Checks that the handle is a named pipe first before querying and checking the name, which is a much faster call than NtQueryInformationFile (this was about a 10x speedup in my probably-not-so-good/take-it-with-a-grain-of-salt benchmarking) --- lib/std/os.zig | 48 +++++++++++++++++++++++++++--------- lib/std/os/windows.zig | 23 +++++++++++++++++ lib/std/os/windows/ntdll.zig | 9 +++++++ 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 821c544cc8..f69532cc49 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -3217,22 +3217,48 @@ pub fn isatty(handle: fd_t) bool { pub fn isCygwinPty(handle: fd_t) bool { if (builtin.os.tag != .windows) return false; - const size = @sizeOf(windows.FILE_NAME_INFO); - var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (size + windows.MAX_PATH); + // If this is a MSYS2/cygwin pty, then it will be a named pipe with a name in one of these formats: + // msys-[...]-ptyN-[...] + // cygwin-[...]-ptyN-[...] + // + // Example: msys-1888ae32e00d56aa-pty0-to-master - if (windows.kernel32.GetFileInformationByHandleEx( - handle, - windows.FileNameInfo, - @ptrCast(*anyopaque, &name_info_bytes), - name_info_bytes.len, - ) == 0) { - return false; + // First, just check that the handle is a named pipe. + // This allows us to avoid the more costly NtQueryInformationFile call + // for handles that aren't named pipes. + { + var io_status: windows.IO_STATUS_BLOCK = undefined; + var device_info: windows.FILE_FS_DEVICE_INFORMATION = undefined; + const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE_FS_DEVICE_INFORMATION), .FileFsDeviceInformation); + switch (rc) { + .SUCCESS => {}, + else => return false, + } + if (device_info.DeviceType != windows.FILE_DEVICE_NAMED_PIPE) return false; + } + + const name_bytes_offset = @offsetOf(windows.FILE_NAME_INFO, "FileName"); + // `NAME_MAX` UTF-16 code units (2 bytes each) + // Note: This buffer may not be long enough to handle *all* possible paths (PATH_MAX_WIDE would be necessary for that), + // but because we only care about certain paths and we know they must be within a reasonable length, + // we can use this smaller buffer and just return false on any error from NtQueryInformationFile. + const num_name_bytes = windows.MAX_PATH * 2; + var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes); + + var io_status_block: windows.IO_STATUS_BLOCK = undefined; + const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(u32, name_info_bytes.len), .FileNameInformation); + switch (rc) { + .SUCCESS => {}, + .INVALID_PARAMETER => unreachable, + else => return false, } const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]); - const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)]; + const name_bytes = name_info_bytes[name_bytes_offset .. name_bytes_offset + @as(usize, name_info.FileNameLength)]; const name_wide = mem.bytesAsSlice(u16, name_bytes); - return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or + // Note: The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master + return (mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or + mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'c', 'y', 'g', 'w', 'i', 'n', '-' })) and mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; } diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index b63fdb9f92..23aa378e9e 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -2472,6 +2472,29 @@ pub const FILE_INFORMATION_CLASS = enum(c_int) { FileMaximumInformation, }; +pub const FILE_FS_DEVICE_INFORMATION = extern struct { + DeviceType: DEVICE_TYPE, + Characteristics: ULONG, +}; + +pub const FS_INFORMATION_CLASS = enum(c_int) { + FileFsVolumeInformation = 1, + FileFsLabelInformation, + FileFsSizeInformation, + FileFsDeviceInformation, + FileFsAttributeInformation, + FileFsControlInformation, + FileFsFullSizeInformation, + FileFsObjectIdInformation, + FileFsDriverPathInformation, + FileFsVolumeFlagsInformation, + FileFsSectorSizeInformation, + FileFsDataCopyInformation, + FileFsMetadataSizeInformation, + FileFsFullSizeInformationEx, + FileFsMaximumInformation, +}; + pub const OVERLAPPED = extern struct { Internal: ULONG_PTR, InternalHigh: ULONG_PTR, diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 8c5260c1bc..58cba356a2 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -18,6 +18,7 @@ const IO_STATUS_BLOCK = windows.IO_STATUS_BLOCK; const LARGE_INTEGER = windows.LARGE_INTEGER; const OBJECT_INFORMATION_CLASS = windows.OBJECT_INFORMATION_CLASS; const FILE_INFORMATION_CLASS = windows.FILE_INFORMATION_CLASS; +const FS_INFORMATION_CLASS = windows.FS_INFORMATION_CLASS; const UNICODE_STRING = windows.UNICODE_STRING; const RTL_OSVERSIONINFOW = windows.RTL_OSVERSIONINFOW; const FILE_BASIC_INFORMATION = windows.FILE_BASIC_INFORMATION; @@ -232,6 +233,14 @@ pub extern "ntdll" fn NtQueryObject( ReturnLength: ?*ULONG, ) callconv(WINAPI) NTSTATUS; +pub extern "ntdll" fn NtQueryVolumeInformationFile( + FileHandle: HANDLE, + IoStatusBlock: *IO_STATUS_BLOCK, + FsInformation: *anyopaque, + Length: ULONG, + FsInformationClass: FS_INFORMATION_CLASS, +) callconv(WINAPI) NTSTATUS; + pub extern "ntdll" fn RtlWakeAddressAll( Address: ?*const anyopaque, ) callconv(WINAPI) void; From 7e3591bedd41bde8bcca892885376e2f4a8163a3 Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Wed, 8 Mar 2023 19:25:53 +0100 Subject: [PATCH 004/216] std.json.parseInternal: use switches instead of ifs --- lib/std/json.zig | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/lib/std/json.zig b/lib/std/json.zig index 0cce71b1e6..9d24ebaff4 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1534,30 +1534,25 @@ fn parseInternal( child_options.allow_trailing_data = true; var found = false; inline for (structInfo.fields, 0..) |field, i| { - // TODO: using switches here segfault the compiler (#2727?) - if ((stringToken.escapes == .None and mem.eql(u8, field.name, key_source_slice)) or (stringToken.escapes == .Some and (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)))) { - // if (switch (stringToken.escapes) { - // .None => mem.eql(u8, field.name, key_source_slice), - // .Some => (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)), - // }) { + if (switch (stringToken.escapes) { + .None => mem.eql(u8, field.name, key_source_slice), + .Some => (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)), + }) { if (fields_seen[i]) { - // switch (options.duplicate_field_behavior) { - // .UseFirst => {}, - // .Error => {}, - // .UseLast => {}, - // } - if (options.duplicate_field_behavior == .UseFirst) { - // unconditonally ignore value. for comptime fields, this skips check against default_value - parseFree(field.type, try parse(field.type, tokens, child_options), child_options); - found = true; - break; - } else if (options.duplicate_field_behavior == .Error) { - return error.DuplicateJSONField; - } else if (options.duplicate_field_behavior == .UseLast) { - if (!field.is_comptime) { - parseFree(field.type, @field(r, field.name), child_options); - } - fields_seen[i] = false; + switch (options.duplicate_field_behavior) { + .UseFirst => { + // unconditonally ignore value. for comptime fields, this skips check against default_value + parseFree(field.type, try parse(field.type, tokens, child_options), child_options); + found = true; + break; + }, + .Error => return error.DuplicateJSONField, + .UseLast => { + if (!field.is_comptime) { + parseFree(field.type, @field(r, field.name), child_options); + } + fields_seen[i] = false; + }, } } if (field.is_comptime) { From c0789b4814989f2d91d3d2145d227dcdec3e2770 Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Wed, 8 Mar 2023 19:26:03 +0100 Subject: [PATCH 005/216] std.json.stringify: support [*:0]const u8 --- lib/std/json.zig | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/std/json.zig b/lib/std/json.zig index 9d24ebaff4..590040efba 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -2350,10 +2350,13 @@ pub fn stringify( return stringify(value.*, options, out_stream); }, }, - // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972) - .Slice => { - if (ptr_info.child == u8 and options.string == .String and std.unicode.utf8ValidateSlice(value)) { - try encodeJsonString(value, options, out_stream); + .Many, .Slice => { + if (ptr_info.size == .Many and ptr_info.sentinel == null) + @compileError("unable to stringify type '" ++ @typeName(T) ++ "' without sentinel"); + const slice = if (ptr_info.size == .Many) mem.span(value) else value; + + if (ptr_info.child == u8 and options.string == .String and std.unicode.utf8ValidateSlice(slice)) { + try encodeJsonString(slice, options, out_stream); return; } @@ -2362,7 +2365,7 @@ pub fn stringify( if (child_options.whitespace) |*whitespace| { whitespace.indent_level += 1; } - for (value, 0..) |x, i| { + for (slice, 0..) |x, i| { if (i != 0) { try out_stream.writeByte(','); } @@ -2371,7 +2374,7 @@ pub fn stringify( } try stringify(x, child_options, out_stream); } - if (value.len != 0) { + if (slice.len != 0) { if (options.whitespace) |whitespace| { try whitespace.outputIndent(out_stream); } @@ -2526,6 +2529,12 @@ test "stringify string" { try teststringify("\"\\/\"", "/", StringifyOptions{ .string = .{ .String = .{ .escape_solidus = true } } }); } +test "stringify many-item sentinel-terminated string" { + try teststringify("\"hello\"", @as([*:0]const u8, "hello"), StringifyOptions{}); + try teststringify("\"with\\nescapes\\r\"", @as([*:0]const u8, "with\nescapes\r"), StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } }); + try teststringify("\"with unicode\\u0001\"", @as([*:0]const u8, "with unicode\u{1}"), StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } }); +} + test "stringify tagged unions" { try teststringify("42", union(enum) { Foo: u32, @@ -2712,7 +2721,7 @@ test "encodesTo" { try testing.expectEqual(true, encodesTo("withąunicode😂", "with\\u0105unicode\\ud83d\\ude02")); } -test "issue 14600" { +test "deserializing string with escape sequence into sentinel slice" { const json = "\"\\n\""; var token_stream = std.json.TokenStream.init(json); const options = ParseOptions{ .allocator = std.testing.allocator }; From 76afdd0586dc646bee1f20fd9ff23c044d70a211 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Mar 2023 17:11:44 +0100 Subject: [PATCH 006/216] link: move macOS kernel inode cache invalidation to MachO linker --- src/link.zig | 21 +-------------------- src/link/MachO.zig | 17 +++++++++++++++++ src/link/MachO/zld.zig | 1 + 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/link.zig b/src/link.zig index e68f9c97d0..a919ffa999 100644 --- a/src/link.zig +++ b/src/link.zig @@ -418,26 +418,7 @@ pub const File = struct { .Exe => {}, } switch (base.tag) { - .macho => if (base.file) |f| { - if (build_options.only_c) unreachable; - if (comptime builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) { - if (base.options.target.cpu.arch == .aarch64) { - // XNU starting with Big Sur running on arm64 is caching inodes of running binaries. - // Any change to the binary will effectively invalidate the kernel's cache - // resulting in a SIGKILL on each subsequent run. Since when doing incremental - // linking we're modifying a binary in-place, this will end up with the kernel - // killing it on every subsequent run. To circumvent it, we will copy the file - // into a new inode, remove the original file, and rename the copy to match - // the original file. This is super messy, but there doesn't seem any other - // way to please the XNU. - const emit = base.options.emit orelse return; - try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, emit.sub_path, .{}); - } - } - f.close(); - base.file = null; - }, - .coff, .elf, .plan9, .wasm => if (base.file) |f| { + .coff, .elf, .macho, .plan9, .wasm => if (base.file) |f| { if (build_options.only_c) unreachable; if (base.intermediary_basename != null) { // The file we have open is not the final file that we want to diff --git a/src/link/MachO.zig b/src/link/MachO.zig index eaf16e4009..368914e1be 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -662,6 +662,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No if (codesig) |*csig| { try self.writeCodeSignature(comp, csig); // code signing always comes last + const emit = self.base.options.emit.?; + try invalidateKernelCache(emit.directory.handle, emit.sub_path); } if (self.d_sym) |*d_sym| { @@ -691,6 +693,21 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No self.cold_start = false; } + +/// XNU starting with Big Sur running on arm64 is caching inodes of running binaries. +/// Any change to the binary will effectively invalidate the kernel's cache +/// resulting in a SIGKILL on each subsequent run. Since when doing incremental +/// linking we're modifying a binary in-place, this will end up with the kernel +/// killing it on every subsequent run. To circumvent it, we will copy the file +/// into a new inode, remove the original file, and rename the copy to match +/// the original file. This is super messy, but there doesn't seem any other +/// way to please the XNU. +pub fn invalidateKernelCache(dir: std.fs.Dir, sub_path: []const u8) !void { + if (comptime builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) { + try dir.copyFile(sub_path, dir, sub_path, .{}); + } +} + inline fn conformUuid(out: *[Md5.digest_length]u8) void { // LC_UUID uuids should conform to RFC 4122 UUID version 4 & UUID version 5 formats out[6] = (out[6] & 0x0F) | (3 << 4); diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index a901e4fd4b..a7c7bc41b9 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -4172,6 +4172,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr if (codesig) |*csig| { try zld.writeCodeSignature(comp, csig); // code signing always comes last + try MachO.invalidateKernelCache(directory.handle, zld.options.emit.?.sub_path); } } From c31007bb47a4d1d62917324a33e9a9a6cd1df5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Fri, 17 Mar 2023 13:16:34 +0200 Subject: [PATCH 007/216] fix copy-paste errors --sysroot was copy-pasted instead of --maxrss from above. Also, make it less likely in other places for this to be repeated. I found this by accident when reviewing f51413d2cf0bd87079dace7f6481d2a361a19ea6 --- lib/build_runner.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/build_runner.zig b/lib/build_runner.zig index 930bccdc0f..00e7c5b65d 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -142,13 +142,13 @@ pub fn main() !void { }; } else if (mem.eql(u8, arg, "--sysroot")) { const sysroot = nextArg(args, &arg_idx) orelse { - std.debug.print("Expected argument after --sysroot\n\n", .{}); + std.debug.print("Expected argument after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; builder.sysroot = sysroot; } else if (mem.eql(u8, arg, "--maxrss")) { const max_rss_text = nextArg(args, &arg_idx) orelse { - std.debug.print("Expected argument after --sysroot\n\n", .{}); + std.debug.print("Expected argument after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; // TODO: support shorthand such as "2GiB", "2GB", or "2G" @@ -160,28 +160,28 @@ pub fn main() !void { }; } else if (mem.eql(u8, arg, "--search-prefix")) { const search_prefix = nextArg(args, &arg_idx) orelse { - std.debug.print("Expected argument after --search-prefix\n\n", .{}); + std.debug.print("Expected argument after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; builder.addSearchPrefix(search_prefix); } else if (mem.eql(u8, arg, "--libc")) { const libc_file = nextArg(args, &arg_idx) orelse { - std.debug.print("Expected argument after --libc\n\n", .{}); + std.debug.print("Expected argument after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; builder.libc_file = libc_file; } else if (mem.eql(u8, arg, "--color")) { const next_arg = nextArg(args, &arg_idx) orelse { - std.debug.print("expected [auto|on|off] after --color", .{}); + std.debug.print("Expected [auto|on|off] after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; color = std.meta.stringToEnum(Color, next_arg) orelse { - std.debug.print("expected [auto|on|off] after --color, found '{s}'", .{next_arg}); + std.debug.print("Expected [auto|on|off] after {s}, found '{s}'\n\n", .{ arg, next_arg }); usageAndErr(builder, false, stderr_stream); }; } else if (mem.eql(u8, arg, "--zig-lib-dir")) { builder.zig_lib_dir = nextArg(args, &arg_idx) orelse { - std.debug.print("Expected argument after --zig-lib-dir\n\n", .{}); + std.debug.print("Expected argument after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; } else if (mem.eql(u8, arg, "--debug-log")) { @@ -196,7 +196,7 @@ pub fn main() !void { builder.debug_compile_errors = true; } else if (mem.eql(u8, arg, "--glibc-runtimes")) { builder.glibc_runtimes_dir = nextArg(args, &arg_idx) orelse { - std.debug.print("Expected argument after --glibc-runtimes\n\n", .{}); + std.debug.print("Expected argument after {s}\n\n", .{arg}); usageAndErr(builder, false, stderr_stream); }; } else if (mem.eql(u8, arg, "--verbose-link")) { From ee705e3ac71205142a4457acd2677f7be921d62b Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 17 Mar 2023 17:54:47 +0100 Subject: [PATCH 008/216] macho+zld: clean up opening and closing of file descriptors --- src/link/MachO/zld.zig | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index a7c7bc41b9..931352545e 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -3665,16 +3665,17 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr } else { const page_size = macho_file.page_size; const sub_path = options.emit.?.sub_path; - if (macho_file.base.file == null) { - macho_file.base.file = try directory.handle.createFile(sub_path, .{ - .truncate = true, - .read = true, - .mode = link.determineMode(options.*), - }); - } + + const file = try directory.handle.createFile(sub_path, .{ + .truncate = true, + .read = true, + .mode = link.determineMode(options.*), + }); + defer file.close(); + var zld = Zld{ .gpa = gpa, - .file = macho_file.base.file.?, + .file = file, .page_size = macho_file.page_size, .options = options, }; From bddf138e7285eefb86ef880e1200a929193da40b Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Wed, 8 Mar 2023 06:27:03 +0100 Subject: [PATCH 009/216] wasm-link: fix storing decls in the right segment When a decl is `undefined` is must be stored in the data segment when the build mode is safe. For unsafe optimize modes, it must be stored in the bss segment instead. For mutable decls where the atom contains all zeroes, it must always be stored in the bss segment. All other values will result in the atom being stored in the data segment. --- src/link/Wasm.zig | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index e998a8d50e..01100add4b 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2828,22 +2828,31 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod const decl = mod.declPtr(entry.key_ptr.*); if (decl.isExtern()) continue; const atom_index = entry.value_ptr.*; + const atom = wasm.getAtomPtr(atom_index); if (decl.ty.zigTypeTag() == .Fn) { try wasm.parseAtom(atom_index, .function); } else if (decl.getVariable()) |variable| { if (!variable.is_mutable) { try wasm.parseAtom(atom_index, .{ .data = .read_only }); } else if (variable.init.isUndefDeep()) { - try wasm.parseAtom(atom_index, .{ .data = .uninitialized }); + // for safe build modes, we store the atom in the data segment, + // whereas for unsafe build modes we store it in bss. + const is_initialized = wasm.base.options.optimize_mode == .Debug or + wasm.base.options.optimize_mode == .ReleaseSafe; + try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized }); } else { - try wasm.parseAtom(atom_index, .{ .data = .initialized }); + // when the decl is all zeroes, we store the atom in the bss segment, + // in all other cases it will be in the data segment. + const is_zeroes = for (atom.code.items) |byte| { + if (byte != 0) break false; + } else true; + try wasm.parseAtom(atom_index, .{ .data = if (is_zeroes) .uninitialized else .initialized }); } } else { try wasm.parseAtom(atom_index, .{ .data = .read_only }); } // also parse atoms for a decl's locals - const atom = wasm.getAtomPtr(atom_index); for (atom.locals.items) |local_atom_index| { try wasm.parseAtom(local_atom_index, .{ .data = .read_only }); } From d0fb1ef9625b55cc71b41438265f596a00d63749 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Wed, 8 Mar 2023 06:42:23 +0100 Subject: [PATCH 010/216] wasm-link: update bss linker test Updates the linker test to verify the various cases where we must store the data in the bss segment. --- test/link/wasm/bss/build.zig | 108 ++++++++++++++++++++++++----------- test/link/wasm/bss/lib2.zig | 5 ++ 2 files changed, 79 insertions(+), 34 deletions(-) create mode 100644 test/link/wasm/bss/lib2.zig diff --git a/test/link/wasm/bss/build.zig b/test/link/wasm/bss/build.zig index bba2e7c602..4a26e78a12 100644 --- a/test/link/wasm/bss/build.zig +++ b/test/link/wasm/bss/build.zig @@ -6,38 +6,78 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test"); b.default_step = test_step; - const lib = b.addSharedLibrary(.{ - .name = "lib", - .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, - .optimize = .Debug, - }); - lib.use_llvm = false; - lib.use_lld = false; - lib.strip = false; - // to make sure the bss segment is emitted, we must import memory - lib.import_memory = true; - lib.install(); - - const check_lib = lib.checkObject(); - - // since we import memory, make sure it exists with the correct naming - check_lib.checkStart("Section import"); - check_lib.checkNext("entries 1"); - check_lib.checkNext("module env"); // default module name is "env" - check_lib.checkNext("name memory"); // as per linker specification - - // since we are importing memory, ensure it's not exported - check_lib.checkNotPresent("Section export"); - - // validate the name of the stack pointer - check_lib.checkStart("Section custom"); - check_lib.checkNext("type data_segment"); - check_lib.checkNext("names 2"); - check_lib.checkNext("index 0"); - check_lib.checkNext("name .rodata"); - check_lib.checkNext("index 1"); // bss section always last - check_lib.checkNext("name .bss"); - - test_step.dependOn(&check_lib.step); + add(b, test_step, .Debug, true); + add(b, test_step, .ReleaseFast, false); + add(b, test_step, .ReleaseSmall, false); + add(b, test_step, .ReleaseSafe, true); +} + +fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode, is_safe: bool) void { + { + const lib = b.addSharedLibrary(.{ + .name = "lib", + .root_source_file = .{ .path = "lib.zig" }, + .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .optimize = optimize_mode, + }); + lib.use_llvm = false; + lib.use_lld = false; + lib.strip = false; + // to make sure the bss segment is emitted, we must import memory + lib.import_memory = true; + + const check_lib = lib.checkObject(); + + // since we import memory, make sure it exists with the correct naming + check_lib.checkStart("Section import"); + check_lib.checkNext("entries 1"); + check_lib.checkNext("module env"); // default module name is "env" + check_lib.checkNext("name memory"); // as per linker specification + + // since we are importing memory, ensure it's not exported + check_lib.checkNotPresent("Section export"); + + // validate the name of the stack pointer + check_lib.checkStart("Section custom"); + check_lib.checkNext("type data_segment"); + check_lib.checkNext("names 2"); + check_lib.checkNext("index 0"); + check_lib.checkNext("name .rodata"); + // for safe optimization modes `undefined` is stored in data instead of bss. + if (is_safe) { + check_lib.checkNext("index 1"); + check_lib.checkNext("name .data"); + check_lib.checkNotPresent("name .bss"); + } else { + check_lib.checkNext("index 1"); // bss section always last + check_lib.checkNext("name .bss"); + } + test_step.dependOn(&check_lib.step); + } + + // verify zero'd declaration is stored in bss for all optimization modes. + { + const lib = b.addSharedLibrary(.{ + .name = "lib", + .root_source_file = .{ .path = "lib2.zig" }, + .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .optimize = optimize_mode, + }); + lib.use_llvm = false; + lib.use_lld = false; + lib.strip = false; + // to make sure the bss segment is emitted, we must import memory + lib.import_memory = true; + + const check_lib = lib.checkObject(); + check_lib.checkStart("Section custom"); + check_lib.checkNext("type data_segment"); + check_lib.checkNext("names 2"); + check_lib.checkNext("index 0"); + check_lib.checkNext("name .rodata"); + check_lib.checkNext("index 1"); + check_lib.checkNext("name .bss"); + + test_step.dependOn(&check_lib.step); + } } diff --git a/test/link/wasm/bss/lib2.zig b/test/link/wasm/bss/lib2.zig new file mode 100644 index 0000000000..9f43128880 --- /dev/null +++ b/test/link/wasm/bss/lib2.zig @@ -0,0 +1,5 @@ +pub var bss: u32 = 0; + +export fn foo() void { + _ = bss; +} From 46171bf6c89dc2c2b8f155c8511b62e5cd52e3bc Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 18 Mar 2023 19:05:06 +0100 Subject: [PATCH 011/216] macho+zld: clean up how to interface with link.zig and openPath() --- src/link/MachO.zig | 71 ++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 368914e1be..2f76c49667 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -60,6 +60,17 @@ pub const SearchStrategy = enum { dylibs_first, }; +/// Mode of operation of the linker. +pub const Mode = enum { + /// Incremental mode will preallocate segments/sections and is compatible with + /// watch and HCS modes of operation. + incremental, + /// Zld mode will link relocatables in a traditional, one-shot + /// fashion (default for LLVM backend). It acts as a drop-in replacement for + /// LLD. + zld, +}; + const Section = struct { header: macho.section_64, segment_index: u8, @@ -98,10 +109,7 @@ d_sym: ?DebugSymbols = null, /// For x86_64 that's 4KB, whereas for aarch64, that's 16KB. page_size: u16, -/// Mode of operation: incremental - will preallocate segments/sections and is compatible with -/// watch and HCS modes of operation; one_shot - will link relocatables in a traditional, one-shot -/// fashion (default for LLVM backend). -mode: enum { incremental, one_shot }, +mode: Mode, dyld_info_cmd: macho.dyld_info_command = .{}, symtab_cmd: macho.symtab_command = .{}, @@ -314,33 +322,42 @@ pub const default_headerpad_size: u32 = 0x1000; pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { assert(options.target.ofmt == .macho); - if (options.emit == null or options.module == null) { + if (options.emit == null) { return createEmpty(allocator, options); } const emit = options.emit.?; - const self = try createEmpty(allocator, options); - errdefer { - self.base.file = null; - self.base.destroy(); - } + const mode: Mode = mode: { + if (options.use_llvm or options.module == null or options.cache_mode == .whole) + break :mode .zld; + break :mode .incremental; + }; + const sub_path = if (mode == .zld) blk: { + if (options.module == null) { + // No point in opening a file, we would not write anything to it. + // Initialize with empty. + return createEmpty(allocator, options); + } + // Open a temporary object file, not the final output file because we + // want to link with LLD. + break :blk try std.fmt.allocPrint(allocator, "{s}{s}", .{ + emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch), + }); + } else emit.sub_path; + errdefer if (mode == .zld) allocator.free(sub_path); - if (build_options.have_llvm and options.use_llvm and options.module != null) { + const self = try createEmpty(allocator, options); + errdefer self.base.destroy(); + + if (mode == .zld) { // TODO this intermediary_basename isn't enough; in the case of `zig build-exe`, // we also want to put the intermediary object file in the cache while the // main emit directory is the cwd. - self.base.intermediary_basename = try std.fmt.allocPrint(allocator, "{s}{s}", .{ - emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch), - }); + self.base.intermediary_basename = sub_path; + return self; } - if (self.base.intermediary_basename != null) switch (options.output_mode) { - .Obj => return self, - .Lib => if (options.link_mode == .Static) return self, - else => {}, - }; - - const file = try emit.directory.handle.createFile(emit.sub_path, .{ + const file = try emit.directory.handle.createFile(sub_path, .{ .truncate = false, .read = true, .mode = link.determineMode(options), @@ -348,23 +365,21 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { errdefer file.close(); self.base.file = file; - if (self.mode == .one_shot) return self; - if (!options.strip and options.module != null) { // Create dSYM bundle. - log.debug("creating {s}.dSYM bundle", .{emit.sub_path}); + log.debug("creating {s}.dSYM bundle", .{sub_path}); const d_sym_path = try fmt.allocPrint( allocator, "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF", - .{emit.sub_path}, + .{sub_path}, ); defer allocator.free(d_sym_path); var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{}); defer d_sym_bundle.close(); - const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{ + const d_sym_file = try d_sym_bundle.createFile(sub_path, .{ .truncate = false, .read = true, }); @@ -413,7 +428,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO { }, .page_size = page_size, .mode = if (use_llvm or options.module == null or options.cache_mode == .whole) - .one_shot + .zld else .incremental, }; @@ -447,7 +462,7 @@ pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) li } switch (self.mode) { - .one_shot => return zld.linkWithZld(self, comp, prog_node), + .zld => return zld.linkWithZld(self, comp, prog_node), .incremental => return self.flushModule(comp, prog_node), } } From 887abd0f33af15d69c0473e2fb139b490f4ecc8f Mon Sep 17 00:00:00 2001 From: square Date: Sat, 18 Mar 2023 18:25:52 +0100 Subject: [PATCH 012/216] delete `--prominent-compile-errors` from help --- lib/build_runner.zig | 1 - src/main.zig | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/build_runner.zig b/lib/build_runner.zig index 00e7c5b65d..bfc6ab77f6 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -949,7 +949,6 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi \\ -l, --list-steps Print available steps \\ --verbose Print commands before executing them \\ --color [auto|off|on] Enable or disable colored error messages - \\ --prominent-compile-errors Output compile errors formatted for a human to read \\ -fsummary Print the build summary, even on success \\ -fno-summary Omit the build summary, even on failure \\ -j Limit concurrent jobs (default is to use all CPU cores) diff --git a/src/main.zig b/src/main.zig index e28bdf34cf..db28a5b09b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4260,7 +4260,6 @@ pub const usage_build = \\ --global-cache-dir [path] Override path to global Zig cache directory \\ --zig-lib-dir [arg] Override path to Zig lib directory \\ --build-runner [file] Override path to build runner - \\ --prominent-compile-errors Output compile errors formatted for a human to read \\ -h, --help Print this help and exit \\ ; From 49d37e2d179948f526f500043c6ea9ae324e9476 Mon Sep 17 00:00:00 2001 From: Nicolas Sterchele Date: Sat, 18 Mar 2023 08:37:33 +0100 Subject: [PATCH 013/216] build-step: remove latest LogStep ref LogStep was removed during the build parallel enhancement made in this commit 58edefc6d1716c0731ee2fe672ec8d073651aafb --- lib/std/Build/Step.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 88580a6cbc..0c05a64b1c 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -79,7 +79,6 @@ pub const Id = enum { install_artifact, install_file, install_dir, - log, remove_dir, fmt, translate_c, @@ -99,7 +98,6 @@ pub const Id = enum { .install_artifact => Build.InstallArtifactStep, .install_file => Build.InstallFileStep, .install_dir => Build.InstallDirStep, - .log => Build.LogStep, .remove_dir => Build.RemoveDirStep, .fmt => Build.FmtStep, .translate_c => Build.TranslateCStep, From b0024c48841b78a962918cd4ab20459ba6451050 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Sun, 12 Mar 2023 15:23:58 +0100 Subject: [PATCH 014/216] wasm-linker: basic TLS support Linker now parses segments with regards to TLS segments. If the name represents a TLS segment but does not contain the TLS flag, we set it manually as the object file is created using an older compiler (LLVM). For now we panic when we find a TLS relocation and implement those later. --- src/link/Wasm.zig | 19 +++++++++++++++++++ src/link/Wasm/Atom.zig | 7 +++++++ src/link/Wasm/Object.zig | 6 ++++++ src/link/Wasm/Symbol.zig | 4 ++++ src/link/Wasm/types.zig | 29 +++++++++++++++++++++-------- 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index e998a8d50e..287f880d92 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -894,6 +894,13 @@ fn resolveLazySymbols(wasm: *Wasm) !void { try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc); _ = wasm.resolved_symbols.swapRemove(loc); } + + if (!wasm.base.options.shared_memory) { + if (wasm.undefs.fetchSwapRemove("__tls_base")) |kv| { + const loc = try wasm.createSyntheticSymbol("__tls_base", .global); + try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc); + } + } } // Tries to find a global symbol by its name. Returns null when not found, @@ -2224,6 +2231,18 @@ fn setupMemory(wasm: *Wasm) !void { while (data_seg_it.next()) |entry| { const segment = &wasm.segments.items[entry.value_ptr.*]; memory_ptr = std.mem.alignForwardGeneric(u64, memory_ptr, segment.alignment); + + // set TLS-related symbols + if (mem.eql(u8, entry.key_ptr.*, ".tdata")) { + if (wasm.findGlobalSymbol("__tls_base")) |loc| { + const sym = loc.getSymbol(wasm); + sym.index = try wasm.globals.append(wasm.base.allocator, wasm.imports.globalCount, .{ + .global_type = .{ .valtype = .i32_const, .mutable = false }, + .init = .{ .i32_const = @intCast(i32, memory_ptr) }, + }); + } + } + memory_ptr += segment.size; segment.offset = offset; offset += segment.size; diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index 0c9d761f05..7d2f5a6696 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -126,10 +126,12 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { .R_WASM_TABLE_INDEX_SLEB, .R_WASM_TABLE_NUMBER_LEB, .R_WASM_TYPE_INDEX_LEB, + .R_WASM_MEMORY_ADDR_TLS_SLEB, => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset..][0..5], @intCast(u32, value)), .R_WASM_MEMORY_ADDR_LEB64, .R_WASM_MEMORY_ADDR_SLEB64, .R_WASM_TABLE_INDEX_SLEB64, + .R_WASM_MEMORY_ADDR_TLS_SLEB64, => leb.writeUnsignedFixed(10, atom.code.items[reloc.offset..][0..10], value), } } @@ -190,5 +192,10 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa const rel_value = @intCast(i32, target_atom.offset + offset) + relocation.addend; return @intCast(u32, rel_value); }, + .R_WASM_MEMORY_ADDR_TLS_SLEB, + .R_WASM_MEMORY_ADDR_TLS_SLEB64, + => { + @panic("TODO: Implement TLS relocations"); + }, } } diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index 45c9464ec8..4b918064c1 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -674,6 +674,12 @@ fn Parser(comptime ReaderType: type) type { segment.alignment, segment.flags, }); + + // support legacy object files that specified being TLS by the name instead of the TLS flag. + if (!segment.isTLS() and (std.mem.startsWith(u8, segment.name, ".tdata") or std.mem.startsWith(u8, segment.name, ".tbss"))) { + // set the flag so we can simply check for the flag in the rest of the linker. + segment.flags |= @enumToInt(types.Segment.Flags.WASM_SEG_FLAG_TLS); + } } parser.object.segment_info = segments; }, diff --git a/src/link/Wasm/Symbol.zig b/src/link/Wasm/Symbol.zig index 156b507a32..8a1c4c5fdb 100644 --- a/src/link/Wasm/Symbol.zig +++ b/src/link/Wasm/Symbol.zig @@ -90,6 +90,10 @@ pub fn requiresImport(symbol: Symbol) bool { return true; } +pub fn isTLS(symbol: Symbol) bool { + return symbol.flags & @enumToInt(Flag.WASM_SYM_TLS) != 0; +} + pub fn hasFlag(symbol: Symbol, flag: Flag) bool { return symbol.flags & @enumToInt(flag) != 0; } diff --git a/src/link/Wasm/types.zig b/src/link/Wasm/types.zig index 964ba04ba0..a65e352c46 100644 --- a/src/link/Wasm/types.zig +++ b/src/link/Wasm/types.zig @@ -38,6 +38,8 @@ pub const Relocation = struct { R_WASM_TABLE_INDEX_SLEB64 = 18, R_WASM_TABLE_INDEX_I64 = 19, R_WASM_TABLE_NUMBER_LEB = 20, + R_WASM_MEMORY_ADDR_TLS_SLEB = 21, + R_WASM_MEMORY_ADDR_TLS_SLEB64 = 25, /// Returns true for relocation types where the `addend` field is present. pub fn addendIsPresent(self: RelocationType) bool { @@ -125,23 +127,34 @@ pub const Segment = struct { /// Bitfield containing flags for a segment flags: u32, + pub fn isTLS(segment: Segment) bool { + return segment.flags & @enumToInt(Flags.WASM_SEG_FLAG_TLS) != 0; + } + /// Returns the name as how it will be output into the final object /// file or binary. When `merge_segments` is true, this will return the /// short name. i.e. ".rodata". When false, it returns the entire name instead. - pub fn outputName(self: Segment, merge_segments: bool) []const u8 { - if (std.mem.startsWith(u8, self.name, ".synthetic")) return ".synthetic"; // always merge - if (!merge_segments) return self.name; - if (std.mem.startsWith(u8, self.name, ".rodata.")) { + pub fn outputName(segment: Segment, merge_segments: bool) []const u8 { + if (segment.isTLS()) { + return ".tdata"; + } else if (!merge_segments) { + return segment.name; + } else if (std.mem.startsWith(u8, segment.name, ".rodata.")) { return ".rodata"; - } else if (std.mem.startsWith(u8, self.name, ".text.")) { + } else if (std.mem.startsWith(u8, segment.name, ".text.")) { return ".text"; - } else if (std.mem.startsWith(u8, self.name, ".data.")) { + } else if (std.mem.startsWith(u8, segment.name, ".data.")) { return ".data"; - } else if (std.mem.startsWith(u8, self.name, ".bss.")) { + } else if (std.mem.startsWith(u8, segment.name, ".bss.")) { return ".bss"; } - return self.name; + return segment.name; } + + pub const Flags = enum(u32) { + WASM_SEG_FLAG_STRINGS = 0x1, + WASM_SEG_FLAG_TLS = 0x2, + }; }; pub const InitFunc = struct { From 09abd53da701a5ef4db4b81463e2535e192a5eee Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Sun, 12 Mar 2023 16:02:02 +0100 Subject: [PATCH 015/216] wasm-linker: refactor Limits and add flags Rather than adding the flags "on-demand" during limits writing, we now properly parse them and store the flags within the limits itself. This also allows us to store whether we're using shared- memory or not. Only when the correct flag is set will we set the max within `Limits` or else we will leave it `undefined`. --- lib/std/wasm.zig | 16 +++++++++++++++- src/link/Wasm.zig | 25 +++++++++++++++++-------- src/link/Wasm/Object.zig | 11 ++++++++--- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/std/wasm.zig b/lib/std/wasm.zig index 25a0bb7abf..35d0ba4866 100644 --- a/lib/std/wasm.zig +++ b/lib/std/wasm.zig @@ -551,8 +551,22 @@ test "Wasm - valtypes" { /// Limits classify the size range of resizeable storage associated with memory types and table types. pub const Limits = struct { + flags: u8, min: u32, - max: ?u32, + max: u32, + + pub const Flags = enum(u8) { + WASM_LIMITS_FLAG_HAS_MAX = 0x1, + WASM_LIMITS_FLAG_IS_SHARED = 0x2, + }; + + pub fn hasFlag(limits: Limits, flag: Flags) bool { + return limits.flags & @enumToInt(flag) != 0; + } + + pub fn setFlag(limits: *Limits, flag: Flags) void { + limits.flags |= @enumToInt(flag); + } }; /// Initialization expressions are used to set the initial value on an object diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 287f880d92..50846eecf1 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -111,7 +111,11 @@ functions: std.AutoArrayHashMapUnmanaged(struct { file: ?u16, index: u32 }, std. /// Output global section wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{}, /// Memory section -memories: std.wasm.Memory = .{ .limits = .{ .min = 0, .max = null } }, +memories: std.wasm.Memory = .{ .limits = .{ + .min = 0, + .max = undefined, + .flags = 0, +} }, /// Output table section tables: std.ArrayListUnmanaged(std.wasm.Table) = .{}, /// Output export section @@ -396,7 +400,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option const loc = try wasm_bin.createSyntheticSymbol("__indirect_function_table", .table); const symbol = loc.getSymbol(wasm_bin); const table: std.wasm.Table = .{ - .limits = .{ .min = 0, .max = null }, // will be overwritten during `mapFunctionTable` + .limits = .{ .flags = 0, .min = 0, .max = undefined }, // will be overwritten during `mapFunctionTable` .reftype = .funcref, }; if (options.output_mode == .Obj or options.import_table) { @@ -1524,7 +1528,7 @@ fn mapFunctionTable(wasm: *Wasm) void { const sym_loc = wasm.findGlobalSymbol("__indirect_function_table").?; const symbol = sym_loc.getSymbol(wasm); const table = &wasm.tables.items[symbol.index - wasm.imported_tables_count]; - table.limits = .{ .min = index, .max = index }; + table.limits = .{ .min = index, .max = index, .flags = 0x1 }; } } @@ -2236,8 +2240,9 @@ fn setupMemory(wasm: *Wasm) !void { if (mem.eql(u8, entry.key_ptr.*, ".tdata")) { if (wasm.findGlobalSymbol("__tls_base")) |loc| { const sym = loc.getSymbol(wasm); - sym.index = try wasm.globals.append(wasm.base.allocator, wasm.imports.globalCount, .{ - .global_type = .{ .valtype = .i32_const, .mutable = false }, + sym.index = @intCast(u32, wasm.wasm_globals.items.len) + wasm.imported_globals_count; + try wasm.wasm_globals.append(wasm.base.allocator, .{ + .global_type = .{ .valtype = .i32, .mutable = false }, .init = .{ .i32_const = @intCast(i32, memory_ptr) }, }); } @@ -2305,6 +2310,10 @@ fn setupMemory(wasm: *Wasm) !void { return error.MemoryTooBig; } wasm.memories.limits.max = @intCast(u32, max_memory / page_size); + wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_HAS_MAX); + if (wasm.base.options.shared_memory) { + wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_IS_SHARED); + } log.debug("Maximum memory pages: {?d}", .{wasm.memories.limits.max}); } } @@ -3517,10 +3526,10 @@ fn emitNameSubsection(wasm: *Wasm, section_id: std.wasm.NameSubsection, names: a } fn emitLimits(writer: anytype, limits: std.wasm.Limits) !void { - try leb.writeULEB128(writer, @boolToInt(limits.max != null)); + try writer.writeByte(limits.flags); try leb.writeULEB128(writer, limits.min); - if (limits.max) |max| { - try leb.writeULEB128(writer, max); + if (limits.hasFlag(.WASM_LIMITS_FLAG_HAS_MAX)) { + try leb.writeULEB128(writer, limits.max); } } diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index 4b918064c1..92336efbf2 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -852,12 +852,17 @@ fn readEnum(comptime T: type, reader: anytype) !T { } fn readLimits(reader: anytype) !std.wasm.Limits { - const flags = try readLeb(u1, reader); + const flags = try reader.readByte(); const min = try readLeb(u32, reader); - return std.wasm.Limits{ + var limits: std.wasm.Limits = .{ + .flags = flags, .min = min, - .max = if (flags == 0) null else try readLeb(u32, reader), + .max = undefined, }; + if (limits.hasFlag(.WASM_LIMITS_FLAG_HAS_MAX)) { + limits.max = try readLeb(u32, reader); + } + return limits; } fn readInit(reader: anytype) !std.wasm.InitExpression { From fb9d3cd50e9a6d112277d7de158ef857162c01d9 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Mon, 13 Mar 2023 19:30:33 +0100 Subject: [PATCH 016/216] wasm-linker: feature verifiction for shared-mem When the user enables shared-memory, we must ensure the linked objects have the 'atomics' and 'bulk-memory' features allowed. --- src/link/Wasm.zig | 41 ++++++++++++++++++++++++++++++++++++---- src/link/Wasm/Object.zig | 4 ++-- src/link/Wasm/types.zig | 12 ++++++++---- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 50846eecf1..5792e57b89 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -795,6 +795,8 @@ fn validateFeatures( // when false, we fail linking. We only verify this after a loop to catch all invalid features. var valid_feature_set = true; + // will be set to true when there's any TLS segment found in any of the object files + var has_tls = false; // When the user has given an explicit list of features to enable, // we extract them and insert each into the 'allowed' list. @@ -825,6 +827,12 @@ fn validateFeatures( }, } } + + for (object.segment_info) |segment| { + if (segment.isTLS()) { + has_tls = true; + } + } } // when we infer the features, we allow each feature found in the 'used' set @@ -836,7 +844,7 @@ fn validateFeatures( allowed[used_index] = is_enabled; emit_features_count.* += @boolToInt(is_enabled); } else if (is_enabled and !allowed[used_index]) { - log.err("feature '{s}' not allowed, but used by linked object", .{(@intToEnum(types.Feature.Tag, used_index)).toString()}); + log.err("feature '{}' not allowed, but used by linked object", .{@intToEnum(types.Feature.Tag, used_index)}); log.err(" defined in '{s}'", .{wasm.objects.items[used_set >> 1].name}); valid_feature_set = false; } @@ -846,6 +854,30 @@ fn validateFeatures( return error.InvalidFeatureSet; } + if (wasm.base.options.shared_memory) { + const disallowed_feature = disallowed[@enumToInt(types.Feature.Tag.shared_mem)]; + if (@truncate(u1, disallowed_feature) != 0) { + log.err( + "shared-memory is disallowed by '{s}' because it wasn't compiled with 'atomics' and 'bulk-memory' features enabled", + .{wasm.objects.items[disallowed_feature >> 1].name}, + ); + valid_feature_set = false; + } + + for ([_]types.Feature.Tag{ .atomics, .bulk_memory }) |feature| { + if (!allowed[@enumToInt(feature)]) { + log.err("feature '{}' is not used but is required for shared-memory", .{feature}); + } + } + } + + if (has_tls) { + for ([_]types.Feature.Tag{ .atomics, .bulk_memory }) |feature| { + if (!allowed[@enumToInt(feature)]) { + log.err("feature '{}' is not used but is required for thread-local storage", .{feature}); + } + } + } // For each linked object, validate the required and disallowed features for (wasm.objects.items) |object| { var object_used_features = [_]bool{false} ** known_features_count; @@ -854,7 +886,7 @@ fn validateFeatures( // from here a feature is always used const disallowed_feature = disallowed[@enumToInt(feature.tag)]; if (@truncate(u1, disallowed_feature) != 0) { - log.err("feature '{s}' is disallowed, but used by linked object", .{feature.tag.toString()}); + log.err("feature '{}' is disallowed, but used by linked object", .{feature.tag}); log.err(" disallowed by '{s}'", .{wasm.objects.items[disallowed_feature >> 1].name}); log.err(" used in '{s}'", .{object.name}); valid_feature_set = false; @@ -867,7 +899,7 @@ fn validateFeatures( for (required, 0..) |required_feature, feature_index| { const is_required = @truncate(u1, required_feature) != 0; if (is_required and !object_used_features[feature_index]) { - log.err("feature '{s}' is required but not used in linked object", .{(@intToEnum(types.Feature.Tag, feature_index)).toString()}); + log.err("feature '{}' is required but not used in linked object", .{@intToEnum(types.Feature.Tag, feature_index)}); log.err(" required by '{s}'", .{wasm.objects.items[required_feature >> 1].name}); log.err(" missing in '{s}'", .{object.name}); valid_feature_set = false; @@ -3432,7 +3464,8 @@ fn emitFeaturesSection(binary_bytes: *std.ArrayList(u8), enabled_features: []con if (enabled) { const feature: types.Feature = .{ .prefix = .used, .tag = @intToEnum(types.Feature.Tag, feature_index) }; try leb.writeULEB128(writer, @enumToInt(feature.prefix)); - const string = feature.tag.toString(); + var buf: [100]u8 = undefined; + const string = try std.fmt.bufPrint(&buf, "{}", .{feature.tag}); try leb.writeULEB128(writer, @intCast(u32, string.len)); try writer.writeAll(string); } diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index 92336efbf2..c2243bdf10 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -601,8 +601,8 @@ fn Parser(comptime ReaderType: type) type { }); for (relocations) |*relocation| { - const rel_type = try leb.readULEB128(u8, reader); - const rel_type_enum = @intToEnum(types.Relocation.RelocationType, rel_type); + const rel_type = try reader.readByte(); + const rel_type_enum = std.meta.intToEnum(types.Relocation.RelocationType, rel_type) catch return error.MalformedSection; relocation.* = .{ .relocation_type = rel_type_enum, .offset = try leb.readULEB128(u32, reader), diff --git a/src/link/Wasm/types.zig b/src/link/Wasm/types.zig index a65e352c46..d19f32b862 100644 --- a/src/link/Wasm/types.zig +++ b/src/link/Wasm/types.zig @@ -50,6 +50,8 @@ pub const Relocation = struct { .R_WASM_MEMORY_ADDR_LEB64, .R_WASM_MEMORY_ADDR_SLEB64, .R_WASM_MEMORY_ADDR_I64, + .R_WASM_MEMORY_ADDR_TLS_SLEB, + .R_WASM_MEMORY_ADDR_TLS_SLEB64, .R_WASM_FUNCTION_OFFSET_I32, .R_WASM_SECTION_OFFSET_I32, => true, @@ -218,8 +220,10 @@ pub const Feature = struct { return @intToEnum(Tag, @enumToInt(feature)); } - pub fn toString(tag: Tag) []const u8 { - return switch (tag) { + pub fn format(tag: Tag, comptime fmt: []const u8, opt: std.fmt.FormatOptions, writer: anytype) !void { + _ = fmt; + _ = opt; + try writer.writeAll(switch (tag) { .atomics => "atomics", .bulk_memory => "bulk-memory", .exception_handling => "exception-handling", @@ -233,7 +237,7 @@ pub const Feature = struct { .simd128 => "simd128", .tail_call => "tail-call", .shared_mem => "shared-mem", - }; + }); } }; @@ -246,7 +250,7 @@ pub const Feature = struct { pub fn format(feature: Feature, comptime fmt: []const u8, opt: std.fmt.FormatOptions, writer: anytype) !void { _ = opt; _ = fmt; - try writer.print("{c} {s}", .{ feature.prefix, feature.tag.toString() }); + try writer.print("{c} {}", .{ feature.prefix, feature.tag }); } }; From 00af3a79aede098c60eeff38ad72fa399b9d3ccf Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Tue, 14 Mar 2023 19:31:45 +0100 Subject: [PATCH 017/216] wasm-linker: emit 'data count' & segment flags When linking with shared-memory enabled, we must ensure to emit the "data count" section as well as emit the correct segment flags to tell the runtime/loader that each segment is passive. This is required as we don't emit the offsets for such segments but instead initialize each segment (for each thread) during runtime. --- src/link/Wasm.zig | 54 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 5792e57b89..720e10fe03 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -180,6 +180,16 @@ pub const Segment = struct { alignment: u32, size: u32, offset: u32, + flags: u32, + + pub const Flag = enum(u32) { + WASM_DATA_SEGMENT_IS_PASSIVE = 0x01, + WASM_DATA_SEGMENT_HAS_MEMINDEX = 0x02, + }; + + pub fn isPassive(segment: Segment) bool { + return segment.flags & @enumToInt(Flag.WASM_DATA_SEGMENT_IS_PASSIVE) != 0; + } }; pub const Export = struct { @@ -1673,6 +1683,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { .alignment = atom.alignment, .size = atom.size, .offset = 0, + .flags = 0, }); } @@ -1711,10 +1722,15 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { break :result index; } else { const index = @intCast(u32, wasm.segments.items.len); + var flags: u32 = 0; + if (wasm.base.options.shared_memory) { + flags |= @enumToInt(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); + } try wasm.segments.append(wasm.base.allocator, .{ .alignment = atom.alignment, .size = 0, .offset = 0, + .flags = flags, }); gop.value_ptr.* = index; @@ -2365,7 +2381,16 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, relocatable_index: u32 const result = try wasm.data_segments.getOrPut(wasm.base.allocator, segment_info.outputName(merge_segment)); if (!result.found_existing) { result.value_ptr.* = index; - try wasm.appendDummySegment(); + var flags: u32 = 0; + if (wasm.base.options.shared_memory) { + flags |= @enumToInt(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); + } + try wasm.segments.append(wasm.base.allocator, .{ + .alignment = 1, + .size = 0, + .offset = 0, + .flags = flags, + }); return index; } else return result.value_ptr.*; }, @@ -2439,6 +2464,7 @@ fn appendDummySegment(wasm: *Wasm) !void { .alignment = 1, .size = 0, .offset = 0, + .flags = 0, }); } @@ -3147,6 +3173,19 @@ fn writeToFile( section_count += 1; } + // When the shared-memory option is enabled, we *must* emit the 'data count' section. + const data_segments_count = wasm.data_segments.count() - @boolToInt(wasm.data_segments.contains(".bss") and import_memory); + if (data_segments_count != 0 and wasm.base.options.shared_memory) { + const header_offset = try reserveVecSectionHeader(&binary_bytes); + try writeVecSectionHeader( + binary_bytes.items, + header_offset, + .data_count, + @intCast(u32, binary_bytes.items.len - header_offset - header_size), + @intCast(u32, data_segments_count), + ); + } + // Code section var code_section_size: u32 = 0; if (wasm.code_section_index) |code_index| { @@ -3197,7 +3236,7 @@ fn writeToFile( } // Data section - if (wasm.data_segments.count() != 0) { + if (data_segments_count != 0) { const header_offset = try reserveVecSectionHeader(&binary_bytes); var it = wasm.data_segments.iterator(); @@ -3212,10 +3251,15 @@ fn writeToFile( segment_count += 1; var atom_index = wasm.atoms.get(segment_index).?; - // flag and index to memory section (currently, there can only be 1 memory section in wasm) - try leb.writeULEB128(binary_writer, @as(u32, 0)); + try leb.writeULEB128(binary_writer, segment.flags); + if (segment.flags & @enumToInt(Wasm.Segment.Flag.WASM_DATA_SEGMENT_HAS_MEMINDEX) != 0) { + try leb.writeULEB128(binary_writer, @as(u32, 0)); // memory is always index 0 as we only have 1 memory entry + } + // when a segment is passive, it's initialized during runtime. + if (!segment.isPassive()) { + try emitInit(binary_writer, .{ .i32_const = @bitCast(i32, segment.offset) }); + } // offset into data section - try emitInit(binary_writer, .{ .i32_const = @bitCast(i32, segment.offset) }); try leb.writeULEB128(binary_writer, segment.size); // fill in the offset table and the data segments From ff28c8b60080b24ae7d5e9d485b6aa47e8c8de9c Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Tue, 14 Mar 2023 19:51:30 +0100 Subject: [PATCH 018/216] wasm-linker: create TLS symbols Initialize TLS symbols when shared-memory is enabled. Those symbols will be called by synthetic functions created by the linker. (TODO). --- src/link/Wasm.zig | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 720e10fe03..d66facb912 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -443,6 +443,30 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option // at the end during `initializeCallCtorsFunction`. } + // shared-memory symbols for TLS support + if (wasm_bin.base.options.shared_memory) { + { + const loc = try wasm_bin.createSyntheticSymbol("__tls_base", .global); + const symbol = loc.getSymbol(wasm_bin); + symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); + } + { + const loc = try wasm_bin.createSyntheticSymbol("__tls_size", .global); + const symbol = loc.getSymbol(wasm_bin); + symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); + } + { + const loc = try wasm_bin.createSyntheticSymbol("__tls_align", .global); + const symbol = loc.getSymbol(wasm_bin); + symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); + } + { + const loc = try wasm_bin.createSyntheticSymbol("__wasm_tls_init", .function); + const symbol = loc.getSymbol(wasm_bin); + symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); + } + } + // if (!options.strip and options.module != null) { // wasm_bin.dwarf = Dwarf.init(allocator, &wasm_bin.base, options.target); // try wasm_bin.initDebugSections(); @@ -2286,12 +2310,28 @@ fn setupMemory(wasm: *Wasm) !void { // set TLS-related symbols if (mem.eql(u8, entry.key_ptr.*, ".tdata")) { - if (wasm.findGlobalSymbol("__tls_base")) |loc| { + if (wasm.findGlobalSymbol("__tls_size")) |loc| { const sym = loc.getSymbol(wasm); sym.index = @intCast(u32, wasm.wasm_globals.items.len) + wasm.imported_globals_count; try wasm.wasm_globals.append(wasm.base.allocator, .{ .global_type = .{ .valtype = .i32, .mutable = false }, - .init = .{ .i32_const = @intCast(i32, memory_ptr) }, + .init = .{ .i32_const = @intCast(i32, segment.size) }, + }); + } + if (wasm.findGlobalSymbol("__tls_align")) |loc| { + const sym = loc.getSymbol(wasm); + sym.index = @intCast(u32, wasm.wasm_globals.items.len) + wasm.imported_globals_count; + try wasm.wasm_globals.append(wasm.base.allocator, .{ + .global_type = .{ .valtype = .i32, .mutable = false }, + .init = .{ .i32_const = @intCast(i32, segment.alignment) }, + }); + } + if (wasm.findGlobalSymbol("__tls_base")) |loc| { + const sym = loc.getSymbol(wasm); + sym.index = @intCast(u32, wasm.wasm_globals.items.len) + wasm.imported_globals_count; + try wasm.wasm_globals.append(wasm.base.allocator, .{ + .global_type = .{ .valtype = .i32, .mutable = wasm.base.options.shared_memory }, + .init = .{ .i32_const = if (wasm.base.options.shared_memory) @as(u32, 0) else @intCast(i32, memory_ptr) }, }); } } From 9d13c2257dcae11d9bc69035e55c33a7dda14a2b Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Wed, 15 Mar 2023 19:27:55 +0100 Subject: [PATCH 019/216] wasm-linker: implement TLS initialization function Implements the TLS initialization function. This is a synthetic function created by the linker. This will only be created when shared-memory is enabled. This function will be called during thread creation, if there's any TLS symbols, which will initialize the TLS segment using the bulk-memory feature. --- src/link/Wasm.zig | 75 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index d66facb912..5d4ab2961b 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1990,10 +1990,23 @@ fn initializeCallCtorsFunction(wasm: *Wasm) !void { try writer.writeByte(std.wasm.opcode(.end)); } - const loc = wasm.findGlobalSymbol("__wasm_call_ctors").?; + try wasm.createSyntheticFunction( + "__wasm_call_ctors", + std.wasm.Type{ .params = &.{}, .returns = &.{} }, + &function_body, + ); +} + +fn createSyntheticFunction( + wasm: *Wasm, + symbol_name: []const u8, + func_ty: std.wasm.Type, + function_body: *std.ArrayList(u8), +) !void { + const loc = wasm.findGlobalSymbol(symbol_name) orelse + try wasm.createSyntheticSymbol(symbol_name, .function); const symbol = loc.getSymbol(wasm); - // create type (() -> nil) as we do not have any parameters or return value. - const ty_index = try wasm.putOrGetFuncType(.{ .params = &[_]std.wasm.Valtype{}, .returns = &[_]std.wasm.Valtype{} }); + const ty_index = try wasm.putOrGetFuncType(func_ty); // create function with above type const func_index = wasm.imported_functions_count + @intCast(u32, wasm.functions.count()); try wasm.functions.putNoClobber( @@ -2025,6 +2038,60 @@ fn initializeCallCtorsFunction(wasm: *Wasm) !void { atom.offset = prev_atom.offset + prev_atom.size; } +fn initializeTLSFunction(wasm: *Wasm) !void { + if (!wasm.base.options.shared_memory) return; + + var function_body = std.ArrayList(u8).init(wasm.base.allocator); + defer function_body.deinit(); + const writer = function_body.writer(); + + // locals + try writer.writeByte(0); + + // If there's a TLS segment, initialize it during runtime using the bulk-memory feature + if (wasm.data_segments.getIndex(".tdata")) |data_index| { + const segment_index = wasm.data_segments.entries.items(.value)[data_index]; + const segment = wasm.segments.items[segment_index]; + + const param_local: u32 = 0; + + try writer.writeByte(std.wasm.opcode(.local_get)); + try leb.writeULEB128(writer, param_local); + + const tls_base_loc = wasm.findGlobalSymbol("__tls_base").?; + try writer.writeByte(std.wasm.opcode(.global_get)); + try leb.writeULEB128(writer, tls_base_loc.getSymbol(wasm).index); + + // load stack values for the bulk-memory operation + { + try writer.writeByte(std.wasm.opcode(.local_get)); + try leb.writeULEB128(writer, param_local); + + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, 0)); //segment offset + + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, segment.size)); //segment offset + } + + // perform the bulk-memory operation to initialize the data segment + try writer.writeByte(std.wasm.opcode(.prefixed)); + try leb.writeULEB128(writer, @enumToInt(std.wasm.PrefixedOpcode.memory_init)); + // segment immediate + try leb.writeULEB128(writer, @intCast(u32, data_index)); + // memory index immediate (always 0) + try leb.writeULEB128(writer, @as(u32, 0)); + } + + try writer.writeByte(std.wasm.opcode(.end)); + + try wasm.createSyntheticFunction( + "__wasm_init_tls", + std.wasm.Type{ .params = &.{.i32}, .returns = &.{} }, + &function_body, + ); +} + fn setupImports(wasm: *Wasm) !void { log.debug("Merging imports", .{}); var discarded_it = wasm.discarded.keyIterator(); @@ -2872,6 +2939,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l try wasm.mergeSections(); try wasm.mergeTypes(); try wasm.initializeCallCtorsFunction(); + try wasm.initializeTLSFunction(); try wasm.setupExports(); try wasm.writeToFile(enabled_features, emit_features_count, arena); @@ -2991,6 +3059,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod try wasm.mergeSections(); try wasm.mergeTypes(); try wasm.initializeCallCtorsFunction(); + try wasm.initializeTLSFunction(); try wasm.setupExports(); try wasm.writeToFile(enabled_features, emit_features_count, arena); } From 9fce1df4cdab57951137c0da2b44fbe6da2442f2 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 17 Mar 2023 06:32:37 +0100 Subject: [PATCH 020/216] wasm-linker: implement runtime TLS relocations --- src/link/Wasm.zig | 63 ++++++++++++++++++++++++++++++++++++++++ src/link/Wasm/Object.zig | 28 ++++++++++++++---- src/link/Wasm/types.zig | 12 -------- 3 files changed, 86 insertions(+), 17 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 5d4ab2961b..eaaabcc89a 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -139,6 +139,8 @@ archives: std.ArrayListUnmanaged(Archive) = .{}, /// A map of global names (read: offset into string table) to their symbol location globals: std.AutoHashMapUnmanaged(u32, SymbolLoc) = .{}, +/// The list of GOT symbols and their location +got_symbols: std.ArrayListUnmanaged(SymbolLoc) = .{}, /// Maps discarded symbols and their positions to the location of the symbol /// it was resolved to discarded: std.AutoHashMapUnmanaged(SymbolLoc, SymbolLoc) = .{}, @@ -635,6 +637,15 @@ fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool { return true; } +fn requiresTLSReloc(wasm: *const Wasm) bool { + for (wasm.got_symbols.items) |loc| { + if (loc.getSymbol(wasm).isTLS()) { + return true; + } + } + return false; +} + fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { const object: Object = wasm.objects.items[object_index]; log.debug("Resolving symbols in object: '{s}'", .{object.name}); @@ -813,6 +824,48 @@ fn resolveSymbolsInArchives(wasm: *Wasm) !void { } } +fn setupTLSRelocationsFunction(wasm: *Wasm) !void { + // When we have TLS GOT entries and shared memory is enabled, + // we must perform runtime relocations or else we don't create the function. + if (!wasm.base.options.shared_memory or !wasm.requiresTLSReloc()) { + return; + } + + // const loc = try wasm.createSyntheticSymbol("__wasm_apply_global_tls_relocs"); + var function_body = std.ArrayList(u8).init(wasm.base.allocator); + defer function_body.deinit(); + const writer = function_body.writer(); + + // locals (we have none) + try writer.writeByte(0); + for (wasm.got_symbols.items, 0..) |got_loc, got_index| { + const sym: *Symbol = got_loc.getSymbol(wasm); + if (!sym.isTLS()) continue; // only relocate TLS symbols + if (sym.tag == .data and sym.isDefined()) { + // get __tls_base + try writer.writeByte(std.wasm.opcode(.global_get)); + try leb.writeULEB128(writer, wasm.findGlobalSymbol("__tls_base").?.getSymbol(wasm).index); + + // add the virtual address of the symbol + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, sym.virtual_address); + } else if (sym.tag == .function) { + @panic("TODO: relocate GOT entry of function"); + } else continue; + + try writer.writeByte(std.wasm.opcode(.i32_add)); + try writer.writeByte(std.wasm.opcode(.global_set)); + try leb.writeULEB128(writer, wasm.imported_globals_count + @intCast(u32, wasm.wasm_globals.items.len + got_index)); + } + try writer.writeByte(std.wasm.opcode(.end)); + + try wasm.createSyntheticFunction( + "__wasm_apply_global_tls_relocs", + std.wasm.Type{ .params = &.{}, .returns = &.{} }, + &function_body, + ); +} + fn validateFeatures( wasm: *const Wasm, to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool, @@ -2083,6 +2136,14 @@ fn initializeTLSFunction(wasm: *Wasm) !void { try leb.writeULEB128(writer, @as(u32, 0)); } + // If we have to perform any TLS relocations, call the corresponding function + // which performs all runtime TLS relocations. This is a synthetic function, + // generated by the linker. + if (wasm.findGlobalSymbol("__wasm_apply_global_tls_relocs")) |loc| { + try writer.writeByte(std.wasm.opcode(.call)); + try leb.writeULEB128(writer, loc.getSymbol(wasm).index); + } + try writer.writeByte(std.wasm.opcode(.end)); try wasm.createSyntheticFunction( @@ -2939,6 +3000,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l try wasm.mergeSections(); try wasm.mergeTypes(); try wasm.initializeCallCtorsFunction(); + try wasm.setupTLSRelocationsFunction(); try wasm.initializeTLSFunction(); try wasm.setupExports(); try wasm.writeToFile(enabled_features, emit_features_count, arena); @@ -3059,6 +3121,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod try wasm.mergeSections(); try wasm.mergeTypes(); try wasm.initializeCallCtorsFunction(); + try wasm.setupTLSRelocationsFunction(); try wasm.initializeTLSFunction(); try wasm.setupExports(); try wasm.writeToFile(enabled_features, emit_features_count, arena); diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index c2243bdf10..363648971a 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -930,11 +930,29 @@ pub fn parseIntoAtoms(object: *Object, gpa: Allocator, object_index: u16, wasm_b reloc.offset -= relocatable_data.offset; try atom.relocs.append(gpa, reloc); - if (relocation.isTableIndex()) { - try wasm_bin.function_table.put(gpa, .{ - .file = object_index, - .index = relocation.index, - }, 0); + switch (relocation.relocation_type) { + .R_WASM_TABLE_INDEX_I32, + .R_WASM_TABLE_INDEX_I64, + .R_WASM_TABLE_INDEX_SLEB, + .R_WASM_TABLE_INDEX_SLEB64, + => { + try wasm_bin.function_table.put(gpa, .{ + .file = object_index, + .index = relocation.index, + }, 0); + }, + .R_WASM_GLOBAL_INDEX_I32, + .R_WASM_GLOBAL_INDEX_LEB, + => { + const sym = object.symtable[relocation.index]; + if (sym.tag != .global) { + try wasm_bin.got_symbols.append( + wasm_bin.base.allocator, + .{ .file = object_index, .index = relocation.index }, + ); + } + }, + else => {}, } } } diff --git a/src/link/Wasm/types.zig b/src/link/Wasm/types.zig index d19f32b862..801c25e9d9 100644 --- a/src/link/Wasm/types.zig +++ b/src/link/Wasm/types.zig @@ -71,18 +71,6 @@ pub const Relocation = struct { }; } - /// Returns true when the relocation represents a table index relocatable - pub fn isTableIndex(self: Relocation) bool { - return switch (self.relocation_type) { - .R_WASM_TABLE_INDEX_I32, - .R_WASM_TABLE_INDEX_I64, - .R_WASM_TABLE_INDEX_SLEB, - .R_WASM_TABLE_INDEX_SLEB64, - => true, - else => false, - }; - } - pub fn format(self: Relocation, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { _ = fmt; _ = options; From 09d6938df9246bac20e84f5512743e96bccdfa3d Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 17 Mar 2023 07:09:01 +0100 Subject: [PATCH 021/216] wasm: add atomics opcodes and refactoring This adds the atomic opcodes for the Threads proposal to the WebAssembly specification: https://github.com/WebAssembly/threads PrefixedOpcode has been renamed to MiscOpcode as there's multiple types of prefixed opcodes. This naming is similar to other tools such as LLVM. As we now use the 0xFE prefix, we moved the function_index MIR instruction as it was occupying the same value. This commit includes renaming all related opcodes. --- lib/std/wasm.zig | 92 ++++++++++++++++++++++++++++++++++++++- src/arch/wasm/CodeGen.zig | 14 +++--- src/arch/wasm/Emit.zig | 18 +++++--- src/arch/wasm/Mir.zig | 23 ++++++---- src/link/Wasm.zig | 4 +- 5 files changed, 126 insertions(+), 25 deletions(-) diff --git a/lib/std/wasm.zig b/lib/std/wasm.zig index 35d0ba4866..d54e998b67 100644 --- a/lib/std/wasm.zig +++ b/lib/std/wasm.zig @@ -189,7 +189,9 @@ pub const Opcode = enum(u8) { i64_extend16_s = 0xC3, i64_extend32_s = 0xC4, - prefixed = 0xFC, + misc_prefix = 0xFC, + simd_prefix = 0xFD, + atomics_prefix = 0xFE, _, }; @@ -217,7 +219,7 @@ test "Wasm - opcodes" { /// Opcodes that require a prefix `0xFC` /// Each opcode represents a varuint32, meaning /// they are encoded as leb128 in binary. -pub const PrefixedOpcode = enum(u32) { +pub const MiscOpcode = enum(u32) { i32_trunc_sat_f32_s = 0x00, i32_trunc_sat_f32_u = 0x01, i32_trunc_sat_f64_s = 0x02, @@ -239,6 +241,12 @@ pub const PrefixedOpcode = enum(u32) { _, }; +/// Returns the integer value of an `MiscOpcode`. Used by the Zig compiler +/// to write instructions to the wasm binary file +pub fn miscOpcode(op: MiscOpcode) u32 { + return @enumToInt(op); +} + /// Simd opcodes that require a prefix `0xFD`. /// Each opcode represents a varuint32, meaning /// they are encoded as leb128 in binary. @@ -510,6 +518,86 @@ pub fn simdOpcode(op: SimdOpcode) u32 { return @enumToInt(op); } +/// Simd opcodes that require a prefix `0xFE`. +/// Each opcode represents a varuint32, meaning +/// they are encoded as leb128 in binary. +pub const AtomicsOpcode = enum(u32) { + memory_atomic_notify = 0x00, + memory_atomic_wait32 = 0x01, + memory_atomic_wait64 = 0x02, + atomic_fence = 0x03, + i32_atomic_load = 0x10, + i64_atomic_load = 0x11, + i32_atomic_load8_u = 0x12, + i32_atomic_load16_u = 0x13, + i64_atomic_load8_u = 0x14, + i64_atomic_load16_u = 0x15, + i64_atomic_load32_u = 0x16, + i32_atomic_store = 0x17, + i64_atomic_store = 0x18, + i32_atomic_store8 = 0x19, + i32_atomic_store16 = 0x1A, + i64_atomic_store8 = 0x1B, + i64_atomic_store16 = 0x1C, + i64_atomic_store32 = 0x1D, + i32_atomic_rmw_add = 0x1E, + i64_atomic_rmw_add = 0x1F, + i32_atomic_rmw8_add_u = 0x20, + i32_atomic_rmw16_add_u = 0x21, + i64_atomic_rmw8_add_u = 0x22, + i64_atomic_rmw16_add_u = 0x23, + i64_atomic_rmw32_add_u = 0x24, + i32_atomic_rmw_sub = 0x25, + i64_atomic_rmw_sub = 0x26, + i32_atomic_rmw8_sub_u = 0x27A, + i32_atomic_rmw16_sub_u = 0x28A, + i64_atomic_rmw8_sub_u = 0x29A, + i64_atomic_rmw16_sub_u = 0x2A, + i64_atomic_rmw32_sub_u = 0x2B, + i32_atomic_rmw_and = 0x2C, + i64_atomic_rmw_and = 0x2D, + i32_atomic_rmw8_and_u = 0x2E, + i32_atomic_rmw16_and_u = 0x2F, + i64_atomic_rmw8_and_u = 0x30, + i64_atomic_rmw16_and_u = 0x31, + i64_atomic_rmw32_and_u = 0x32, + i32_atomic_rmw_or = 0x33, + i64_atomic_rmw_or = 0x34, + i32_atomic_rmw8_or_u = 0x35, + i32_atomic_rmw16_or_u = 0x36, + i64_atomic_rmw8_or_u = 0x37, + i64_atomic_rmw16_or_u = 0x38, + i64_atomic_rmw32_or_u = 0x39, + i32_atomic_rmw_xor = 0x3A, + i64_atomic_rmw_xor = 0x3B, + i32_atomic_rmw8_xor_u = 0x3C, + i32_atomic_rmw16_xor_u = 0x3D, + i64_atomic_rmw8_xor_u = 0x3E, + i64_atomic_rmw16_xor_u = 0x3F, + i64_atomic_rmw32_xor_u = 0x40, + i32_atomic_rmw_xchg = 0x41, + i64_atomic_rmw_xchg = 0x42, + i32_atomic_rmw8_xchg_u = 0x43, + i32_atomic_rmw16_xchg_u = 0x44, + i64_atomic_rmw8_xchg_u = 0x45, + i64_atomic_rmw16_xchg_u = 0x46, + i64_atomic_rmw32_xchg_u = 0x47, + + i32_atomic_rmw_cmpxchg = 0x48, + i64_atomic_rmw_cmpxchg = 0x49, + i32_atomic_rmw8_cmpxchg_u = 0x4A, + i32_atomic_rmw16_cmpxchg_u = 0x4B, + i64_atomic_rmw8_cmpxchg_u = 0x4C, + i64_atomic_rmw16_cmpxchg_u = 0x4D, + i64_atomic_rmw32_cmpxchg_u = 0x4E, +}; + +/// Returns the integer value of an `AtomicsOpcode`. Used by the Zig compiler +/// to write instructions to the wasm binary file +pub fn atomicsOpcode(op: AtomicsOpcode) u32 { + return @enumToInt(op); +} + /// Enum representing all Wasm value types as per spec: /// https://webassembly.github.io/spec/core/binary/types.html pub const Valtype = enum(u8) { diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index e79129ddb8..c05f07a602 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -895,10 +895,10 @@ fn addTag(func: *CodeGen, tag: Mir.Inst.Tag) error{OutOfMemory}!void { try func.addInst(.{ .tag = tag, .data = .{ .tag = {} } }); } -fn addExtended(func: *CodeGen, opcode: wasm.PrefixedOpcode) error{OutOfMemory}!void { +fn addExtended(func: *CodeGen, opcode: wasm.MiscOpcode) error{OutOfMemory}!void { const extra_index = @intCast(u32, func.mir_extra.items.len); try func.mir_extra.append(func.gpa, @enumToInt(opcode)); - try func.addInst(.{ .tag = .extended, .data = .{ .payload = extra_index } }); + try func.addInst(.{ .tag = .misc_prefix, .data = .{ .payload = extra_index } }); } fn addLabel(func: *CodeGen, tag: Mir.Inst.Tag, label: u32) error{OutOfMemory}!void { @@ -925,7 +925,7 @@ fn addImm128(func: *CodeGen, index: u32) error{OutOfMemory}!void { try func.mir_extra.ensureUnusedCapacity(func.gpa, 5); func.mir_extra.appendAssumeCapacity(std.wasm.simdOpcode(.v128_const)); func.mir_extra.appendSliceAssumeCapacity(@alignCast(4, mem.bytesAsSlice(u32, &simd_values))); - try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } }); + try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); } fn addFloat64(func: *CodeGen, float: f64) error{OutOfMemory}!void { @@ -2310,7 +2310,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE offset + lhs.offset(), ty.abiAlignment(func.target), }); - return func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } }); + return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); }, }, .Pointer => { @@ -2420,7 +2420,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu offset + operand.offset(), ty.abiAlignment(func.target), }); - try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } }); + try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); return WValue{ .stack = {} }; } @@ -4477,7 +4477,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { operand.offset(), elem_ty.abiAlignment(func.target), }); - try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } }); + try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); try func.addLabel(.local_set, result.local.value); return func.finishAir(inst, result, &.{ty_op.operand}); }, @@ -4493,7 +4493,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { try func.emitWValue(operand); const extra_index = @intCast(u32, func.mir_extra.items.len); try func.mir_extra.append(func.gpa, opcode); - try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } }); + try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); try func.addLabel(.local_set, result.local.value); return func.finishAir(inst, result, &.{ty_op.operand}); }, diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 7d44d3622f..5982d3b48c 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -239,8 +239,9 @@ pub fn emitMir(emit: *Emit) InnerError!void { .i64_clz => try emit.emitTag(tag), .i64_ctz => try emit.emitTag(tag), - .extended => try emit.emitExtended(inst), - .simd => try emit.emitSimd(inst), + .misc_prefix => try emit.emitExtended(inst), + .simd_prefix => try emit.emitSimd(inst), + .atomics_prefix => try emit.emitAtomic(inst), } } } @@ -433,9 +434,9 @@ fn emitExtended(emit: *Emit, inst: Mir.Inst.Index) !void { const extra_index = emit.mir.instructions.items(.data)[inst].payload; const opcode = emit.mir.extra[extra_index]; const writer = emit.code.writer(); - try emit.code.append(0xFC); + try emit.code.append(std.wasm.opcode(.misc_prefix)); try leb128.writeULEB128(writer, opcode); - switch (@intToEnum(std.wasm.PrefixedOpcode, opcode)) { + switch (@intToEnum(std.wasm.MiscOpcode, opcode)) { // bulk-memory opcodes .data_drop => { const segment = emit.mir.extra[extra_index + 1]; @@ -472,7 +473,7 @@ fn emitSimd(emit: *Emit, inst: Mir.Inst.Index) !void { const extra_index = emit.mir.instructions.items(.data)[inst].payload; const opcode = emit.mir.extra[extra_index]; const writer = emit.code.writer(); - try emit.code.append(0xFD); + try emit.code.append(std.wasm.opcode(.simd_prefix)); try leb128.writeULEB128(writer, opcode); switch (@intToEnum(std.wasm.SimdOpcode, opcode)) { .v128_store, @@ -496,10 +497,15 @@ fn emitSimd(emit: *Emit, inst: Mir.Inst.Index) !void { .f32x4_splat, .f64x2_splat, => {}, // opcode already written - else => |tag| return emit.fail("TODO: Implement simd instruction: {s}\n", .{@tagName(tag)}), + else => |tag| return emit.fail("TODO: Implement simd instruction: {s}", .{@tagName(tag)}), } } +fn emitAtomic(emit: *Emit, inst: Mir.Inst.Index) !void { + _ = inst; + return emit.fail("TODO: Implement atomics instructions", .{}); +} + fn emitMemFill(emit: *Emit) !void { try emit.code.append(0xFC); try emit.code.append(0x0B); diff --git a/src/arch/wasm/Mir.zig b/src/arch/wasm/Mir.zig index 2d59c09e18..4c550d8637 100644 --- a/src/arch/wasm/Mir.zig +++ b/src/arch/wasm/Mir.zig @@ -87,6 +87,13 @@ pub const Inst = struct { /// /// Uses `label` call_indirect = 0x11, + /// Contains a symbol to a function pointer + /// uses `label` + /// + /// Note: This uses `0x16` as value which is reserved by the WebAssembly + /// specification but unused, meaning we must update this if the specification were to + /// use this value. + function_index = 0x16, /// Pops three values from the stack and pushes /// the first or second value dependent on the third value. /// Uses `tag` @@ -510,24 +517,24 @@ pub const Inst = struct { i64_extend16_s = 0xC3, /// Uses `tag` i64_extend32_s = 0xC4, - /// The instruction consists of an extension opcode. + /// The instruction consists of a prefixed opcode. /// The prefixed opcode can be found at payload's index. /// /// The `data` field depends on the extension instruction and /// may contain additional data. - extended = 0xFC, + misc_prefix = 0xFC, /// The instruction consists of a simd opcode. /// The actual simd-opcode is found at payload's index. /// /// The `data` field depends on the simd instruction and /// may contain additional data. - simd = 0xFD, - /// Contains a symbol to a function pointer - /// uses `label` + simd_prefix = 0xFD, + /// The instruction consists of an atomics opcode. + /// The actual atomics-opcode is found at payload's index. /// - /// Note: This uses `0xFE` as value as it is unused and not reserved - /// by the wasm specification, making it safe to use. - function_index = 0xFE, + /// The `data` field depends on the atomics instruction and + /// may contain additional data. + atomics_prefix = 0xFE, /// Contains a symbol to a memory address /// Uses `label` /// diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index eaaabcc89a..5175f760d1 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2128,8 +2128,8 @@ fn initializeTLSFunction(wasm: *Wasm) !void { } // perform the bulk-memory operation to initialize the data segment - try writer.writeByte(std.wasm.opcode(.prefixed)); - try leb.writeULEB128(writer, @enumToInt(std.wasm.PrefixedOpcode.memory_init)); + try writer.writeByte(std.wasm.opcode(.misc_prefix)); + try leb.writeULEB128(writer, std.wasm.miscOpcode(.memory_init)); // segment immediate try leb.writeULEB128(writer, @intCast(u32, data_index)); // memory index immediate (always 0) From 4e0d7154b1a701b906f3d9c5401dc0109253971f Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Sat, 18 Mar 2023 16:02:30 +0100 Subject: [PATCH 022/216] wasm-linker: implement __wasm_init_memory & flag Implements the __wasm_init_memory and __wasm_init_memory_flag synthetic function and symbol. The former will initialize all passive segments during runtime. For the bss section we will fill it with zeroes, whereas the other segments will simply be initialized only. The latter stores the offset into the linear data section, after all heap memory that is part of the Wasm module. Any memory initialized at runtime starts from this offset. --- src/link/Wasm.zig | 203 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 5175f760d1..31169b5de1 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -192,6 +192,14 @@ pub const Segment = struct { pub fn isPassive(segment: Segment) bool { return segment.flags & @enumToInt(Flag.WASM_DATA_SEGMENT_IS_PASSIVE) != 0; } + + /// For a given segment, determines if it needs passive initialization + fn needsPassiveInitialization(segment: Segment, import_mem: bool, name: []const u8) bool { + if (import_mem and !std.mem.eql(u8, name, ".bss")) { + return true; + } + return segment.isPassive(); + } }; pub const Export = struct { @@ -824,6 +832,178 @@ fn resolveSymbolsInArchives(wasm: *Wasm) !void { } } +fn setupInitMemoryFunction(wasm: *Wasm) !void { + // Passive segments are used to avoid memory being reinitialized on each + // thread's instantiation. These passive segments are initialized and + // dropped in __wasm_init_memory, which is registered as the start function + // We also initialize bss segments (using memory.fill) as part of this + // function. + if (!wasm.hasPassiveInitializationSegments()) { + return; + } + + const flag_address: u32 = if (wasm.base.options.shared_memory) address: { + // when we have passive initialization segments and shared memory + // `setupMemory` will create this symbol and set its virtual address. + const loc = wasm.findGlobalSymbol("__wasm_init_memory_flag").?; + break :address loc.getSymbol(wasm).virtual_address; + } else 0; + + var function_body = std.ArrayList(u8).init(wasm.base.allocator); + defer function_body.deinit(); + const writer = function_body.writer(); + + // we have 0 locals + try leb.writeULEB128(writer, @as(u32, 0)); + + if (wasm.base.options.shared_memory) { + // destination blocks + // based on values we jump to corresponding label + try writer.writeByte(std.wasm.opcode(.block)); // $drop + try writer.writeByte(std.wasm.block_empty); // block type + + try writer.writeByte(std.wasm.opcode(.block)); // $wait + try writer.writeByte(std.wasm.block_empty); // block type + + try writer.writeByte(std.wasm.opcode(.block)); // $init + try writer.writeByte(std.wasm.block_empty); // block type + + // atomically check + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, flag_address); + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, 0)); + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, 1)); + try writer.writeByte(std.wasm.opcode(.atomics_prefix)); + try leb.writeULEB128(writer, std.wasm.atomicsOpcode(.i32_atomic_rmw_cmpxchg)); + try leb.writeULEB128(writer, @as(u32, 2)); // alignment + try leb.writeULEB128(writer, @as(u32, 0)); // offset + + // based on the value from the atomic check, jump to the label. + try writer.writeByte(std.wasm.opcode(.br_table)); + try leb.writeULEB128(writer, @as(u32, 2)); // length of the table (we have 3 blocks but because of the mandatory default the length is 2). + try leb.writeULEB128(writer, @as(u32, 0)); // $init + try leb.writeULEB128(writer, @as(u32, 1)); // $wait + try leb.writeULEB128(writer, @as(u32, 2)); // $drop + try writer.writeByte(std.wasm.opcode(.end)); + } + + var it = wasm.data_segments.iterator(); + var segment_index: u32 = 0; + while (it.next()) |entry| : (segment_index += 1) { + const segment: Segment = wasm.segments.items[entry.value_ptr.*]; + if (segment.needsPassiveInitialization(wasm.base.options.import_memory, entry.key_ptr.*)) { + // For passive BSS segments we can simple issue a memory.fill(0). + // For non-BSS segments we do a memory.init. Both these + // instructions take as their first argument the destination + // address. + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, segment.offset); + + if (wasm.base.options.shared_memory and std.mem.eql(u8, entry.key_ptr.*, ".tdata")) { + // When we initialize the TLS segment we also set the `__tls_base` + // global. This allows the runtime to use this static copy of the + // TLS data for the first/main thread. + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, segment.offset); + try writer.writeByte(std.wasm.opcode(.global_set)); + const loc = wasm.findGlobalSymbol("__tls_base").?; + try leb.writeULEB128(writer, loc.getSymbol(wasm).index); + } + + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, 0)); + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, segment.size); + try writer.writeByte(std.wasm.opcode(.misc_prefix)); + if (std.mem.eql(u8, entry.key_ptr.*, ".bss")) { + // fill bss segment with zeroes + try leb.writeULEB128(writer, std.wasm.miscOpcode(.memory_fill)); + } else { + // initialize the segment + try leb.writeULEB128(writer, std.wasm.miscOpcode(.memory_init)); + try leb.writeULEB128(writer, segment_index); + } + try writer.writeByte(0); // memory index immediate + } + } + + if (wasm.base.options.shared_memory) { + // we set the init memory flag to value '2' + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, flag_address); + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, 2)); + try writer.writeByte(std.wasm.opcode(.atomics_prefix)); + try leb.writeULEB128(writer, std.wasm.atomicsOpcode(.i32_atomic_store)); + try leb.writeULEB128(writer, @as(u32, 2)); // alignment + try leb.writeULEB128(writer, @as(u32, 0)); // offset + + // notify any waiters for segment initialization completion + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, flag_address); + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeILEB128(writer, @as(i32, -1)); // number of waiters + try writer.writeByte(std.wasm.opcode(.atomics_prefix)); + try leb.writeULEB128(writer, std.wasm.atomicsOpcode(.memory_atomic_notify)); + try leb.writeULEB128(writer, @as(u32, 2)); // alignment + try leb.writeULEB128(writer, @as(u32, 0)); // offset + try writer.writeByte(std.wasm.opcode(.drop)); + + // branch and drop segments + try writer.writeByte(std.wasm.opcode(.br)); + try leb.writeULEB128(writer, @as(u32, 1)); + + // wait for thread to initialize memory segments + try writer.writeByte(std.wasm.opcode(.end)); // end $wait + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, flag_address); + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeULEB128(writer, @as(u32, 1)); // expected flag value + try writer.writeByte(std.wasm.opcode(.i32_const)); + try leb.writeILEB128(writer, @as(i32, -1)); // timeout + try writer.writeByte(std.wasm.opcode(.atomics_prefix)); + try leb.writeULEB128(writer, std.wasm.atomicsOpcode(.memory_atomic_wait32)); + try leb.writeULEB128(writer, @as(u32, 2)); // alignment + try leb.writeULEB128(writer, @as(u32, 0)); // offset + try writer.writeByte(std.wasm.opcode(.drop)); + + try writer.writeByte(std.wasm.opcode(.end)); // end $drop + } + + it.reset(); + segment_index = 0; + while (it.next()) |entry| : (segment_index += 1) { + const name = entry.key_ptr.*; + const segment: Segment = wasm.segments.items[entry.value_ptr.*]; + if (segment.needsPassiveInitialization(wasm.base.options.import_memory, name) and + !std.mem.eql(u8, name, ".bss")) + { + // The TLS region should not be dropped since its is needed + // during the initialization of each thread (__wasm_init_tls). + if (wasm.base.options.shared_memory and std.mem.eql(u8, name, ".tdata")) { + continue; + } + + try writer.writeByte(std.wasm.opcode(.misc_prefix)); + try leb.writeULEB128(writer, std.wasm.miscOpcode(.data_drop)); + try leb.writeULEB128(writer, segment_index); + } + } + + // End of the function body + try writer.writeByte(std.wasm.opcode(.end)); + + try wasm.createSyntheticFunction( + "__wasm_init_memory", + std.wasm.Type{ .params = &.{}, .returns = &.{} }, + &function_body, + ); +} + +/// Constructs a synthetic function that performs runtime relocations for +/// TLS symbols. This function is called by `__wasm_init_tls`. fn setupTLSRelocationsFunction(wasm: *Wasm) !void { // When we have TLS GOT entries and shared memory is enabled, // we must perform runtime relocations or else we don't create the function. @@ -2469,6 +2649,16 @@ fn setupMemory(wasm: *Wasm) !void { offset += segment.size; } + // create the memory init flag which is used by the init memory function + if (wasm.base.options.shared_memory and wasm.hasPassiveInitializationSegments()) { + // align to pointer size + memory_ptr = mem.alignForwardGeneric(u64, memory_ptr, 4); + const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data); + const sym = loc.getSymbol(wasm); + sym.virtual_address = @intCast(u32, memory_ptr); + memory_ptr += 4; + } + if (!place_stack_first and !is_obj) { memory_ptr = std.mem.alignForwardGeneric(u64, memory_ptr, stack_alignment); memory_ptr += stack_size; @@ -3000,6 +3190,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l try wasm.mergeSections(); try wasm.mergeTypes(); try wasm.initializeCallCtorsFunction(); + try wasm.setupInitMemoryFunction(); try wasm.setupTLSRelocationsFunction(); try wasm.initializeTLSFunction(); try wasm.setupExports(); @@ -3121,6 +3312,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod try wasm.mergeSections(); try wasm.mergeTypes(); try wasm.initializeCallCtorsFunction(); + try wasm.setupInitMemoryFunction(); try wasm.setupTLSRelocationsFunction(); try wasm.initializeTLSFunction(); try wasm.setupExports(); @@ -4473,6 +4665,17 @@ fn emitDataRelocations( try writeCustomSectionHeader(binary_bytes.items, header_offset, size); } +fn hasPassiveInitializationSegments(wasm: *const Wasm) bool { + var it = wasm.data_segments.iterator(); + while (it.next()) |entry| { + const segment: Segment = wasm.segments.items[entry.value_ptr.*]; + if (segment.needsPassiveInitialization(wasm.base.options.import_memory, entry.key_ptr.*)) { + return true; + } + } + return false; +} + pub fn getTypeIndex(wasm: *const Wasm, func_type: std.wasm.Type) ?u32 { var index: u32 = 0; while (index < wasm.func_types.items.len) : (index += 1) { From a23ef3783bb5357376acdce12f73b0285636d6cf Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Mar 2023 12:13:19 +0100 Subject: [PATCH 023/216] os.zig: expose ptrace wrapper for darwin and linux --- lib/std/os.zig | 53 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 25cc4e34c4..d49db10a2f 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -7129,22 +7129,49 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec { pub const PtraceError = error{ DeviceBusy, + InputOutput, + Overflow, ProcessNotFound, PermissionDenied, } || UnexpectedError; -/// TODO on other OSes -pub fn ptrace(request: i32, pid: pid_t, addr: ?[*]u8, signal: i32) PtraceError!void { - switch (builtin.os.tag) { - .macos, .ios, .tvos, .watchos => {}, - else => @compileError("TODO implement ptrace"), - } - return switch (errno(system.ptrace(request, pid, addr, signal))) { - .SUCCESS => {}, - .SRCH => error.ProcessNotFound, - .INVAL => unreachable, - .PERM => error.PermissionDenied, - .BUSY => error.DeviceBusy, - else => |err| return unexpectedErrno(err), +pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!void { + if (builtin.os.tag == .windows or builtin.os.tag == .wasi) + @compileError("Unsupported OS"); + + return switch (builtin.os.tag) { + .linux => switch (errno(linux.ptrace(request, pid, addr, signal, 0))) { + .SUCCESS => {}, + .SRCH => error.ProcessNotFound, + .FAULT => unreachable, + .INVAL => unreachable, + .IO => return error.InputOutput, + .PERM => error.PermissionDenied, + .BUSY => error.DeviceBusy, + else => |err| return unexpectedErrno(err), + }, + + .macos, .ios, .tvos, .watchos => switch (errno(darwin.ptrace( + math.cast(i32, request) orelse return error.Overflow, + pid, + @intToPtr(?[*]u8, addr), + math.cast(i32, signal) orelse return error.Overflow, + ))) { + .SUCCESS => {}, + .SRCH => error.ProcessNotFound, + .INVAL => unreachable, + .PERM => error.PermissionDenied, + .BUSY => error.DeviceBusy, + else => |err| return unexpectedErrno(err), + }, + + else => switch (errno(system.ptrace(request, pid, addr, signal))) { + .SUCCESS => {}, + .SRCH => error.ProcessNotFound, + .INVAL => unreachable, + .PERM => error.PermissionDenied, + .BUSY => error.DeviceBusy, + else => |err| return unexpectedErrno(err), + }, }; } From e35c8a2fd6bb0eb16b45e76a39f4602f1161f357 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Mar 2023 18:09:23 +0100 Subject: [PATCH 024/216] link: use std.os.ptrace wrapper on linux --- src/link.zig | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/link.zig b/src/link.zig index a919ffa999..c91d621305 100644 --- a/src/link.zig +++ b/src/link.zig @@ -389,11 +389,8 @@ pub const File = struct { try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); switch (builtin.os.tag) { - .linux => { - switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0, 0))) { - .SUCCESS => {}, - else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}), - } + .linux => std.os.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { + log.warn("ptrace failure: {s}", .{@errorName(err)}); }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } @@ -430,11 +427,8 @@ pub const File = struct { if (base.child_pid) |pid| { switch (builtin.os.tag) { - .linux => { - switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0, 0))) { - .SUCCESS => {}, - else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}), - } + .linux => std.os.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0) catch |err| { + log.warn("ptrace failure: {s}", .{@errorName(err)}); }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } From 266c81322e4e7b6c0b7f0a7fe9873b092aef7f54 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Mar 2023 18:48:16 +0100 Subject: [PATCH 025/216] darwin: resurrect posix_spawn wrappers --- lib/std/c/darwin.zig | 369 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 298 insertions(+), 71 deletions(-) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 75267cc171..ef31bc6d53 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -203,47 +203,6 @@ pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) kern_retu pub extern "c" fn malloc_size(?*const anyopaque) usize; pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; -pub const posix_spawnattr_t = *opaque {}; -pub const posix_spawn_file_actions_t = *opaque {}; -pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int; -pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int; -pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: c_short) c_int; -pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) c_int; -pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int; -pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int; -pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; -pub extern "c" fn posix_spawn_file_actions_addopen( - actions: *posix_spawn_file_actions_t, - filedes: fd_t, - path: [*:0]const u8, - oflag: c_int, - mode: mode_t, -) c_int; -pub extern "c" fn posix_spawn_file_actions_adddup2( - actions: *posix_spawn_file_actions_t, - filedes: fd_t, - newfiledes: fd_t, -) c_int; -pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; -pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int; -pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; -pub extern "c" fn posix_spawn( - pid: *pid_t, - path: [*:0]const u8, - actions: ?*const posix_spawn_file_actions_t, - attr: ?*const posix_spawnattr_t, - argv: [*:null]?[*:0]const u8, - env: [*:null]?[*:0]const u8, -) c_int; -pub extern "c" fn posix_spawnp( - pid: *pid_t, - path: [*:0]const u8, - actions: ?*const posix_spawn_file_actions_t, - attr: ?*const posix_spawnattr_t, - argv: [*:null]?[*:0]const u8, - env: [*:null]?[*:0]const u8, -) c_int; - pub extern "c" fn kevent64( kq: c_int, changelist: [*]const kevent64_s, @@ -2176,18 +2135,6 @@ pub const E = enum(u16) { _, }; -pub fn getKernError(err: kern_return_t) KernE { - return @intToEnum(KernE, @truncate(u32, @intCast(usize, err))); -} - -pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError { - if (std.os.unexpected_error_tracing) { - std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)}); - std.debug.dumpCurrentStackTrace(null); - } - return error.Unexpected; -} - /// Kernel return values pub const KernE = enum(u32) { SUCCESS = 0, @@ -3063,6 +3010,29 @@ pub const CPUFAMILY = enum(u32) { _, }; +pub const PT = struct { + pub const TRACE_ME = 0; + pub const READ_I = 1; + pub const READ_D = 2; + pub const READ_U = 3; + pub const WRITE_I = 4; + pub const WRITE_D = 5; + pub const WRITE_U = 6; + pub const CONTINUE = 7; + pub const KILL = 8; + pub const STEP = 9; + pub const DETACH = 11; + pub const SIGEXC = 12; + pub const THUPDATE = 13; + pub const ATTACHEXC = 14; + pub const FORCEQUOTA = 30; + pub const DENY_ATTACH = 31; +}; + +pub const caddr_t = ?[*]u8; + +pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int; + pub const POSIX_SPAWN_RESETIDS = 0x0001; pub const POSIX_SPAWN_SETPGROUP = 0x0002; pub const POSIX_SPAWN_SETSIGDEF = 0x0004; @@ -3074,26 +3044,283 @@ pub const POSIX_SPAWN_SETSID = 0x0400; pub const _POSIX_SPAWN_RESLIDE = 0x0800; pub const POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000; -pub const PT_TRACE_ME = 0; -pub const PT_READ_I = 1; -pub const PT_READ_D = 2; -pub const PT_READ_U = 3; -pub const PT_WRITE_I = 4; -pub const PT_WRITE_D = 5; -pub const PT_WRITE_U = 6; -pub const PT_CONTINUE = 7; -pub const PT_KILL = 8; -pub const PT_STEP = 9; -pub const PT_DETACH = 11; -pub const PT_SIGEXC = 12; -pub const PT_THUPDATE = 13; -pub const PT_ATTACHEXC = 14; -pub const PT_FORCEQUOTA = 30; -pub const PT_DENY_ATTACH = 31; +pub const posix_spawnattr_t = *opaque {}; +pub const posix_spawn_file_actions_t = *opaque {}; +pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int; +pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int; +pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: c_short) c_int; +pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) c_int; +pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int; +pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int; +pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; +pub extern "c" fn posix_spawn_file_actions_addopen( + actions: *posix_spawn_file_actions_t, + filedes: fd_t, + path: [*:0]const u8, + oflag: c_int, + mode: mode_t, +) c_int; +pub extern "c" fn posix_spawn_file_actions_adddup2( + actions: *posix_spawn_file_actions_t, + filedes: fd_t, + newfiledes: fd_t, +) c_int; +pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; +pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int; +pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; +pub extern "c" fn posix_spawn( + pid: *pid_t, + path: [*:0]const u8, + actions: ?*const posix_spawn_file_actions_t, + attr: ?*const posix_spawnattr_t, + argv: [*:null]?[*:0]const u8, + env: [*:null]?[*:0]const u8, +) c_int; +pub extern "c" fn posix_spawnp( + pid: *pid_t, + path: [*:0]const u8, + actions: ?*const posix_spawn_file_actions_t, + attr: ?*const posix_spawnattr_t, + argv: [*:null]?[*:0]const u8, + env: [*:null]?[*:0]const u8, +) c_int; -pub const caddr_t = ?[*]u8; +pub const PosixSpawn = struct { + const errno = std.os.errno; + const unexpectedErrno = std.os.unexpectedErrno; -pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int; + pub const Error = error{ + SystemResources, + InvalidFileDescriptor, + NameTooLong, + TooBig, + PermissionDenied, + InputOutput, + FileSystem, + FileNotFound, + InvalidExe, + NotDir, + FileBusy, + /// Returned when the child fails to execute either in the pre-exec() initialization step, or + /// when exec(3) is invoked. + ChildExecFailed, + } || std.os.UnexpectedError; + + pub const Attr = struct { + attr: posix_spawnattr_t, + + pub fn init() Error!Attr { + var attr: posix_spawnattr_t = undefined; + switch (errno(posix_spawnattr_init(&attr))) { + .SUCCESS => return Attr{ .attr = attr }, + .NOMEM => return error.SystemResources, + .INVAL => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn deinit(self: *Attr) void { + defer self.* = undefined; + switch (errno(posix_spawnattr_destroy(&self.attr))) { + .SUCCESS => return, + .INVAL => unreachable, // Invalid parameters. + else => unreachable, + } + } + + pub fn get(self: Attr) Error!u16 { + var flags: c_short = undefined; + switch (errno(posix_spawnattr_getflags(&self.attr, &flags))) { + .SUCCESS => return @bitCast(u16, flags), + .INVAL => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn set(self: *Attr, flags: u16) Error!void { + switch (errno(posix_spawnattr_setflags(&self.attr, @bitCast(c_short, flags)))) { + .SUCCESS => return, + .INVAL => unreachable, + else => |err| return unexpectedErrno(err), + } + } + }; + + pub const Actions = struct { + actions: posix_spawn_file_actions_t, + + pub fn init() Error!Actions { + var actions: posix_spawn_file_actions_t = undefined; + switch (errno(posix_spawn_file_actions_init(&actions))) { + .SUCCESS => return Actions{ .actions = actions }, + .NOMEM => return error.SystemResources, + .INVAL => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn deinit(self: *Actions) void { + defer self.* = undefined; + switch (errno(posix_spawn_file_actions_destroy(&self.actions))) { + .SUCCESS => return, + .INVAL => unreachable, // Invalid parameters. + else => unreachable, + } + } + + pub fn open(self: *Actions, fd: fd_t, path: []const u8, flags: u32, mode: mode_t) Error!void { + const posix_path = try std.os.toPosixPath(path); + return self.openZ(fd, &posix_path, flags, mode); + } + + pub fn openZ(self: *Actions, fd: fd_t, path: [*:0]const u8, flags: u32, mode: mode_t) Error!void { + switch (errno(posix_spawn_file_actions_addopen(&self.actions, fd, path, @bitCast(c_int, flags), mode))) { + .SUCCESS => return, + .BADF => return error.InvalidFileDescriptor, + .NOMEM => return error.SystemResources, + .NAMETOOLONG => return error.NameTooLong, + .INVAL => unreachable, // the value of file actions is invalid + else => |err| return unexpectedErrno(err), + } + } + + pub fn close(self: *Actions, fd: fd_t) Error!void { + switch (errno(posix_spawn_file_actions_addclose(&self.actions, fd))) { + .SUCCESS => return, + .BADF => return error.InvalidFileDescriptor, + .NOMEM => return error.SystemResources, + .INVAL => unreachable, // the value of file actions is invalid + .NAMETOOLONG => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn dup2(self: *Actions, fd: fd_t, newfd: fd_t) Error!void { + switch (errno(posix_spawn_file_actions_adddup2(&self.actions, fd, newfd))) { + .SUCCESS => return, + .BADF => return error.InvalidFileDescriptor, + .NOMEM => return error.SystemResources, + .INVAL => unreachable, // the value of file actions is invalid + .NAMETOOLONG => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn inherit(self: *Actions, fd: fd_t) Error!void { + switch (errno(posix_spawn_file_actions_addinherit_np(&self.actions, fd))) { + .SUCCESS => return, + .BADF => return error.InvalidFileDescriptor, + .NOMEM => return error.SystemResources, + .INVAL => unreachable, // the value of file actions is invalid + .NAMETOOLONG => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn chdir(self: *Actions, path: []const u8) Error!void { + const posix_path = try std.os.toPosixPath(path); + return self.chdirZ(&posix_path); + } + + pub fn chdirZ(self: *Actions, path: [*:0]const u8) Error!void { + switch (errno(posix_spawn_file_actions_addchdir_np(&self.actions, path))) { + .SUCCESS => return, + .NOMEM => return error.SystemResources, + .NAMETOOLONG => return error.NameTooLong, + .BADF => unreachable, + .INVAL => unreachable, // the value of file actions is invalid + else => |err| return unexpectedErrno(err), + } + } + + pub fn fchdir(self: *Actions, fd: fd_t) Error!void { + switch (errno(posix_spawn_file_actions_addfchdir_np(&self.actions, fd))) { + .SUCCESS => return, + .BADF => return error.InvalidFileDescriptor, + .NOMEM => return error.SystemResources, + .INVAL => unreachable, // the value of file actions is invalid + .NAMETOOLONG => unreachable, + else => |err| return unexpectedErrno(err), + } + } + }; + + pub fn spawn( + path: []const u8, + actions: ?Actions, + attr: ?Attr, + argv: [*:null]?[*:0]const u8, + envp: [*:null]?[*:0]const u8, + ) Error!pid_t { + const posix_path = try std.os.toPosixPath(path); + return spawnZ(&posix_path, actions, attr, argv, envp); + } + + pub fn spawnZ( + path: [*:0]const u8, + actions: ?Actions, + attr: ?Attr, + argv: [*:null]?[*:0]const u8, + envp: [*:null]?[*:0]const u8, + ) Error!pid_t { + var pid: pid_t = undefined; + switch (errno(posix_spawn( + &pid, + path, + if (actions) |a| &a.actions else null, + if (attr) |a| &a.attr else null, + argv, + envp, + ))) { + .SUCCESS => return pid, + .@"2BIG" => return error.TooBig, + .NOMEM => return error.SystemResources, + .BADF => return error.InvalidFileDescriptor, + .ACCES => return error.PermissionDenied, + .IO => return error.InputOutput, + .LOOP => return error.FileSystem, + .NAMETOOLONG => return error.NameTooLong, + .NOENT => return error.FileNotFound, + .NOEXEC => return error.InvalidExe, + .NOTDIR => return error.NotDir, + .TXTBSY => return error.FileBusy, + .BADARCH => return error.InvalidExe, + .BADEXEC => return error.InvalidExe, + .FAULT => unreachable, + .INVAL => unreachable, + else => |err| return unexpectedErrno(err), + } + } + + pub fn waitpid(pid: pid_t, flags: u32) Error!std.os.WaitPidResult { + var status: c_int = undefined; + while (true) { + const rc = waitpid(pid, &status, @intCast(c_int, flags)); + switch (errno(rc)) { + .SUCCESS => return std.os.WaitPidResult{ + .pid = @intCast(pid_t, rc), + .status = @bitCast(u32, status), + }, + .INTR => continue, + .CHILD => return error.ChildExecFailed, + .INVAL => unreachable, // Invalid flags. + else => unreachable, + } + } + } +}; + +pub fn getKernError(err: kern_return_t) KernE { + return @intToEnum(KernE, @truncate(u32, @intCast(usize, err))); +} + +pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError { + if (std.os.unexpected_error_tracing) { + std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)}); + std.debug.dumpCurrentStackTrace(null); + } + return error.Unexpected; +} pub const MachError = error{ /// Not enough permissions held to perform the requested kernel From f1e25cf43ec60075a4fc6f3eceb5a3af1f9f0712 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 16 Mar 2023 20:41:46 +0100 Subject: [PATCH 026/216] macho: add hot-code swapping poc --- build.zig | 2 + lib/std/macho.zig | 4 + src/link.zig | 16 ++++ src/link/MachO.zig | 55 +++++++++++-- src/link/MachO/Atom.zig | 16 +--- src/link/MachO/Relocation.zig | 146 ++++++++++++++-------------------- src/main.zig | 36 +++++++-- 7 files changed, 165 insertions(+), 110 deletions(-) diff --git a/build.zig b/build.zig index 303495f6ba..60172eaebd 100644 --- a/build.zig +++ b/build.zig @@ -152,6 +152,7 @@ pub fn build(b: *std.Build) !void { if (only_install_lib_files) return; + const entitlements = b.option([]const u8, "entitlements", "Path to entitlements file for hot-code swapping without sudo on macOS"); const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source"); const tracy_callstack = b.option(bool, "tracy-callstack", "Include callstack information with Tracy data. Does nothing if -Dtracy is not provided") orelse (tracy != null); const tracy_allocation = b.option(bool, "tracy-allocation", "Include allocation information with Tracy data. Does nothing if -Dtracy is not provided") orelse (tracy != null); @@ -173,6 +174,7 @@ pub fn build(b: *std.Build) !void { exe.pie = pie; exe.sanitize_thread = sanitize_thread; exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false; + exe.entitlements = entitlements; exe.install(); const compile_step = b.step("compile", "Build the self-hosted compiler"); diff --git a/lib/std/macho.zig b/lib/std/macho.zig index 0c0c1a15cc..8f695b14b7 100644 --- a/lib/std/macho.zig +++ b/lib/std/macho.zig @@ -656,6 +656,10 @@ pub const segment_command_64 = extern struct { pub fn segName(seg: *const segment_command_64) []const u8 { return parseName(&seg.segname); } + + pub fn isWriteable(seg: segment_command_64) bool { + return seg.initprot & PROT.WRITE != 0; + } }; pub const PROT = struct { diff --git a/src/link.zig b/src/link.zig index c91d621305..f1846f184c 100644 --- a/src/link.zig +++ b/src/link.zig @@ -392,6 +392,19 @@ pub const File = struct { .linux => std.os.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { log.warn("ptrace failure: {s}", .{@errorName(err)}); }, + .macos => { + const macho = base.cast(MachO).?; + if (macho.mach_task == null) { + if (std.os.darwin.machTaskForPid(pid)) |task| { + macho.mach_task = task; + std.os.ptrace(std.os.darwin.PT.ATTACHEXC, pid, 0, 0) catch |err| { + log.warn("ptrace failure: {s}", .{@errorName(err)}); + }; + } else |err| { + log.warn("failed to acquire Mach task for child process: {s}", .{@errorName(err)}); + } + } + }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } } @@ -430,6 +443,9 @@ pub const File = struct { .linux => std.os.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0) catch |err| { log.warn("ptrace failure: {s}", .{@errorName(err)}); }, + .macos => std.os.ptrace(std.os.darwin.PT.KILL, pid, 0, 0) catch |err| { + log.warn("ptrace failure: {s}", .{@errorName(err)}); + }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } } diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2f76c49667..274c4dd9aa 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -221,6 +221,9 @@ lazy_bindings: BindingTable = .{}, /// Table of tracked Decls. decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, +/// Mach task used when the compiler is in hot-code swapping mode. +mach_task: ?std.os.darwin.MachTask = null, + const DeclMetadata = struct { atom: Atom.Index, section: u8, @@ -584,7 +587,21 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try self.allocateSpecialSymbols(); for (self.relocs.keys()) |atom_index| { - try Atom.resolveRelocations(self, atom_index); + if (self.relocs.get(atom_index) == null) continue; + + const atom = self.getAtom(atom_index); + const sym = atom.getSymbol(self); + const section = self.sections.get(sym.n_sect - 1).header; + const file_offset = section.offset + sym.n_value - section.addr; + + var code = std.ArrayList(u8).init(self.base.allocator); + defer code.deinit(); + try code.resize(atom.size); + + const amt = try self.base.file.?.preadAll(code.items, file_offset); + if (amt != code.items.len) return error.InputOutput; + + try self.writeAtom(atom_index, code.items); } if (build_options.enable_logging) { @@ -1052,14 +1069,38 @@ pub fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: } } -pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []const u8) !void { +pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { const atom = self.getAtom(atom_index); const sym = atom.getSymbol(self); const section = self.sections.get(sym.n_sect - 1); const file_offset = section.header.offset + sym.n_value - section.header.addr; log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); + + if (self.relocs.get(atom_index)) |relocs| { + try Atom.resolveRelocations(self, atom_index, relocs.items, code); + } + + if (self.base.child_pid) |pid| blk: { + const task = self.mach_task orelse { + log.warn("cannot hot swap: no Mach task acquired for child process with pid {d}", .{pid}); + break :blk; + }; + self.writeAtomToMemory(task, section.segment_index, sym.n_value, code) catch |err| { + log.warn("cannot hot swap: writing to memory failed: {s}", .{@errorName(err)}); + }; + } + try self.base.file.?.pwriteAll(code, file_offset); - try Atom.resolveRelocations(self, atom_index); +} + +fn writeAtomToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void { + const segment = self.segments.items[segment_index]; + if (!segment.isWriteable()) { + try task.setCurrProtection(addr, code.len, macho.PROT.READ | macho.PROT.WRITE | macho.PROT.COPY); + } + defer if (!segment.isWriteable()) task.setCurrProtection(addr, code.len, segment.initprot) catch {}; + const nwritten = try task.writeMem(addr, code, self.base.options.target.cpu.arch); + if (nwritten != code.len) return error.InputOutput; } fn writePtrWidthAtom(self: *MachO, atom_index: Atom.Index) !void { @@ -2063,7 +2104,7 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv else try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none); - const code = switch (res) { + var code = switch (res) { .ok => code_buffer.items, .fail => |em| { decl.analysis = .codegen_failure; @@ -2115,7 +2156,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .none, .{ .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, }); - const code = switch (res) { + var code = switch (res) { .ok => code_buffer.items, .fail => |em| { decl.analysis = .codegen_failure; @@ -2202,7 +2243,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) .parent_atom_index = atom.getSymbolIndex().?, }); - const code = switch (res) { + var code = switch (res) { .ok => code_buffer.items, .fail => |em| { decl.analysis = .codegen_failure; @@ -2375,7 +2416,7 @@ pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 { return sect_id; } -fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) !u64 { +fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 { const gpa = self.base.allocator; const mod = self.base.options.module.?; const decl = mod.declPtr(decl_index); diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 5fb94b7c13..36511dfd78 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -183,19 +183,11 @@ pub fn addLazyBinding(macho_file: *MachO, atom_index: Index, binding: Binding) ! try gop.value_ptr.append(gpa, binding); } -pub fn resolveRelocations(macho_file: *MachO, atom_index: Index) !void { - const atom = macho_file.getAtom(atom_index); - const relocs = macho_file.relocs.get(atom_index) orelse return; - const source_sym = atom.getSymbol(macho_file); - const source_section = macho_file.sections.get(source_sym.n_sect - 1).header; - const file_offset = source_section.offset + source_sym.n_value - source_section.addr; - - log.debug("relocating '{s}'", .{atom.getName(macho_file)}); - - for (relocs.items) |*reloc| { +pub fn resolveRelocations(macho_file: *MachO, atom_index: Index, relocs: []Relocation, code: []u8) !void { + log.debug("relocating '{s}'", .{macho_file.getAtom(atom_index).getName(macho_file)}); + for (relocs) |*reloc| { if (!reloc.dirty) continue; - - try reloc.resolve(macho_file, atom_index, file_offset); + try reloc.resolve(macho_file, atom_index, code); reloc.dirty = false; } } diff --git a/src/link/MachO/Relocation.zig b/src/link/MachO/Relocation.zig index 07e5cf1aa2..6beae8e8ea 100644 --- a/src/link/MachO/Relocation.zig +++ b/src/link/MachO/Relocation.zig @@ -50,7 +50,7 @@ pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index { return macho_file.getAtomIndexForSymbol(self.target); } -pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, base_offset: u64) !void { +pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) !void { const arch = macho_file.base.options.target.cpu.arch; const atom = macho_file.getAtom(atom_index); const source_sym = atom.getSymbol(macho_file); @@ -68,42 +68,28 @@ pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, bas }); switch (arch) { - .aarch64 => return self.resolveAarch64(macho_file, source_addr, target_addr, base_offset), - .x86_64 => return self.resolveX8664(macho_file, source_addr, target_addr, base_offset), + .aarch64 => return self.resolveAarch64(source_addr, target_addr, code), + .x86_64 => return self.resolveX8664(source_addr, target_addr, code), else => unreachable, } } fn resolveAarch64( self: Relocation, - macho_file: *MachO, source_addr: u64, target_addr: i64, - base_offset: u64, + code: []u8, ) !void { const rel_type = @intToEnum(macho.reloc_type_arm64, self.type); if (rel_type == .ARM64_RELOC_UNSIGNED) { - var buffer: [@sizeOf(u64)]u8 = undefined; - const code = blk: { - switch (self.length) { - 2 => { - mem.writeIntLittle(u32, buffer[0..4], @truncate(u32, @bitCast(u64, target_addr))); - break :blk buffer[0..4]; - }, - 3 => { - mem.writeIntLittle(u64, &buffer, @bitCast(u64, target_addr)); - break :blk &buffer; - }, - else => unreachable, - } + return switch (self.length) { + 2 => mem.writeIntLittle(u32, code[self.offset..][0..4], @truncate(u32, @bitCast(u64, target_addr))), + 3 => mem.writeIntLittle(u64, code[self.offset..][0..8], @bitCast(u64, target_addr)), + else => unreachable, }; - return macho_file.base.file.?.pwriteAll(code, base_offset + self.offset); } - var buffer: [@sizeOf(u32)]u8 = undefined; - const amt = try macho_file.base.file.?.preadAll(&buffer, base_offset + self.offset); - if (amt != buffer.len) return error.InputOutput; - + var buffer = code[self.offset..][0..4]; switch (rel_type) { .ARM64_RELOC_BRANCH26 => { const displacement = math.cast( @@ -114,10 +100,10 @@ fn resolveAarch64( .unconditional_branch_immediate = mem.bytesToValue(meta.TagPayload( aarch64.Instruction, aarch64.Instruction.unconditional_branch_immediate, - ), &buffer), + ), buffer), }; inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement >> 2)); - mem.writeIntLittle(u32, &buffer, inst.toU32()); + mem.writeIntLittle(u32, buffer, inst.toU32()); }, .ARM64_RELOC_PAGE21, .ARM64_RELOC_GOT_LOAD_PAGE21, @@ -130,31 +116,31 @@ fn resolveAarch64( .pc_relative_address = mem.bytesToValue(meta.TagPayload( aarch64.Instruction, aarch64.Instruction.pc_relative_address, - ), &buffer), + ), buffer), }; inst.pc_relative_address.immhi = @truncate(u19, pages >> 2); inst.pc_relative_address.immlo = @truncate(u2, pages); - mem.writeIntLittle(u32, &buffer, inst.toU32()); + mem.writeIntLittle(u32, buffer, inst.toU32()); }, .ARM64_RELOC_PAGEOFF12, .ARM64_RELOC_GOT_LOAD_PAGEOFF12, => { const narrowed = @truncate(u12, @intCast(u64, target_addr)); - if (isArithmeticOp(&buffer)) { + if (isArithmeticOp(buffer)) { var inst = aarch64.Instruction{ .add_subtract_immediate = mem.bytesToValue(meta.TagPayload( aarch64.Instruction, aarch64.Instruction.add_subtract_immediate, - ), &buffer), + ), buffer), }; inst.add_subtract_immediate.imm12 = narrowed; - mem.writeIntLittle(u32, &buffer, inst.toU32()); + mem.writeIntLittle(u32, buffer, inst.toU32()); } else { var inst = aarch64.Instruction{ .load_store_register = mem.bytesToValue(meta.TagPayload( aarch64.Instruction, aarch64.Instruction.load_store_register, - ), &buffer), + ), buffer), }; const offset: u12 = blk: { if (inst.load_store_register.size == 0) { @@ -170,7 +156,7 @@ fn resolveAarch64( } }; inst.load_store_register.offset = offset; - mem.writeIntLittle(u32, &buffer, inst.toU32()); + mem.writeIntLittle(u32, buffer, inst.toU32()); } }, .ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => { @@ -180,11 +166,11 @@ fn resolveAarch64( size: u2, }; const reg_info: RegInfo = blk: { - if (isArithmeticOp(&buffer)) { + if (isArithmeticOp(buffer)) { const inst = mem.bytesToValue(meta.TagPayload( aarch64.Instruction, aarch64.Instruction.add_subtract_immediate, - ), &buffer); + ), buffer); break :blk .{ .rd = inst.rd, .rn = inst.rn, @@ -194,7 +180,7 @@ fn resolveAarch64( const inst = mem.bytesToValue(meta.TagPayload( aarch64.Instruction, aarch64.Instruction.load_store_register, - ), &buffer); + ), buffer); break :blk .{ .rd = inst.rt, .rn = inst.rn, @@ -214,72 +200,62 @@ fn resolveAarch64( .sf = @truncate(u1, reg_info.size), }, }; - mem.writeIntLittle(u32, &buffer, inst.toU32()); + mem.writeIntLittle(u32, buffer, inst.toU32()); }, .ARM64_RELOC_POINTER_TO_GOT => { const result = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr)); - mem.writeIntLittle(i32, &buffer, result); + mem.writeIntLittle(i32, buffer, result); }, .ARM64_RELOC_SUBTRACTOR => unreachable, .ARM64_RELOC_ADDEND => unreachable, .ARM64_RELOC_UNSIGNED => unreachable, } - try macho_file.base.file.?.pwriteAll(&buffer, base_offset + self.offset); } fn resolveX8664( self: Relocation, - macho_file: *MachO, source_addr: u64, target_addr: i64, - base_offset: u64, + code: []u8, ) !void { const rel_type = @intToEnum(macho.reloc_type_x86_64, self.type); - var buffer: [@sizeOf(u64)]u8 = undefined; - const code = blk: { - switch (rel_type) { - .X86_64_RELOC_BRANCH, - .X86_64_RELOC_GOT, - .X86_64_RELOC_GOT_LOAD, - .X86_64_RELOC_TLV, - => { - const displacement = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4); - mem.writeIntLittle(u32, buffer[0..4], @bitCast(u32, displacement)); - break :blk buffer[0..4]; - }, - .X86_64_RELOC_SIGNED, - .X86_64_RELOC_SIGNED_1, - .X86_64_RELOC_SIGNED_2, - .X86_64_RELOC_SIGNED_4, - => { - const correction: u3 = switch (rel_type) { - .X86_64_RELOC_SIGNED => 0, - .X86_64_RELOC_SIGNED_1 => 1, - .X86_64_RELOC_SIGNED_2 => 2, - .X86_64_RELOC_SIGNED_4 => 4, - else => unreachable, - }; - const displacement = @intCast(i32, target_addr - @intCast(i64, source_addr + correction + 4)); - mem.writeIntLittle(u32, buffer[0..4], @bitCast(u32, displacement)); - break :blk buffer[0..4]; - }, - .X86_64_RELOC_UNSIGNED => { - switch (self.length) { - 2 => { - mem.writeIntLittle(u32, buffer[0..4], @truncate(u32, @bitCast(u64, target_addr))); - break :blk buffer[0..4]; - }, - 3 => { - mem.writeIntLittle(u64, buffer[0..8], @bitCast(u64, target_addr)); - break :blk &buffer; - }, - else => unreachable, - } - }, - .X86_64_RELOC_SUBTRACTOR => unreachable, - } - }; - try macho_file.base.file.?.pwriteAll(code, base_offset + self.offset); + switch (rel_type) { + .X86_64_RELOC_BRANCH, + .X86_64_RELOC_GOT, + .X86_64_RELOC_GOT_LOAD, + .X86_64_RELOC_TLV, + => { + const displacement = @intCast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4); + mem.writeIntLittle(u32, code[self.offset..][0..4], @bitCast(u32, displacement)); + }, + .X86_64_RELOC_SIGNED, + .X86_64_RELOC_SIGNED_1, + .X86_64_RELOC_SIGNED_2, + .X86_64_RELOC_SIGNED_4, + => { + const correction: u3 = switch (rel_type) { + .X86_64_RELOC_SIGNED => 0, + .X86_64_RELOC_SIGNED_1 => 1, + .X86_64_RELOC_SIGNED_2 => 2, + .X86_64_RELOC_SIGNED_4 => 4, + else => unreachable, + }; + const displacement = @intCast(i32, target_addr - @intCast(i64, source_addr + correction + 4)); + mem.writeIntLittle(u32, code[self.offset..][0..4], @bitCast(u32, displacement)); + }, + .X86_64_RELOC_UNSIGNED => { + switch (self.length) { + 2 => { + mem.writeIntLittle(u32, code[self.offset..][0..4], @truncate(u32, @bitCast(u64, target_addr))); + }, + 3 => { + mem.writeIntLittle(u64, code[self.offset..][0..8], @bitCast(u64, target_addr)); + }, + else => unreachable, + } + }, + .X86_64_RELOC_SUBTRACTOR => unreachable, + } } inline fn isArithmeticOp(inst: *const [4]u8) bool { diff --git a/src/main.zig b/src/main.zig index db28a5b09b..7d46f10a22 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3851,15 +3851,39 @@ fn runOrTestHotSwap( if (runtime_args_start) |i| { try argv.appendSlice(all_args[i..]); } - var child = std.ChildProcess.init(argv.items, gpa); - child.stdin_behavior = .Inherit; - child.stdout_behavior = .Inherit; - child.stderr_behavior = .Inherit; + switch (builtin.target.os.tag) { + .macos, .ios, .tvos, .watchos => { + const PosixSpawn = std.os.darwin.PosixSpawn; + var attr = try PosixSpawn.Attr.init(); + defer attr.deinit(); + const flags: u16 = std.os.darwin.POSIX_SPAWN_SETSIGDEF | + std.os.darwin.POSIX_SPAWN_SETSIGMASK | + std.os.darwin._POSIX_SPAWN_DISABLE_ASLR; + try attr.set(flags); - try child.spawn(); + var arena_allocator = std.heap.ArenaAllocator.init(gpa); + defer arena_allocator.deinit(); + const arena = arena_allocator.allocator(); - return child.id; + const argv_buf = try arena.allocSentinel(?[*:0]u8, argv.items.len, null); + for (argv.items, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr; + + const pid = try PosixSpawn.spawn(argv.items[0], null, attr, argv_buf, std.c.environ); + return pid; + }, + else => { + var child = std.ChildProcess.init(argv.items, gpa); + + child.stdin_behavior = .Inherit; + child.stdout_behavior = .Inherit; + child.stderr_behavior = .Inherit; + + try child.spawn(); + + return child.id; + }, + } } const AfterUpdateHook = union(enum) { From 37192bcdcb38be2266133f6d46dce5a842984c06 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 17 Mar 2023 09:25:49 +0100 Subject: [PATCH 027/216] macos: HCS PoC working --- lib/std/c/darwin.zig | 2 +- src/link.zig | 15 +++++++++------ src/link/MachO.zig | 26 ++++++++++++++++++-------- src/main.zig | 31 ++++++++++++++----------------- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index ef31bc6d53..4e5bc73c38 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -3316,7 +3316,7 @@ pub fn getKernError(err: kern_return_t) KernE { pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError { if (std.os.unexpected_error_tracing) { - std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)}); + std.debug.print("unexpected error: {d}\n", .{@enumToInt(err)}); std.debug.dumpCurrentStackTrace(null); } return error.Unexpected; diff --git a/src/link.zig b/src/link.zig index f1846f184c..c87d5b5dd5 100644 --- a/src/link.zig +++ b/src/link.zig @@ -397,9 +397,10 @@ pub const File = struct { if (macho.mach_task == null) { if (std.os.darwin.machTaskForPid(pid)) |task| { macho.mach_task = task; - std.os.ptrace(std.os.darwin.PT.ATTACHEXC, pid, 0, 0) catch |err| { - log.warn("ptrace failure: {s}", .{@errorName(err)}); - }; + // TODO enable ones we register for exceptions + // std.os.ptrace(std.os.darwin.PT.ATTACHEXC, pid, 0, 0) catch |err| { + // log.warn("ptrace failure: {s}", .{@errorName(err)}); + // }; } else |err| { log.warn("failed to acquire Mach task for child process: {s}", .{@errorName(err)}); } @@ -443,9 +444,11 @@ pub const File = struct { .linux => std.os.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0) catch |err| { log.warn("ptrace failure: {s}", .{@errorName(err)}); }, - .macos => std.os.ptrace(std.os.darwin.PT.KILL, pid, 0, 0) catch |err| { - log.warn("ptrace failure: {s}", .{@errorName(err)}); - }, + .macos => {}, + // TODO see comment above in makeWritable + // .macos => std.os.ptrace(std.os.darwin.PT.DETACH, pid, 0, 0) catch |err| { + // log.warn("ptrace failure: {s}", .{@errorName(err)}); + // }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } } diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 274c4dd9aa..869061be38 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -587,7 +587,12 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try self.allocateSpecialSymbols(); for (self.relocs.keys()) |atom_index| { - if (self.relocs.get(atom_index) == null) continue; + const relocs = self.relocs.get(atom_index).?; + const needs_update = for (relocs.items) |reloc| { + if (reloc.dirty) break true; + } else false; + + if (!needs_update) continue; const atom = self.getAtom(atom_index); const sym = atom.getSymbol(self); @@ -1085,7 +1090,7 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { log.warn("cannot hot swap: no Mach task acquired for child process with pid {d}", .{pid}); break :blk; }; - self.writeAtomToMemory(task, section.segment_index, sym.n_value, code) catch |err| { + self.updateAtomInMemory(task, section.segment_index, sym.n_value, code) catch |err| { log.warn("cannot hot swap: writing to memory failed: {s}", .{@errorName(err)}); }; } @@ -1093,13 +1098,13 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { try self.base.file.?.pwriteAll(code, file_offset); } -fn writeAtomToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void { +fn updateAtomInMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void { const segment = self.segments.items[segment_index]; - if (!segment.isWriteable()) { - try task.setCurrProtection(addr, code.len, macho.PROT.READ | macho.PROT.WRITE | macho.PROT.COPY); - } - defer if (!segment.isWriteable()) task.setCurrProtection(addr, code.len, segment.initprot) catch {}; - const nwritten = try task.writeMem(addr, code, self.base.options.target.cpu.arch); + const cpu_arch = self.base.options.target.cpu.arch; + const nwritten = if (!segment.isWriteable()) + try task.writeMemProtected(addr, code, cpu_arch) + else + try task.writeMem(addr, code, cpu_arch); if (nwritten != code.len) return error.InputOutput; } @@ -1109,6 +1114,7 @@ fn writePtrWidthAtom(self: *MachO, atom_index: Atom.Index) !void { } fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { + log.debug("marking relocs dirty by target: {}", .{target}); // TODO: reverse-lookup might come in handy here for (self.relocs.values()) |*relocs| { for (relocs.items) |*reloc| { @@ -1119,6 +1125,7 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { } fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { + log.debug("marking relocs dirty by address: {x}", .{addr}); for (self.relocs.values()) |*relocs| { for (relocs.items) |*reloc| { const target_atom_index = reloc.getTargetAtomIndex(self) orelse continue; @@ -1743,6 +1750,8 @@ pub fn resolveDyldStubBinder(self: *MachO) !void { if (self.dyld_stub_binder_index != null) return; if (self.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports + log.debug("resolving dyld_stub_binder", .{}); + const gpa = self.base.allocator; const sym_index = try self.allocateSymbol(); const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; @@ -2829,6 +2838,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { if (self.linkedit_segment_cmd_index == null) { self.linkedit_segment_cmd_index = @intCast(u8, self.segments.items.len); + try self.segments.append(gpa, .{ .segname = makeStaticString("__LINKEDIT"), .maxprot = macho.PROT.READ, diff --git a/src/main.zig b/src/main.zig index 7d46f10a22..551bd55c42 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3320,21 +3320,20 @@ fn buildOutputType( try server.listen(.{ .in = ip4_addr }); - while (true) { - const conn = try server.accept(); - defer conn.stream.close(); + const conn = try server.accept(); + defer conn.stream.close(); - try serve( - comp, - .{ .handle = conn.stream.handle }, - .{ .handle = conn.stream.handle }, - test_exec_args.items, - self_exe_path, - arg_mode, - all_args, - runtime_args_start, - ); - } + try serve( + comp, + .{ .handle = conn.stream.handle }, + .{ .handle = conn.stream.handle }, + test_exec_args.items, + self_exe_path, + arg_mode, + all_args, + runtime_args_start, + ); + return cleanExit(); }, } @@ -3465,9 +3464,7 @@ fn serve( const hdr = try server.receiveMessage(); switch (hdr.tag) { - .exit => { - return cleanExit(); - }, + .exit => return, .update => { assert(main_progress_node.recently_updated_child == null); tracy.frameMark(); From 0aab3bda126b0221f81533b335c7a6a01749344b Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 17 Mar 2023 14:51:08 +0100 Subject: [PATCH 028/216] macho: add wrappers for attaching/detaching from HCS process --- src/link.zig | 23 +++++------------------ src/link/MachO.zig | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/link.zig b/src/link.zig index c87d5b5dd5..ae6c02c08b 100644 --- a/src/link.zig +++ b/src/link.zig @@ -392,19 +392,8 @@ pub const File = struct { .linux => std.os.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { log.warn("ptrace failure: {s}", .{@errorName(err)}); }, - .macos => { - const macho = base.cast(MachO).?; - if (macho.mach_task == null) { - if (std.os.darwin.machTaskForPid(pid)) |task| { - macho.mach_task = task; - // TODO enable ones we register for exceptions - // std.os.ptrace(std.os.darwin.PT.ATTACHEXC, pid, 0, 0) catch |err| { - // log.warn("ptrace failure: {s}", .{@errorName(err)}); - // }; - } else |err| { - log.warn("failed to acquire Mach task for child process: {s}", .{@errorName(err)}); - } - } + .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| { + log.warn("attaching failed with error: {s}", .{@errorName(err)}); }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } @@ -444,11 +433,9 @@ pub const File = struct { .linux => std.os.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0) catch |err| { log.warn("ptrace failure: {s}", .{@errorName(err)}); }, - .macos => {}, - // TODO see comment above in makeWritable - // .macos => std.os.ptrace(std.os.darwin.PT.DETACH, pid, 0, 0) catch |err| { - // log.warn("ptrace failure: {s}", .{@errorName(err)}); - // }, + .macos => base.cast(MachO).?.ptraceDetach(pid) catch |err| { + log.warn("detaching failed with error: {s}", .{@errorName(err)}); + }, else => return error.HotSwapUnavailableOnHostOperatingSystem, } } diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 869061be38..3d0b8b2f77 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3811,6 +3811,28 @@ pub fn allocatedVirtualSize(self: *MachO, start: u64) u64 { return min_pos - start; } +pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void { + const mach_task = try std.os.darwin.machTaskForPid(pid); + log.debug("Mach task for pid {d}: {any}", .{ pid, mach_task }); + self.mach_task = mach_task; + + // TODO start exception handler in another thread + + // TODO enable ones we register for exceptions + // try std.os.ptrace(std.os.darwin.PT.ATTACHEXC, pid, 0, 0); +} + +pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { + _ = pid; + + // TODO stop exception handler + + // TODO see comment in ptraceAttach + // try std.os.ptrace(std.os.darwin.PT.DETACH, pid, 0, 0); + + self.mach_task = null; +} + pub fn makeStaticString(bytes: []const u8) [16]u8 { var buf = [_]u8{0} ** 16; assert(bytes.len <= buf.len); From 6f15eedff1bd32085808ab58f095ab549b493745 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 17 Mar 2023 15:16:31 +0100 Subject: [PATCH 029/216] darwin: put posix spawn constants in POSIX_SPAWN struct --- lib/std/c/darwin.zig | 22 ++++++++++++---------- src/main.zig | 10 +++++++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 4e5bc73c38..eefa68e6a9 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -3033,16 +3033,18 @@ pub const caddr_t = ?[*]u8; pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int; -pub const POSIX_SPAWN_RESETIDS = 0x0001; -pub const POSIX_SPAWN_SETPGROUP = 0x0002; -pub const POSIX_SPAWN_SETSIGDEF = 0x0004; -pub const POSIX_SPAWN_SETSIGMASK = 0x0008; -pub const POSIX_SPAWN_SETEXEC = 0x0040; -pub const POSIX_SPAWN_START_SUSPENDED = 0x0080; -pub const _POSIX_SPAWN_DISABLE_ASLR = 0x0100; -pub const POSIX_SPAWN_SETSID = 0x0400; -pub const _POSIX_SPAWN_RESLIDE = 0x0800; -pub const POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000; +pub const POSIX_SPAWN = struct { + pub const RESETIDS = 0x0001; + pub const SETPGROUP = 0x0002; + pub const SETSIGDEF = 0x0004; + pub const SETSIGMASK = 0x0008; + pub const SETEXEC = 0x0040; + pub const START_SUSPENDED = 0x0080; + pub const DISABLE_ASLR = 0x0100; + pub const SETSID = 0x0400; + pub const RESLIDE = 0x0800; + pub const CLOEXEC_DEFAULT = 0x4000; +}; pub const posix_spawnattr_t = *opaque {}; pub const posix_spawn_file_actions_t = *opaque {}; diff --git a/src/main.zig b/src/main.zig index 551bd55c42..961d649d38 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3852,11 +3852,15 @@ fn runOrTestHotSwap( switch (builtin.target.os.tag) { .macos, .ios, .tvos, .watchos => { const PosixSpawn = std.os.darwin.PosixSpawn; + var attr = try PosixSpawn.Attr.init(); defer attr.deinit(); - const flags: u16 = std.os.darwin.POSIX_SPAWN_SETSIGDEF | - std.os.darwin.POSIX_SPAWN_SETSIGMASK | - std.os.darwin._POSIX_SPAWN_DISABLE_ASLR; + + // ASLR is probably a good default for better debugging experience/programming + // with hot-code updates in mind. However, we can also make it work with ASLR on. + const flags: u16 = std.os.darwin.POSIX_SPAWN.SETSIGDEF | + std.os.darwin.POSIX_SPAWN.SETSIGMASK | + std.os.darwin.POSIX_SPAWN.DISABLE_ASLR; try attr.set(flags); var arena_allocator = std.heap.ArenaAllocator.init(gpa); From 8f481dfc3c4f12327499485e3bf10fbbb1023186 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 18 Mar 2023 18:32:43 -0700 Subject: [PATCH 030/216] fix std.Build.OptionsStep * use the same hash function as the rest of the steps * fix race condition due to a macOS oddity. * fix race condition due to file truncation (rename into place instead) * integrate with marking Step.result_cached. check if the file already exists with fs.access before doing anything else. * use a directory so that the file basename can be "options.zig" instead of a hash digest. * better error reporting in case of file system failures. --- lib/std/Build.zig | 4 +- lib/std/Build/OptionsStep.zig | 82 +++++++++++++++++++++++-------- test/standalone.zig | 5 ++ test/standalone/options/build.zig | 7 +-- 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 056a7ec639..5b974bb816 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1737,7 +1737,7 @@ pub fn makeTempPath(b: *Build) []const u8 { const rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ hex64(rand_int); const result_path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch @panic("OOM"); - fs.cwd().makePath(result_path) catch |err| { + b.cache_root.handle.makePath(tmp_dir_sub_path) catch |err| { std.debug.print("unable to make tmp path '{s}': {s}\n", .{ result_path, @errorName(err), }); @@ -1747,7 +1747,7 @@ pub fn makeTempPath(b: *Build) []const u8 { /// There are a few copies of this function in miscellaneous places. Would be nice to find /// a home for them. -fn hex64(x: u64) [16]u8 { +pub fn hex64(x: u64) [16]u8 { const hex_charset = "0123456789abcdef"; var result: [16]u8 = undefined; var i: usize = 0; diff --git a/lib/std/Build/OptionsStep.zig b/lib/std/Build/OptionsStep.zig index 859d0b68c9..a0e72e3695 100644 --- a/lib/std/Build/OptionsStep.zig +++ b/lib/std/Build/OptionsStep.zig @@ -241,33 +241,75 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { ); } - var options_dir = try b.cache_root.handle.makeOpenPath("options", .{}); - defer options_dir.close(); + const basename = "options.zig"; - const basename = self.hashContentsToFileName(); + // Hash contents to file name. + var hash = b.cache.hash; + // Random bytes to make unique. Refresh this with new random bytes when + // implementation is modified in a non-backwards-compatible way. + hash.add(@as(u32, 0x38845ef8)); + hash.addBytes(self.contents.items); + const sub_path = "c" ++ fs.path.sep_str ++ hash.final() ++ fs.path.sep_str ++ basename; - try options_dir.writeFile(&basename, self.contents.items); + self.generated_file.path = try b.cache_root.join(b.allocator, &.{sub_path}); - self.generated_file.path = try b.cache_root.join(b.allocator, &.{ "options", &basename }); -} + // Optimize for the hot path. Stat the file, and if it already exists, + // cache hit. + if (b.cache_root.handle.access(sub_path, .{})) |_| { + // This is the hot path, success. + step.result_cached = true; + return; + } else |outer_err| switch (outer_err) { + error.FileNotFound => { + const sub_dirname = fs.path.dirname(sub_path).?; + b.cache_root.handle.makePath(sub_dirname) catch |e| { + return step.fail("unable to make path '{}{s}': {s}", .{ + b.cache_root, sub_dirname, @errorName(e), + }); + }; -fn hashContentsToFileName(self: *OptionsStep) [64]u8 { - // TODO update to use the cache system instead of this - // This implementation is copied from `WriteFileStep.make` + const rand_int = std.crypto.random.int(u64); + const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ + std.Build.hex64(rand_int) ++ fs.path.sep_str ++ + basename; + const tmp_sub_path_dirname = fs.path.dirname(tmp_sub_path).?; - var hash = std.crypto.hash.blake2.Blake2b384.init(.{}); + b.cache_root.handle.makePath(tmp_sub_path_dirname) catch |err| { + return step.fail("unable to make temporary directory '{}{s}': {s}", .{ + b.cache_root, tmp_sub_path_dirname, @errorName(err), + }); + }; - // Random bytes to make OptionsStep unique. Refresh this with - // new random bytes when OptionsStep implementation is modified - // in a non-backwards-compatible way. - hash.update("yL0Ya4KkmcCjBlP8"); - hash.update(self.contents.items); + b.cache_root.handle.writeFile(tmp_sub_path, self.contents.items) catch |err| { + return step.fail("unable to write options to '{}{s}': {s}", .{ + b.cache_root, tmp_sub_path, @errorName(err), + }); + }; - var digest: [48]u8 = undefined; - hash.final(&digest); - var hash_basename: [64]u8 = undefined; - _ = fs.base64_encoder.encode(&hash_basename, &digest); - return hash_basename; + b.cache_root.handle.rename(tmp_sub_path, sub_path) catch |err| switch (err) { + error.PathAlreadyExists => { + // Other process beat us to it. Clean up the temp file. + b.cache_root.handle.deleteFile(tmp_sub_path) catch |e| { + try step.addError("warning: unable to delete temp file '{}{s}': {s}", .{ + b.cache_root, tmp_sub_path, @errorName(e), + }); + }; + step.result_cached = true; + return; + }, + else => { + return step.fail("unable to rename options from '{}{s}' to '{}{s}': {s}", .{ + b.cache_root, tmp_sub_path, + b.cache_root, sub_path, + @errorName(err), + }); + }, + }; + }, + else => |e| return step.fail("unable to access options file '{}{s}': {s}", .{ + b.cache_root, sub_path, @errorName(e), + }), + } } const OptionArtifactArg = struct { diff --git a/test/standalone.zig b/test/standalone.zig index 4cf795a85f..98297e9578 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -213,6 +213,11 @@ pub const build_cases = [_]BuildCase{ .build_root = "test/standalone/issue_13030", .import = @import("standalone/issue_13030/build.zig"), }, + // TODO restore this test + //.{ + // .build_root = "test/standalone/options", + // .import = @import("standalone/options/build.zig"), + //}, }; const std = @import("std"); diff --git a/test/standalone/options/build.zig b/test/standalone/options/build.zig index 5e894102a7..28e7e31eb7 100644 --- a/test/standalone/options/build.zig +++ b/test/standalone/options/build.zig @@ -1,13 +1,10 @@ const std = @import("std"); pub fn build(b: *std.Build) void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - const main = b.addTest(.{ .root_source_file = .{ .path = "src/main.zig" }, - .target = target, - .optimize = optimize, + .target = .{}, + .optimize = .Debug, }); const options = b.addOptions(); From f026939a40b3567f1a798547391b398dc40db49a Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 19 Mar 2023 09:45:05 +0100 Subject: [PATCH 031/216] macho: enable hot update state only when on compatible host --- src/link/MachO.zig | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 3d0b8b2f77..3ee2ccde2d 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -221,8 +221,13 @@ lazy_bindings: BindingTable = .{}, /// Table of tracked Decls. decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, -/// Mach task used when the compiler is in hot-code swapping mode. -mach_task: ?std.os.darwin.MachTask = null, +/// Hot-code swapping state. +hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, + +const is_hot_update_compatible = switch (builtin.target.os.tag) { + .macos => true, + else => false, +}; const DeclMetadata = struct { atom: Atom.Index, @@ -303,6 +308,10 @@ pub const SymbolWithLoc = struct { } }; +const HotUpdateState = struct { + mach_task: ?std.os.darwin.MachTask = null, +}; + /// When allocating, the ideal_capacity is calculated by /// actual_capacity + (actual_capacity / ideal_factor) const ideal_factor = 3; @@ -1085,14 +1094,16 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { try Atom.resolveRelocations(self, atom_index, relocs.items, code); } - if (self.base.child_pid) |pid| blk: { - const task = self.mach_task orelse { - log.warn("cannot hot swap: no Mach task acquired for child process with pid {d}", .{pid}); - break :blk; - }; - self.updateAtomInMemory(task, section.segment_index, sym.n_value, code) catch |err| { - log.warn("cannot hot swap: writing to memory failed: {s}", .{@errorName(err)}); - }; + if (is_hot_update_compatible) { + if (self.base.child_pid) |pid| blk: { + const task = self.hot_state.mach_task orelse { + log.warn("cannot hot swap: no Mach task acquired for child process with pid {d}", .{pid}); + break :blk; + }; + self.updateAtomInMemory(task, section.segment_index, sym.n_value, code) catch |err| { + log.warn("cannot hot swap: writing to memory failed: {s}", .{@errorName(err)}); + }; + } } try self.base.file.?.pwriteAll(code, file_offset); @@ -3812,9 +3823,11 @@ pub fn allocatedVirtualSize(self: *MachO, start: u64) u64 { } pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void { + if (!is_hot_update_compatible) return; + const mach_task = try std.os.darwin.machTaskForPid(pid); log.debug("Mach task for pid {d}: {any}", .{ pid, mach_task }); - self.mach_task = mach_task; + self.hot_state.mach_task = mach_task; // TODO start exception handler in another thread @@ -3823,6 +3836,8 @@ pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void { } pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { + if (!is_hot_update_compatible) return; + _ = pid; // TODO stop exception handler @@ -3830,7 +3845,7 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { // TODO see comment in ptraceAttach // try std.os.ptrace(std.os.darwin.PT.DETACH, pid, 0, 0); - self.mach_task = null; + self.hot_state.mach_task = null; } pub fn makeStaticString(bytes: []const u8) [16]u8 { From 6874b2930891363e1fc393d99f59f361eb69eada Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 19 Mar 2023 17:13:38 +0100 Subject: [PATCH 032/216] macho: fix 32bit build --- src/link/MachO.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 3ee2ccde2d..151b947141 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -610,7 +610,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No var code = std.ArrayList(u8).init(self.base.allocator); defer code.deinit(); - try code.resize(atom.size); + try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); const amt = try self.base.file.?.preadAll(code.items, file_offset); if (amt != code.items.len) return error.InputOutput; From 2fce991d2ab1dfc6d591b560607ef0edecc7db19 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 8 Mar 2023 01:06:50 -0800 Subject: [PATCH 033/216] Remove std.os.windows.QueryInformationFile (a wrapper of NtQueryInformationFile) This function is unused, and the current implementation contains a few footguns: - The current wrapper treats all possible errors as unexpected, even likely ones like BUFFER_OVERFLOW (which is returned if the size of the out_buffer is too small to contain all the variable-length members of the requested info, which the user may not actually care about) - Each caller may need to handle errors differently, different errors might be possible depending on the FILE_INFORMATION_CLASS, etc, and making a wrapper that handles all of those different use-cases nicely seems like it'd be more trouble than it's worth (FILE_INFORMATION_CLASS has 76 different possible values) If a wrapper for NtQueryInformationFile is wanted, then it should probably have wrapper functions per-use-case, like how QueryObjectName wraps NtQueryObject for the `ObjectNameInformation` class --- lib/std/os/windows.zig | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 5576200ea5..28dac40c9a 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1230,23 +1230,6 @@ test "GetFinalPathNameByHandle" { _ = try GetFinalPathNameByHandle(handle, .{ .volume_name = .Dos }, buffer[0..required_len_in_u16]); } -pub const QueryInformationFileError = error{Unexpected}; - -pub fn QueryInformationFile( - handle: HANDLE, - info_class: FILE_INFORMATION_CLASS, - out_buffer: []u8, -) QueryInformationFileError!void { - var io: IO_STATUS_BLOCK = undefined; - const len_bytes = std.math.cast(u32, out_buffer.len) orelse unreachable; - const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class); - switch (rc) { - .SUCCESS => {}, - .INVALID_PARAMETER => unreachable, - else => return unexpectedStatus(rc), - } -} - pub const GetFileSizeError = error{Unexpected}; pub fn GetFileSizeEx(hFile: HANDLE) GetFileSizeError!u64 { From 30aeb41a19d3ac15c89190cd546cbe7c05c60ac8 Mon Sep 17 00:00:00 2001 From: Ganesan Rajagopal Date: Mon, 5 Dec 2022 16:17:19 +0530 Subject: [PATCH 034/216] Fix linker segfault adding rpath to sharedlib If the shared library is a relative path, dirname will return null causing a segfault. In the case I debugged, the current directory was already in RPATH so just ignoring this case seems a reasonable fix. After this fix "make" and "make test" pass for mimalloc. Closes #13766 --- src/link/Elf.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index f1ab98372e..fcab34bf5e 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1636,7 +1636,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v } for (self.base.options.objects) |obj| { if (Compilation.classifyFileExt(obj.path) == .shared_library) { - const lib_dir_path = std.fs.path.dirname(obj.path).?; + const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) { try argv.append("-rpath"); try argv.append(lib_dir_path); From 30427ff794514d51cb5066b9e50113da998e0fd0 Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Sun, 19 Mar 2023 16:23:05 -0700 Subject: [PATCH 035/216] Fix GetFileInformationByHandle compile error (#14829) * Fix GetFileInformationByHandle compile error The wrapper function was mistakenly referencing ntdll.zig when the actual function is declared in kernel32.zig. * delete GetFileInformationByHandle since it's not used by the stdlib --- lib/std/os/windows.zig | 15 --------------- lib/std/os/windows/kernel32.zig | 5 ----- 2 files changed, 20 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 28dac40c9a..36b84d657b 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1708,21 +1708,6 @@ pub fn LocalFree(hMem: HLOCAL) void { assert(kernel32.LocalFree(hMem) == null); } -pub const GetFileInformationByHandleError = error{Unexpected}; - -pub fn GetFileInformationByHandle( - hFile: HANDLE, -) GetFileInformationByHandleError!BY_HANDLE_FILE_INFORMATION { - var info: BY_HANDLE_FILE_INFORMATION = undefined; - const rc = ntdll.GetFileInformationByHandle(hFile, &info); - if (rc == 0) { - switch (kernel32.GetLastError()) { - else => |err| return unexpectedError(err), - } - } - return info; -} - pub const SetFileTimeError = error{Unexpected}; pub fn SetFileTime( diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 1fd8a406d5..942d7ddba7 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -202,11 +202,6 @@ pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*:0]const WCHAR) callc pub extern "kernel32" fn GetLastError() callconv(WINAPI) Win32Error; pub extern "kernel32" fn SetLastError(dwErrCode: Win32Error) callconv(WINAPI) void; -pub extern "kernel32" fn GetFileInformationByHandle( - hFile: HANDLE, - lpFileInformation: *BY_HANDLE_FILE_INFORMATION, -) callconv(WINAPI) BOOL; - pub extern "kernel32" fn GetFileInformationByHandleEx( in_hFile: HANDLE, in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, From 5b5466626810302371b2d21c39e7ad04ea13a8dc Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 20 Mar 2023 16:12:51 +0100 Subject: [PATCH 036/216] macho+zld: relax assumption about dead strip atoms uniqueness In case the compiler outputted an object file that is not slicable into subsections, entry point may overlap with a section atom which is perfectly fine, so don't panic in that case. --- src/link/MachO/dead_strip.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index 9dfd6226b4..a132ecb2de 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -102,7 +102,7 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void { }; if (is_gc_root) { - try roots.putNoClobber(atom_index, {}); + _ = try roots.getOrPut(atom_index); log.debug("root(ATOM({d}, %{d}, {?d}))", .{ atom_index, From 0c169127338ef8af752d1a077e412b5135e300d5 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 16 Mar 2023 17:46:34 +0200 Subject: [PATCH 037/216] std: improve error for formatting a function body type Closes #14915 --- lib/std/fmt.zig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 8167a2b252..1658f8a502 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -703,10 +703,7 @@ pub fn formatType( } try writer.writeAll(" }"); }, - .Fn => { - if (actual_fmt.len != 0) invalidFmtError(fmt, value); - return format(writer, "{s}@{x}", .{ @typeName(T), @ptrToInt(value) }); - }, + .Fn => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), .Type => { if (actual_fmt.len != 0) invalidFmtError(fmt, value); return formatBuf(@typeName(value), options, writer); From 5df31f3ef3d2c4640fa2c7fc9b03c83c6a8606ae Mon Sep 17 00:00:00 2001 From: KOUNOIKE Yuusuke Date: Tue, 21 Mar 2023 01:45:12 +0900 Subject: [PATCH 038/216] add wasm-simd support for suggestVectorSizeForCpu (#14992) --- lib/std/simd.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/std/simd.zig b/lib/std/simd.zig index 71d56daec3..c2e0d9f972 100644 --- a/lib/std/simd.zig +++ b/lib/std/simd.zig @@ -43,6 +43,8 @@ pub fn suggestVectorSizeForCpu(comptime T: type, comptime cpu: std.Target.Cpu) ? // for multiple processing, but I don't know what's optimal here, if using // the 2048 bits or using just 64 per vector or something in between if (std.Target.sparc.featureSetHasAny(cpu.features, .{ .vis, .vis2, .vis3 })) break :blk 64; + } else if (cpu.arch.isWasm()) { + if (std.Target.wasm.featureSetHas(cpu.features, .simd128)) break :blk 128; } return null; }; From 626a75bbc21453237f95c186d1fea790f233bc58 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 19 Mar 2023 16:26:19 -0700 Subject: [PATCH 039/216] std.Build.RunStep: fix control flow with qemu+glibc logic --- lib/std/Build/RunStep.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/Build/RunStep.zig b/lib/std/Build/RunStep.zig index feeb64f6ca..36b409d907 100644 --- a/lib/std/Build/RunStep.zig +++ b/lib/std/Build/RunStep.zig @@ -594,7 +594,8 @@ fn runCommand( .qemu => |bin_name| { if (b.enable_qemu) { const glibc_dir_arg = if (need_cross_glibc) - b.glibc_runtimes_dir orelse return + b.glibc_runtimes_dir orelse + return failForeign(self, "--glibc-runtimes", argv[0], exe) else null; From 773b1c4c5cdf9fde19cbf09d0f81f1bfe27ed7ca Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 20 Mar 2023 18:05:52 +0200 Subject: [PATCH 040/216] llvm: fix lowering packed union initiated to zero-bit value Closes #14980 --- src/codegen/llvm.zig | 2 ++ test/behavior/union.zig | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 11fc44747e..dd13087afe 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3815,6 +3815,8 @@ pub const DeclGen = struct { const field_ty = union_obj.fields.values()[field_index].ty; if (union_obj.layout == .Packed) { + if (!field_ty.hasRuntimeBits()) + return llvm_union_ty.constNull(); const non_int_val = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val }); const ty_bit_size = @intCast(u16, field_ty.bitSize(target)); const small_int_ty = dg.context.intType(ty_bit_size); diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 9b49f8bf47..ff3f0b7e54 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1493,3 +1493,23 @@ test "union reassignment can use previous value" { a = U{ .b = a.a }; try expect(a.b == 32); } + +test "packed union with zero-bit field" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + + const S = packed struct { + nested: packed union { + zero: void, + sized: u32, + }, + bar: u32, + + fn doTest(self: @This()) !void { + try expect(self.bar == 42); + } + }; + try S.doTest(.{ .nested = .{ .zero = {} }, .bar = 42 }); +} From 9d9815fb9c21c91df41422ff582402fb56029328 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 20 Mar 2023 18:30:33 +0200 Subject: [PATCH 041/216] Value: handle comparisons of runtime_values Closes #15004 --- src/value.zig | 10 ++++++++++ test/behavior/src.zig | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/value.zig b/src/value.zig index e5283d1270..1b6d2adc1e 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1113,6 +1113,10 @@ pub const Value = extern union { .bool_true, => return BigIntMutable.init(&space.limbs, 1).toConst(), + .runtime_value => { + const sub_val = val.castTag(.runtime_value).?.data; + return sub_val.toBigIntAdvanced(space, target, opt_sema); + }, .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(), .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(), .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(), @@ -1979,6 +1983,12 @@ pub const Value = extern union { .variable, => .gt, + .runtime_value => { + // This is needed to correctly handle hashing the value. + // Checks in Sema should prevent direct comparisons from reaching here. + const val = lhs.castTag(.runtime_value).?.data; + return val.orderAgainstZeroAdvanced(opt_sema); + }, .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0), .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0), .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0), diff --git a/test/behavior/src.zig b/test/behavior/src.zig index 77e420afcf..e6b84e5d56 100644 --- a/test/behavior/src.zig +++ b/test/behavior/src.zig @@ -32,3 +32,14 @@ test "@src used as a comptime parameter" { const T2 = S.Foo(@src()); try expect(T1 != T2); } + +test "@src in tuple passed to anytype function" { + const S = struct { + fn Foo(a: anytype) u32 { + return a[0].line; + } + }; + const l1 = S.Foo(.{@src()}); + const l2 = S.Foo(.{@src()}); + try expect(l1 != l2); +} From 82133cd992575ab567091eaf2f12fbe5e326b5df Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 21 Mar 2023 00:09:00 +0200 Subject: [PATCH 042/216] Sema: improve error message of field access of wrapped type Closes #15027 --- src/Sema.zig | 48 ++++++++++++++++++- .../field_access_of_wrapped_type.zig | 20 ++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/field_access_of_wrapped_type.zig diff --git a/src/Sema.zig b/src/Sema.zig index 0afce47e76..6d6a9a13e8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2127,6 +2127,50 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError return sema.failWithOwnedErrorMsg(msg); } +fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError { + const inner_ty = if (object_ty.isSinglePointer()) object_ty.childType() else object_ty; + + if (inner_ty.zigTypeTag() == .Optional) opt: { + var buf: Type.Payload.ElemType = undefined; + const child_ty = inner_ty.optionalChild(&buf); + if (!typeSupportsFieldAccess(child_ty, field_name)) break :opt; + const msg = msg: { + const msg = try sema.errMsg(block, src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); + errdefer msg.destroy(sema.gpa); + try sema.errNote(block, src, msg, "consider using '.?', 'orelse', or 'if'", .{}); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(msg); + } else if (inner_ty.zigTypeTag() == .ErrorUnion) err: { + const child_ty = inner_ty.errorUnionPayload(); + if (!typeSupportsFieldAccess(child_ty, field_name)) break :err; + const msg = msg: { + const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); + errdefer msg.destroy(sema.gpa); + try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{}); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(msg); + } + return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); +} + +fn typeSupportsFieldAccess(ty: Type, field_name: []const u8) bool { + switch (ty.zigTypeTag()) { + .Array => return mem.eql(u8, field_name, "len"), + .Pointer => { + const ptr_info = ty.ptrInfo().data; + if (ptr_info.size == .Slice) { + return mem.eql(u8, field_name, "ptr") or mem.eql(u8, field_name, "len"); + } else if (ptr_info.pointee_type.zigTypeTag() == .Array) { + return mem.eql(u8, field_name, "len"); + } else return false; + }, + .Type, .Struct, .Union => return true, + else => return false, + } +} + /// We don't return a pointer to the new error note because the pointer /// becomes invalid when you add another one. fn errNote( @@ -23321,7 +23365,7 @@ fn fieldVal( }, else => {}, } - return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); + return sema.failWithInvalidFieldAccess(block, src, object_ty, field_name); } fn fieldPtr( @@ -23535,7 +23579,7 @@ fn fieldPtr( }, else => {}, } - return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); + return sema.failWithInvalidFieldAccess(block, src, object_ty, field_name); } fn fieldCallBind( diff --git a/test/cases/compile_errors/field_access_of_wrapped_type.zig b/test/cases/compile_errors/field_access_of_wrapped_type.zig new file mode 100644 index 0000000000..9d8a7ef17c --- /dev/null +++ b/test/cases/compile_errors/field_access_of_wrapped_type.zig @@ -0,0 +1,20 @@ +const Foo = struct { + a: i32, +}; +export fn f1() void { + var foo: ?Foo = undefined; + foo.a += 1; +} +export fn f2() void { + var foo: anyerror!Foo = undefined; + foo.a += 1; +} + +// error +// backend=stage2 +// target=native +// +// :6:8: error: optional type '?tmp.Foo' does not support field access +// :6:8: note: consider using '.?', 'orelse', or 'if' +// :10:8: error: error union type 'anyerror!tmp.Foo' does not support field access +// :10:8: note: consider using 'try', 'catch', or 'if' From 3a25f6a22e0f339fcaecc87efb0fa4e5f67bd73c Mon Sep 17 00:00:00 2001 From: mlugg Date: Fri, 17 Mar 2023 12:27:19 +0000 Subject: [PATCH 043/216] Port some stage1 test cases to stage2 There are now very few stage1 cases remaining: * `cases/compile_errors/stage1/obj/*` currently don't work correctly on stage2. There are 6 of these, and most of them are probably fairly simple to fix. * `cases/compile_errors/async/*` and all remaining `safety/*` depend on async; see #6025. Resolves: #14849 --- .../undefined_as_field_type_is_rejected.zig | 4 +- test/compile_errors.zig | 47 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/test/cases/compile_errors/undefined_as_field_type_is_rejected.zig b/test/cases/compile_errors/undefined_as_field_type_is_rejected.zig index b6eb059661..b0abd7139e 100644 --- a/test/cases/compile_errors/undefined_as_field_type_is_rejected.zig +++ b/test/cases/compile_errors/undefined_as_field_type_is_rejected.zig @@ -7,7 +7,7 @@ export fn entry1() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:2:8: error: use of undefined value here causes undefined behavior +// :2:8: error: use of undefined value here causes undefined behavior diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 2d796b9463..5a60ef2e55 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -136,4 +136,51 @@ pub fn addCases(ctx: *Cases) !void { \\const dummy = 0; ); } + + { + const case = ctx.obj("wrong same named struct", .{}); + + case.addError( + \\const a = @import("a.zig"); + \\const b = @import("b.zig"); + \\ + \\export fn entry() void { + \\ var a1: a.Foo = undefined; + \\ bar(&a1); + \\} + \\ + \\fn bar(_: *b.Foo) void {} + , &[_][]const u8{ + ":6:9: error: expected type '*b.Foo', found '*a.Foo'", + ":6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", + ":1:17: note: struct declared here", + ":1:17: note: struct declared here", + ":9:11: note: parameter type declared here", + }); + + case.addSourceFile("a.zig", + \\pub const Foo = struct { + \\ x: i32, + \\}; + ); + + case.addSourceFile("b.zig", + \\pub const Foo = struct { + \\ z: f64, + \\}; + ); + } + + { + const case = ctx.obj("non-printable invalid character", .{}); + + case.addError("\xff\xfe" ++ + \\export fn foo() bool { + \\ return true; + \\} + , &[_][]const u8{ + ":1:1: error: expected type expression, found 'invalid bytes'", + ":1:1: note: invalid byte: '\\xff'", + }); + } } From bc0f246911a35324473f72b770cc5715902cc912 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 19:35:58 -0400 Subject: [PATCH 044/216] tests: add -Dskip-cross-glibc option It is reasonable to pass -Dskip-non-native when unable to run foreign binaries, however there is no option for being able to run foreign static binaries but unable to run foreign dynamic binaries. This can occur when qemu is installed but not cross glibc. --- build.zig | 6 ++++++ test/tests.zig | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/build.zig b/build.zig index 60172eaebd..9926d6e5ec 100644 --- a/build.zig +++ b/build.zig @@ -81,6 +81,7 @@ pub fn build(b: *std.Build) !void { const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release; const skip_release_safe = b.option(bool, "skip-release-safe", "Main test suite skips release-safe builds") orelse skip_release; const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false; + const skip_cross_glibc = b.option(bool, "skip-cross-glibc", "Main test suite skips builds that require cross glibc") orelse false; const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false; const skip_single_threaded = b.option(bool, "skip-single-threaded", "Main test suite skips tests that are single-threaded") orelse false; const skip_stage1 = b.option(bool, "skip-stage1", "Main test suite skips stage1 compile error tests") orelse false; @@ -351,6 +352,7 @@ pub fn build(b: *std.Build) !void { test_cases_options.addOption(bool, "enable_logging", enable_logging); test_cases_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots); test_cases_options.addOption(bool, "skip_non_native", skip_non_native); + test_cases_options.addOption(bool, "skip_cross_glibc", skip_cross_glibc); test_cases_options.addOption(bool, "skip_stage1", skip_stage1); test_cases_options.addOption(bool, "have_llvm", enable_llvm); test_cases_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k); @@ -415,6 +417,7 @@ pub fn build(b: *std.Build) !void { .optimize_modes = optimization_modes, .skip_single_threaded = skip_single_threaded, .skip_non_native = skip_non_native, + .skip_cross_glibc = skip_cross_glibc, .skip_libc = skip_libc, .skip_stage1 = skip_stage1, .skip_stage2 = skip_stage2_tests, @@ -429,6 +432,7 @@ pub fn build(b: *std.Build) !void { .optimize_modes = optimization_modes, .skip_single_threaded = true, .skip_non_native = skip_non_native, + .skip_cross_glibc = skip_cross_glibc, .skip_libc = true, .skip_stage1 = skip_stage1, .skip_stage2 = true, // TODO get all these passing @@ -442,6 +446,7 @@ pub fn build(b: *std.Build) !void { .optimize_modes = optimization_modes, .skip_single_threaded = true, .skip_non_native = skip_non_native, + .skip_cross_glibc = skip_cross_glibc, .skip_libc = true, .skip_stage1 = skip_stage1, .skip_stage2 = true, // TODO get all these passing @@ -473,6 +478,7 @@ pub fn build(b: *std.Build) !void { .optimize_modes = optimization_modes, .skip_single_threaded = skip_single_threaded, .skip_non_native = skip_non_native, + .skip_cross_glibc = skip_cross_glibc, .skip_libc = skip_libc, .skip_stage1 = skip_stage1, .skip_stage2 = true, // TODO get all these passing diff --git a/test/tests.zig b/test/tests.zig index 3166fbc14a..26e684cd0d 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -910,6 +910,7 @@ const ModuleTestOptions = struct { optimize_modes: []const OptimizeMode, skip_single_threaded: bool, skip_non_native: bool, + skip_cross_glibc: bool, skip_libc: bool, skip_stage1: bool, skip_stage2: bool, @@ -923,6 +924,9 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { if (options.skip_non_native and !test_target.target.isNative()) continue; + if (options.skip_cross_glibc and test_target.target.isGnuLibC() and test_target.link_libc) + continue; + if (options.skip_libc and test_target.link_libc) continue; From e70a0b2a6b329a76e9edc4d22c7b923841703a24 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 21 Mar 2023 00:27:33 +0200 Subject: [PATCH 045/216] Value: implement reinterpreting enum field index as integer Closes #15019 --- src/value.zig | 5 +++++ test/behavior/union.zig | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/value.zig b/src/value.zig index 1b6d2adc1e..e677414c0f 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1113,6 +1113,10 @@ pub const Value = extern union { .bool_true, => return BigIntMutable.init(&space.limbs, 1).toConst(), + .enum_field_index => { + const index = val.castTag(.enum_field_index).?.data; + return BigIntMutable.init(&space.limbs, index).toConst(); + }, .runtime_value => { const sub_val = val.castTag(.runtime_value).?.data; return sub_val.toBigIntAdvanced(space, target, opt_sema); @@ -1983,6 +1987,7 @@ pub const Value = extern union { .variable, => .gt, + .enum_field_index => return std.math.order(lhs.castTag(.enum_field_index).?.data, 0), .runtime_value => { // This is needed to correctly handle hashing the value. // Checks in Sema should prevent direct comparisons from reaching here. diff --git a/test/behavior/union.zig b/test/behavior/union.zig index ff3f0b7e54..010b4a1ffa 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1513,3 +1513,23 @@ test "packed union with zero-bit field" { }; try S.doTest(.{ .nested = .{ .zero = {} }, .bar = 42 }); } + +test "reinterpreting enum value inside packed union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + + const U = packed union { + tag: enum { a, b }, + val: u8, + + fn doTest() !void { + var u: @This() = .{ .tag = .a }; + u.val += 1; + try expect(u.tag == .b); + } + }; + try U.doTest(); + comptime try U.doTest(); +} From dff4bbfd2426ce4943972782d2bcffc89b3fd26d Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Tue, 21 Mar 2023 05:54:10 +0100 Subject: [PATCH 046/216] Remove Gimli and Xoodoo from the standard library (#14928) These are great permutations, and there's nothing wrong with them from a practical security perspective. However, both were competing in the NIST lightweight crypto competition. Gimli didn't pass the 3rd selection round, and is not much used in the wild besides Zig and libhydrogen. It will never be standardized and is unlikely to get more traction in the future. Xoodyak, that Xoodoo is the permutation of, was a finalist. It has a lot of advantages and *might* be standardized without NIST. But this is too early to tell, and too risky to commit to it in a standard library. For lightweight crypto, Ascon is the one that we know NIST will standardize and that we can safely rely on from a usage perspective. Switch to a traditional ChaCha-based CSPRNG, with an Ascon-based one as an option for constrained systems. Add a RNG benchmark by the way. Gimli and Xoodoo served us well. Their code will be maintained, but outside the standard library. --- lib/std/crypto.zig | 11 - lib/std/crypto/ascon.zig | 11 + lib/std/crypto/benchmark.zig | 2 - lib/std/crypto/chacha20.zig | 77 ++++- lib/std/crypto/gimli.zig | 527 ----------------------------------- lib/std/crypto/tlcsprng.zig | 18 +- lib/std/crypto/xoodoo.zig | 141 ---------- lib/std/rand.zig | 5 +- lib/std/rand/Ascon.zig | 47 ++-- lib/std/rand/ChaCha.zig | 97 +++++++ lib/std/rand/Gimli.zig | 34 --- lib/std/rand/Xoodoo.zig | 42 --- lib/std/rand/benchmark.zig | 217 +++++++++++++++ 13 files changed, 443 insertions(+), 786 deletions(-) delete mode 100644 lib/std/crypto/gimli.zig delete mode 100644 lib/std/crypto/xoodoo.zig create mode 100644 lib/std/rand/ChaCha.zig delete mode 100644 lib/std/rand/Gimli.zig delete mode 100644 lib/std/rand/Xoodoo.zig create mode 100644 lib/std/rand/benchmark.zig diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index 9b995480aa..6f0d1d9b6e 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -17,8 +17,6 @@ pub const aead = struct { pub const Aes256Ocb = @import("crypto/aes_ocb.zig").Aes256Ocb; }; - pub const Gimli = @import("crypto/gimli.zig").Aead; - pub const chacha_poly = struct { pub const ChaCha20Poly1305 = @import("crypto/chacha20.zig").ChaCha20Poly1305; pub const ChaCha12Poly1305 = @import("crypto/chacha20.zig").ChaCha12Poly1305; @@ -52,8 +50,6 @@ pub const core = struct { pub const keccak = @import("crypto/keccak_p.zig"); pub const Ascon = @import("crypto/ascon.zig").State; - pub const Gimli = @import("crypto/gimli.zig").State; - pub const Xoodoo = @import("crypto/xoodoo.zig").State; /// Modes are generic compositions to construct encryption/decryption functions from block ciphers and permutations. /// @@ -87,7 +83,6 @@ pub const ecc = struct { pub const hash = struct { pub const blake2 = @import("crypto/blake2.zig"); pub const Blake3 = @import("crypto/blake3.zig").Blake3; - pub const Gimli = @import("crypto/gimli.zig").Hash; pub const Md5 = @import("crypto/md5.zig").Md5; pub const Sha1 = @import("crypto/sha1.zig").Sha1; pub const sha2 = @import("crypto/sha2.zig"); @@ -221,8 +216,6 @@ test { _ = aead.aes_ocb.Aes128Ocb; _ = aead.aes_ocb.Aes256Ocb; - _ = aead.Gimli; - _ = aead.chacha_poly.ChaCha20Poly1305; _ = aead.chacha_poly.ChaCha12Poly1305; _ = aead.chacha_poly.ChaCha8Poly1305; @@ -239,8 +232,6 @@ test { _ = core.aes; _ = core.Ascon; - _ = core.Gimli; - _ = core.Xoodoo; _ = core.modes; _ = dh.X25519; @@ -256,7 +247,6 @@ test { _ = hash.blake2; _ = hash.Blake3; - _ = hash.Gimli; _ = hash.Md5; _ = hash.Sha1; _ = hash.sha2; @@ -334,7 +324,6 @@ test "issue #4532: no index out of bounds" { hash.blake2.Blake2b256, hash.blake2.Blake2b384, hash.blake2.Blake2b512, - hash.Gimli, }; inline for (types) |Hasher| { diff --git a/lib/std/crypto/ascon.zig b/lib/std/crypto/ascon.zig index 6de003d436..f37d9acea5 100644 --- a/lib/std/crypto/ascon.zig +++ b/lib/std/crypto/ascon.zig @@ -168,6 +168,17 @@ pub fn State(comptime endian: builtin.Endian) type { state.permuteR(12); } + /// Apply a permutation to the state and prevent backtracking. + /// The rate is expressed in bytes and must be a multiple of the word size (8). + pub inline fn permuteRatchet(state: *Self, comptime rounds: u4, comptime rate: u6) void { + const capacity = block_bytes - rate; + debug.assert(capacity > 0 and capacity % 8 == 0); // capacity must be a multiple of 64 bits + var mask: [capacity / 8]u64 = undefined; + inline for (&mask, state.st[state.st.len - mask.len ..]) |*m, x| m.* = x; + state.permuteR(rounds); + inline for (mask, state.st[state.st.len - mask.len ..]) |m, *x| x.* ^= m; + } + // Core Ascon permutation. inline fn round(state: *Self, rk: u64) void { const x = &state.st; diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index ff098c7804..f512c513e7 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -29,7 +29,6 @@ const hashes = [_]Crypto{ Crypto{ .ty = crypto.hash.sha3.Shake256, .name = "shake-256" }, Crypto{ .ty = crypto.hash.sha3.TurboShake128(null), .name = "turboshake-128" }, Crypto{ .ty = crypto.hash.sha3.TurboShake256(null), .name = "turboshake-256" }, - Crypto{ .ty = crypto.hash.Gimli, .name = "gimli-hash" }, Crypto{ .ty = crypto.hash.blake2.Blake2s256, .name = "blake2s" }, Crypto{ .ty = crypto.hash.blake2.Blake2b512, .name = "blake2b" }, Crypto{ .ty = crypto.hash.Blake3, .name = "blake3" }, @@ -274,7 +273,6 @@ const aeads = [_]Crypto{ Crypto{ .ty = crypto.aead.chacha_poly.XChaCha20Poly1305, .name = "xchacha20Poly1305" }, Crypto{ .ty = crypto.aead.chacha_poly.XChaCha8Poly1305, .name = "xchacha8Poly1305" }, Crypto{ .ty = crypto.aead.salsa_poly.XSalsa20Poly1305, .name = "xsalsa20Poly1305" }, - Crypto{ .ty = crypto.aead.Gimli, .name = "gimli-aead" }, Crypto{ .ty = crypto.aead.aegis.Aegis128L, .name = "aegis-128l" }, Crypto{ .ty = crypto.aead.aegis.Aegis256, .name = "aegis-256" }, Crypto{ .ty = crypto.aead.aes_gcm.Aes128Gcm, .name = "aes128-gcm" }, diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig index 883ee51a62..aa0f148be9 100644 --- a/lib/std/crypto/chacha20.zig +++ b/lib/std/crypto/chacha20.zig @@ -195,6 +195,26 @@ fn ChaChaVecImpl(comptime rounds_nb: usize) type { } } + fn chacha20Stream(out: []u8, key: [8]u32, counter: [4]u32) void { + var ctx = initContext(key, counter); + var x: BlockVec = undefined; + var i: usize = 0; + while (i + 64 <= out.len) : (i += 64) { + chacha20Core(x[0..], ctx); + contextFeedback(&x, ctx); + hashToBytes(out[i..][0..64], x); + ctx[3][0] += 1; + } + if (i < out.len) { + chacha20Core(x[0..], ctx); + contextFeedback(&x, ctx); + + var buf: [64]u8 = undefined; + hashToBytes(buf[0..], x); + mem.copy(u8, out[i..], buf[0 .. out.len - i]); + } + } + fn hchacha20(input: [16]u8, key: [32]u8) [32]u8 { var c: [4]u32 = undefined; for (c, 0..) |_, i| { @@ -336,6 +356,26 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type { } } + fn chacha20Stream(out: []u8, key: [8]u32, counter: [4]u32) void { + var ctx = initContext(key, counter); + var x: BlockVec = undefined; + var i: usize = 0; + while (i + 64 <= out.len) : (i += 64) { + chacha20Core(x[0..], ctx); + contextFeedback(&x, ctx); + hashToBytes(out[i..][0..64], x); + ctx[12] += 1; + } + if (i < out.len) { + chacha20Core(x[0..], ctx); + contextFeedback(&x, ctx); + + var buf: [64]u8 = undefined; + hashToBytes(buf[0..], x); + mem.copy(u8, out[i..], buf[0 .. out.len - i]); + } + } + fn hchacha20(input: [16]u8, key: [32]u8) [32]u8 { var c: [4]u32 = undefined; for (c, 0..) |_, i| { @@ -387,6 +427,8 @@ fn ChaChaIETF(comptime rounds_nb: usize) type { pub const nonce_length = 12; /// Key length in bytes. pub const key_length = 32; + /// Block length in bytes. + pub const block_length = 64; /// Add the output of the ChaCha20 stream cipher to `in` and stores the result into `out`. /// WARNING: This function doesn't provide authenticated encryption. @@ -402,6 +444,18 @@ fn ChaChaIETF(comptime rounds_nb: usize) type { d[3] = mem.readIntLittle(u32, nonce[8..12]); ChaChaImpl(rounds_nb).chacha20Xor(out, in, keyToWords(key), d); } + + /// Write the output of the ChaCha20 stream cipher into `out`. + pub fn stream(out: []u8, counter: u32, key: [key_length]u8, nonce: [nonce_length]u8) void { + assert(out.len / 64 <= (1 << 32 - 1) - counter); + + var d: [4]u32 = undefined; + d[0] = counter; + d[1] = mem.readIntLittle(u32, nonce[0..4]); + d[2] = mem.readIntLittle(u32, nonce[4..8]); + d[3] = mem.readIntLittle(u32, nonce[8..12]); + ChaChaImpl(rounds_nb).chacha20Stream(out, keyToWords(key), d); + } }; } @@ -411,6 +465,8 @@ fn ChaChaWith64BitNonce(comptime rounds_nb: usize) type { pub const nonce_length = 8; /// Key length in bytes. pub const key_length = 32; + /// Block length in bytes. + pub const block_length = 64; /// Add the output of the ChaCha20 stream cipher to `in` and stores the result into `out`. /// WARNING: This function doesn't provide authenticated encryption. @@ -427,7 +483,6 @@ fn ChaChaWith64BitNonce(comptime rounds_nb: usize) type { c[2] = mem.readIntLittle(u32, nonce[0..4]); c[3] = mem.readIntLittle(u32, nonce[4..8]); - const block_length = (1 << 6); // The full block size is greater than the address space on a 32bit machine const big_block = if (@sizeOf(usize) > 4) (block_length << 32) else maxInt(usize); @@ -448,6 +503,18 @@ fn ChaChaWith64BitNonce(comptime rounds_nb: usize) type { } ChaChaImpl(rounds_nb).chacha20Xor(out[cursor..], in[cursor..], k, c); } + + /// Write the output of the ChaCha20 stream cipher into `out`. + pub fn stream(out: []u8, counter: u32, key: [key_length]u8, nonce: [nonce_length]u8) void { + assert(out.len / 64 <= (1 << 32 - 1) - counter); + const k = keyToWords(key); + var c: [4]u32 = undefined; + c[0] = @truncate(u32, counter); + c[1] = @truncate(u32, counter >> 32); + c[2] = mem.readIntLittle(u32, nonce[0..4]); + c[3] = mem.readIntLittle(u32, nonce[4..8]); + ChaChaImpl(rounds_nb).chacha20Stream(out, k, c); + } }; } @@ -457,6 +524,8 @@ fn XChaChaIETF(comptime rounds_nb: usize) type { pub const nonce_length = 24; /// Key length in bytes. pub const key_length = 32; + /// Block length in bytes. + pub const block_length = 64; /// Add the output of the XChaCha20 stream cipher to `in` and stores the result into `out`. /// WARNING: This function doesn't provide authenticated encryption. @@ -465,6 +534,12 @@ fn XChaChaIETF(comptime rounds_nb: usize) type { const extended = extend(key, nonce, rounds_nb); ChaChaIETF(rounds_nb).xor(out, in, counter, extended.key, extended.nonce); } + + /// Write the output of the XChaCha20 stream cipher into `out`. + pub fn stream(out: []u8, counter: u32, key: [key_length]u8, nonce: [nonce_length]u8) void { + const extended = extend(key, nonce, rounds_nb); + ChaChaIETF(rounds_nb).xor(out, counter, extended.key, extended.nonce); + } }; } diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig deleted file mode 100644 index 0189f4c359..0000000000 --- a/lib/std/crypto/gimli.zig +++ /dev/null @@ -1,527 +0,0 @@ -//! Gimli is a 384-bit permutation designed to achieve high security with high -//! performance across a broad range of platforms, including 64-bit Intel/AMD -//! server CPUs, 64-bit and 32-bit ARM smartphone CPUs, 32-bit ARM -//! microcontrollers, 8-bit AVR microcontrollers, FPGAs, ASICs without -//! side-channel protection, and ASICs with side-channel protection. -//! -//! https://gimli.cr.yp.to/ -//! https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/gimli-spec.pdf - -const std = @import("../std.zig"); -const builtin = @import("builtin"); -const mem = std.mem; -const math = std.math; -const debug = std.debug; -const assert = std.debug.assert; -const testing = std.testing; -const htest = @import("test.zig"); -const AuthenticationError = std.crypto.errors.AuthenticationError; - -pub const State = struct { - pub const BLOCKBYTES = 48; - pub const RATE = 16; - - data: [BLOCKBYTES / 4]u32 align(16), - - const Self = @This(); - - pub fn init(initial_state: [State.BLOCKBYTES]u8) Self { - var data: [BLOCKBYTES / 4]u32 = undefined; - var i: usize = 0; - while (i < State.BLOCKBYTES) : (i += 4) { - data[i / 4] = mem.readIntNative(u32, initial_state[i..][0..4]); - } - return Self{ .data = data }; - } - - /// TODO follow the span() convention instead of having this and `toSliceConst` - pub fn toSlice(self: *Self) *[BLOCKBYTES]u8 { - return mem.asBytes(&self.data); - } - - /// TODO follow the span() convention instead of having this and `toSlice` - pub fn toSliceConst(self: *const Self) *const [BLOCKBYTES]u8 { - return mem.asBytes(&self.data); - } - - inline fn endianSwap(self: *Self) void { - for (&self.data) |*w| { - w.* = mem.littleToNative(u32, w.*); - } - } - - fn permute_unrolled(self: *Self) void { - self.endianSwap(); - const state = &self.data; - comptime var round = @as(u32, 24); - inline while (round > 0) : (round -= 1) { - var column = @as(usize, 0); - while (column < 4) : (column += 1) { - const x = math.rotl(u32, state[column], 24); - const y = math.rotl(u32, state[4 + column], 9); - const z = state[8 + column]; - state[8 + column] = ((x ^ (z << 1)) ^ ((y & z) << 2)); - state[4 + column] = ((y ^ x) ^ ((x | z) << 1)); - state[column] = ((z ^ y) ^ ((x & y) << 3)); - } - switch (round & 3) { - 0 => { - mem.swap(u32, &state[0], &state[1]); - mem.swap(u32, &state[2], &state[3]); - state[0] ^= round | 0x9e377900; - }, - 2 => { - mem.swap(u32, &state[0], &state[2]); - mem.swap(u32, &state[1], &state[3]); - }, - else => {}, - } - } - self.endianSwap(); - } - - fn permute_small(self: *Self) void { - self.endianSwap(); - const state = &self.data; - var round = @as(u32, 24); - while (round > 0) : (round -= 1) { - var column = @as(usize, 0); - while (column < 4) : (column += 1) { - const x = math.rotl(u32, state[column], 24); - const y = math.rotl(u32, state[4 + column], 9); - const z = state[8 + column]; - state[8 + column] = ((x ^ (z << 1)) ^ ((y & z) << 2)); - state[4 + column] = ((y ^ x) ^ ((x | z) << 1)); - state[column] = ((z ^ y) ^ ((x & y) << 3)); - } - switch (round & 3) { - 0 => { - mem.swap(u32, &state[0], &state[1]); - mem.swap(u32, &state[2], &state[3]); - state[0] ^= round | 0x9e377900; - }, - 2 => { - mem.swap(u32, &state[0], &state[2]); - mem.swap(u32, &state[1], &state[3]); - }, - else => {}, - } - } - self.endianSwap(); - } - - const Lane = @Vector(4, u32); - - inline fn shift(x: Lane, comptime n: comptime_int) Lane { - return x << @splat(4, @as(u5, n)); - } - - fn permute_vectorized(self: *Self) void { - self.endianSwap(); - const state = &self.data; - var x = Lane{ state[0], state[1], state[2], state[3] }; - var y = Lane{ state[4], state[5], state[6], state[7] }; - var z = Lane{ state[8], state[9], state[10], state[11] }; - var round = @as(u32, 24); - while (round > 0) : (round -= 1) { - x = math.rotl(Lane, x, 24); - y = math.rotl(Lane, y, 9); - const newz = x ^ shift(z, 1) ^ shift(y & z, 2); - const newy = y ^ x ^ shift(x | z, 1); - const newx = z ^ y ^ shift(x & y, 3); - x = newx; - y = newy; - z = newz; - switch (round & 3) { - 0 => { - x = @shuffle(u32, x, undefined, [_]i32{ 1, 0, 3, 2 }); - x[0] ^= round | 0x9e377900; - }, - 2 => { - x = @shuffle(u32, x, undefined, [_]i32{ 2, 3, 0, 1 }); - }, - else => {}, - } - } - comptime var i: usize = 0; - inline while (i < 4) : (i += 1) { - state[0 + i] = x[i]; - state[4 + i] = y[i]; - state[8 + i] = z[i]; - } - self.endianSwap(); - } - - pub const permute = if (builtin.cpu.arch == .x86_64) impl: { - break :impl permute_vectorized; - } else if (builtin.mode == .ReleaseSmall) impl: { - break :impl permute_small; - } else impl: { - break :impl permute_unrolled; - }; - - pub fn squeeze(self: *Self, out: []u8) void { - var i = @as(usize, 0); - while (i + RATE <= out.len) : (i += RATE) { - self.permute(); - mem.copy(u8, out[i..], self.toSliceConst()[0..RATE]); - } - const leftover = out.len - i; - if (leftover != 0) { - self.permute(); - mem.copy(u8, out[i..], self.toSliceConst()[0..leftover]); - } - } -}; - -test "permute" { - // test vector from gimli-20170627 - const tv_input = [3][4]u32{ - [4]u32{ 0x00000000, 0x9e3779ba, 0x3c6ef37a, 0xdaa66d46 }, - [4]u32{ 0x78dde724, 0x1715611a, 0xb54cdb2e, 0x53845566 }, - [4]u32{ 0xf1bbcfc8, 0x8ff34a5a, 0x2e2ac522, 0xcc624026 }, - }; - var input: [48]u8 = undefined; - var i: usize = 0; - while (i < 12) : (i += 1) { - mem.writeIntLittle(u32, input[i * 4 ..][0..4], tv_input[i / 4][i % 4]); - } - - var state = State.init(input); - state.permute(); - - const tv_output = [3][4]u32{ - [4]u32{ 0xba11c85a, 0x91bad119, 0x380ce880, 0xd24c2c68 }, - [4]u32{ 0x3eceffea, 0x277a921c, 0x4f73a0bd, 0xda5a9cd8 }, - [4]u32{ 0x84b673f0, 0x34e52ff7, 0x9e2bef49, 0xf41bb8d6 }, - }; - var expected_output: [48]u8 = undefined; - i = 0; - while (i < 12) : (i += 1) { - mem.writeIntLittle(u32, expected_output[i * 4 ..][0..4], tv_output[i / 4][i % 4]); - } - try testing.expectEqualSlices(u8, state.toSliceConst(), expected_output[0..]); -} - -pub const Hash = struct { - state: State, - buf_off: usize, - - pub const block_length = State.RATE; - pub const digest_length = 32; - pub const Options = struct {}; - - const Self = @This(); - - pub fn init(options: Options) Self { - _ = options; - return Self{ - .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) }, - .buf_off = 0, - }; - } - - /// Also known as 'absorb' - pub fn update(self: *Self, data: []const u8) void { - const buf = self.state.toSlice(); - var in = data; - while (in.len > 0) { - const left = State.RATE - self.buf_off; - const ps = math.min(in.len, left); - for (buf[self.buf_off .. self.buf_off + ps], 0..) |*p, i| { - p.* ^= in[i]; - } - self.buf_off += ps; - in = in[ps..]; - if (self.buf_off == State.RATE) { - self.state.permute(); - self.buf_off = 0; - } - } - } - - /// Finish the current hashing operation, writing the hash to `out` - /// - /// From 4.9 "Application to hashing" - /// By default, Gimli-Hash provides a fixed-length output of 32 bytes - /// (the concatenation of two 16-byte blocks). However, Gimli-Hash can - /// be used as an “extendable one-way function” (XOF). - pub fn final(self: *Self, out: []u8) void { - const buf = self.state.toSlice(); - - // XOR 1 into the next byte of the state - buf[self.buf_off] ^= 1; - // XOR 1 into the last byte of the state, position 47. - buf[buf.len - 1] ^= 1; - - self.state.squeeze(out); - } - - pub const Error = error{}; - pub const Writer = std.io.Writer(*Self, Error, write); - - fn write(self: *Self, bytes: []const u8) Error!usize { - self.update(bytes); - return bytes.len; - } - - pub fn writer(self: *Self) Writer { - return .{ .context = self }; - } -}; - -pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void { - var st = Hash.init(options); - st.update(in); - st.final(out); -} - -test "hash" { - // a test vector (30) from NIST KAT submission. - var msg: [58 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C"); - var md: [32]u8 = undefined; - hash(&md, &msg, .{}); - try htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md); -} - -test "hash test vector 17" { - var msg: [32 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F"); - var md: [32]u8 = undefined; - hash(&md, &msg, .{}); - try htest.assertEqual("404C130AF1B9023A7908200919F690FFBB756D5176E056FFDE320016A37C7282", &md); -} - -test "hash test vector 33" { - var msg: [32]u8 = undefined; - _ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); - var md: [32]u8 = undefined; - hash(&md, &msg, .{}); - try htest.assertEqual("A8F4FA28708BDA7EFB4C1914CA4AFA9E475B82D588D36504F87DBB0ED9AB3C4B", &md); -} - -pub const Aead = struct { - pub const tag_length = State.RATE; - pub const nonce_length = 16; - pub const key_length = 32; - - /// ad: Associated Data - /// npub: public nonce - /// k: private key - fn init(ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) State { - var state = State{ - .data = undefined, - }; - const buf = state.toSlice(); - - // Gimli-Cipher initializes a 48-byte Gimli state to a 16-byte nonce - // followed by a 32-byte key. - assert(npub.len + k.len == State.BLOCKBYTES); - std.mem.copy(u8, buf[0..npub.len], &npub); - std.mem.copy(u8, buf[npub.len .. npub.len + k.len], &k); - - // It then applies the Gimli permutation. - state.permute(); - - { - // Gimli-Cipher then handles each block of associated data, including - // exactly one final non-full block, in the same way as Gimli-Hash. - var data = ad; - while (data.len >= State.RATE) : (data = data[State.RATE..]) { - for (buf[0..State.RATE], 0..) |*p, i| { - p.* ^= data[i]; - } - state.permute(); - } - for (buf[0..data.len], 0..) |*p, i| { - p.* ^= data[i]; - } - - // XOR 1 into the next byte of the state - buf[data.len] ^= 1; - // XOR 1 into the last byte of the state, position 47. - buf[buf.len - 1] ^= 1; - - state.permute(); - } - - return state; - } - - /// c: ciphertext: output buffer should be of size m.len - /// tag: authentication tag: output MAC - /// m: message - /// ad: Associated Data - /// npub: public nonce - /// k: private key - pub fn encrypt(c: []u8, tag: *[tag_length]u8, m: []const u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) void { - assert(c.len == m.len); - - var state = Aead.init(ad, npub, k); - const buf = state.toSlice(); - - // Gimli-Cipher then handles each block of plaintext, including - // exactly one final non-full block, in the same way as Gimli-Hash. - // Whenever a plaintext byte is XORed into a state byte, the new state - // byte is output as ciphertext. - var in = m; - var out = c; - while (in.len >= State.RATE) : ({ - in = in[State.RATE..]; - out = out[State.RATE..]; - }) { - for (in[0..State.RATE], 0..) |v, i| { - buf[i] ^= v; - } - mem.copy(u8, out[0..State.RATE], buf[0..State.RATE]); - state.permute(); - } - for (in[0..], 0..) |v, i| { - buf[i] ^= v; - out[i] = buf[i]; - } - - // XOR 1 into the next byte of the state - buf[in.len] ^= 1; - // XOR 1 into the last byte of the state, position 47. - buf[buf.len - 1] ^= 1; - - state.permute(); - - // After the final non-full block of plaintext, the first 16 bytes - // of the state are output as an authentication tag. - std.mem.copy(u8, tag, buf[0..State.RATE]); - } - - /// m: message: output buffer should be of size c.len - /// c: ciphertext - /// tag: authentication tag - /// ad: Associated Data - /// npub: public nonce - /// k: private key - /// NOTE: the check of the authentication tag is currently not done in constant time - pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { - assert(c.len == m.len); - - var state = Aead.init(ad, npub, k); - const buf = state.toSlice(); - - var in = c; - var out = m; - while (in.len >= State.RATE) : ({ - in = in[State.RATE..]; - out = out[State.RATE..]; - }) { - const d = in[0..State.RATE].*; - for (d, 0..) |v, i| { - out[i] = buf[i] ^ v; - } - mem.copy(u8, buf[0..State.RATE], d[0..State.RATE]); - state.permute(); - } - for (buf[0..in.len], 0..) |*p, i| { - const d = in[i]; - out[i] = p.* ^ d; - p.* = d; - } - - // XOR 1 into the next byte of the state - buf[in.len] ^= 1; - // XOR 1 into the last byte of the state, position 47. - buf[buf.len - 1] ^= 1; - - state.permute(); - - // After the final non-full block of plaintext, the first 16 bytes - // of the state are the authentication tag. - // TODO: use a constant-time equality check here, see https://github.com/ziglang/zig/issues/1776 - if (!mem.eql(u8, buf[0..State.RATE], &tag)) { - @memset(m.ptr, undefined, m.len); - return error.AuthenticationFailed; - } - } -}; - -test "cipher" { - var key: [32]u8 = undefined; - _ = try std.fmt.hexToBytes(&key, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); - var nonce: [16]u8 = undefined; - _ = try std.fmt.hexToBytes(&nonce, "000102030405060708090A0B0C0D0E0F"); - { // test vector (1) from NIST KAT submission. - const ad: [0]u8 = undefined; - const pt: [0]u8 = undefined; - - var ct: [pt.len]u8 = undefined; - var tag: [16]u8 = undefined; - Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); - try htest.assertEqual("", &ct); - try htest.assertEqual("14DA9BB7120BF58B985A8E00FDEBA15B", &tag); - - var pt2: [pt.len]u8 = undefined; - try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); - try testing.expectEqualSlices(u8, &pt, &pt2); - } - { // test vector (34) from NIST KAT submission. - const ad: [0]u8 = undefined; - var pt: [2 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&pt, "00"); - - var ct: [pt.len]u8 = undefined; - var tag: [16]u8 = undefined; - Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); - try htest.assertEqual("7F", &ct); - try htest.assertEqual("80492C317B1CD58A1EDC3A0D3E9876FC", &tag); - - var pt2: [pt.len]u8 = undefined; - try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); - try testing.expectEqualSlices(u8, &pt, &pt2); - } - { // test vector (106) from NIST KAT submission. - var ad: [12 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&ad, "000102030405"); - var pt: [6 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&pt, "000102"); - - var ct: [pt.len]u8 = undefined; - var tag: [16]u8 = undefined; - Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); - try htest.assertEqual("484D35", &ct); - try htest.assertEqual("030BBEA23B61C00CED60A923BDCF9147", &tag); - - var pt2: [pt.len]u8 = undefined; - try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); - try testing.expectEqualSlices(u8, &pt, &pt2); - } - { // test vector (790) from NIST KAT submission. - var ad: [60 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&ad, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D"); - var pt: [46 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F10111213141516"); - - var ct: [pt.len]u8 = undefined; - var tag: [16]u8 = undefined; - Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); - try htest.assertEqual("6815B4A0ECDAD01596EAD87D9E690697475D234C6A13D1", &ct); - try htest.assertEqual("DFE23F1642508290D68245279558B2FB", &tag); - - var pt2: [pt.len]u8 = undefined; - try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); - try testing.expectEqualSlices(u8, &pt, &pt2); - } - { // test vector (1057) from NIST KAT submission. - const ad: [0]u8 = undefined; - var pt: [64 / 2]u8 = undefined; - _ = try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); - - var ct: [pt.len]u8 = undefined; - var tag: [16]u8 = undefined; - Aead.encrypt(&ct, &tag, &pt, &ad, nonce, key); - try htest.assertEqual("7F8A2CF4F52AA4D6B2E74105C30A2777B9D0C8AEFDD555DE35861BD3011F652F", &ct); - try htest.assertEqual("7256456FA935AC34BBF55AE135F33257", &tag); - - var pt2: [pt.len]u8 = undefined; - try Aead.decrypt(&pt2, &ct, tag, &ad, nonce, key); - try testing.expectEqualSlices(u8, &pt, &pt2); - } -} diff --git a/lib/std/crypto/tlcsprng.zig b/lib/std/crypto/tlcsprng.zig index 5a09e20f07..ac706e5f6a 100644 --- a/lib/std/crypto/tlcsprng.zig +++ b/lib/std/crypto/tlcsprng.zig @@ -41,9 +41,11 @@ const maybe_have_wipe_on_fork = builtin.os.isAtLeast(.linux, .{ }) orelse true; const is_haiku = builtin.os.tag == .haiku; +const Rng = std.rand.DefaultCsprng; + const Context = struct { init_state: enum(u8) { uninitialized = 0, initialized, failed }, - gimli: std.crypto.core.Gimli, + rng: Rng, }; var install_atfork_handler = std.once(struct { @@ -93,7 +95,7 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void { const S = struct { threadlocal var buf: Context align(mem.page_size) = .{ .init_state = .uninitialized, - .gimli = undefined, + .rng = undefined, }; }; wipe_mem = mem.asBytes(&S.buf); @@ -156,12 +158,7 @@ fn childAtForkHandler() callconv(.C) void { fn fillWithCsprng(buffer: []u8) void { const ctx = @ptrCast(*Context, wipe_mem.ptr); - if (buffer.len != 0) { - ctx.gimli.squeeze(buffer); - } else { - ctx.gimli.permute(); - } - mem.set(u8, ctx.gimli.toSlice()[0..std.crypto.core.Gimli.RATE], 0); + return ctx.rng.fill(buffer); } pub fn defaultRandomSeed(buffer: []u8) void { @@ -169,7 +166,7 @@ pub fn defaultRandomSeed(buffer: []u8) void { } fn initAndFill(buffer: []u8) void { - var seed: [std.crypto.core.Gimli.BLOCKBYTES]u8 = undefined; + var seed: [Rng.secret_seed_length]u8 = undefined; // Because we panic on getrandom() failing, we provide the opportunity // to override the default seed function. This also makes // `std.crypto.random` available on freestanding targets, provided that @@ -177,7 +174,8 @@ fn initAndFill(buffer: []u8) void { std.options.cryptoRandomSeed(&seed); const ctx = @ptrCast(*Context, wipe_mem.ptr); - ctx.gimli = std.crypto.core.Gimli.init(seed); + ctx.rng = Rng.init(seed); + std.crypto.utils.secureZero(u8, &seed); // This is at the end so that accidental recursive dependencies result // in stack overflows instead of invalid random data. diff --git a/lib/std/crypto/xoodoo.zig b/lib/std/crypto/xoodoo.zig deleted file mode 100644 index ea3554a635..0000000000 --- a/lib/std/crypto/xoodoo.zig +++ /dev/null @@ -1,141 +0,0 @@ -//! Xoodoo is a 384-bit permutation designed to achieve high security with high -//! performance across a broad range of platforms, including 64-bit Intel/AMD -//! server CPUs, 64-bit and 32-bit ARM smartphone CPUs, 32-bit ARM -//! microcontrollers, 8-bit AVR microcontrollers, FPGAs, ASICs without -//! side-channel protection, and ASICs with side-channel protection. -//! -//! Xoodoo is the core function of Xoodyak, a finalist of the NIST lightweight cryptography competition. -//! https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/Xoodyak-spec.pdf -//! -//! It is not meant to be used directly, but as a building block for symmetric cryptography. - -const std = @import("../std.zig"); -const builtin = @import("builtin"); -const mem = std.mem; -const math = std.math; -const testing = std.testing; - -/// A Xoodoo state. -pub const State = struct { - /// Number of bytes in the state. - pub const block_bytes = 48; - - const rcs = [12]u32{ 0x058, 0x038, 0x3c0, 0x0d0, 0x120, 0x014, 0x060, 0x02c, 0x380, 0x0f0, 0x1a0, 0x012 }; - const Lane = @Vector(4, u32); - st: [3]Lane, - - /// Initialize a state from a slice of bytes. - pub fn init(initial_state: [block_bytes]u8) State { - var state = State{ .st = undefined }; - mem.copy(u8, state.asBytes(), &initial_state); - state.endianSwap(); - return state; - } - - // A representation of the state as 32-bit words. - fn asWords(self: *State) *[12]u32 { - return @ptrCast(*[12]u32, &self.st); - } - - /// A representation of the state as bytes. The byte order is architecture-dependent. - pub fn asBytes(self: *State) *[block_bytes]u8 { - return mem.asBytes(&self.st); - } - - /// Byte-swap words storing the bytes of a given range if the architecture is not little-endian. - pub fn endianSwapPartial(self: *State, from: usize, to: usize) void { - for (self.asWords()[from / 4 .. (to + 3) / 4]) |*w| { - w.* = mem.littleToNative(u32, w.*); - } - } - - /// Byte-swap the entire state if the architecture is not little-endian. - pub fn endianSwap(self: *State) void { - for (self.asWords()) |*w| { - w.* = mem.littleToNative(u32, w.*); - } - } - - /// XOR a byte into the state at a given offset. - pub fn addByte(self: *State, byte: u8, offset: usize) void { - self.endianSwapPartial(offset, offset); - self.asBytes()[offset] ^= byte; - self.endianSwapPartial(offset, offset); - } - - /// XOR bytes into the beginning of the state. - pub fn addBytes(self: *State, bytes: []const u8) void { - self.endianSwap(); - for (self.asBytes()[0..bytes.len], 0..) |*byte, i| { - byte.* ^= bytes[i]; - } - self.endianSwap(); - } - - /// Extract the first bytes of the state. - pub fn extract(self: *State, out: []u8) void { - self.endianSwap(); - mem.copy(u8, out, self.asBytes()[0..out.len]); - self.endianSwap(); - } - - /// Set the words storing the bytes of a given range to zero. - pub fn clear(self: *State, from: usize, to: usize) void { - mem.set(u32, self.asWords()[from / 4 .. (to + 3) / 4], 0); - } - - /// Apply the Xoodoo permutation. - pub fn permute(self: *State) void { - const rot8x32 = comptime if (builtin.target.cpu.arch.endian() == .Big) - [_]i32{ 9, 10, 11, 8, 13, 14, 15, 12, 1, 2, 3, 0, 5, 6, 7, 4 } - else - [_]i32{ 11, 8, 9, 10, 15, 12, 13, 14, 3, 0, 1, 2, 7, 4, 5, 6 }; - - var a = self.st[0]; - var b = self.st[1]; - var c = self.st[2]; - inline for (rcs) |rc| { - var p = @shuffle(u32, a ^ b ^ c, undefined, [_]i32{ 3, 0, 1, 2 }); - var e = math.rotl(Lane, p, 5); - p = math.rotl(Lane, p, 14); - e ^= p; - a ^= e; - b ^= e; - c ^= e; - b = @shuffle(u32, b, undefined, [_]i32{ 3, 0, 1, 2 }); - c = math.rotl(Lane, c, 11); - a[0] ^= rc; - a ^= ~b & c; - b ^= ~c & a; - c ^= ~a & b; - b = math.rotl(Lane, b, 1); - c = @bitCast(Lane, @shuffle(u8, @bitCast(@Vector(16, u8), c), undefined, rot8x32)); - } - self.st[0] = a; - self.st[1] = b; - self.st[2] = c; - } -}; - -test "xoodoo" { - const bytes = [_]u8{0x01} ** State.block_bytes; - var st = State.init(bytes); - var out: [State.block_bytes]u8 = undefined; - st.permute(); - st.extract(&out); - const expected1 = [_]u8{ 51, 240, 163, 117, 43, 238, 62, 200, 114, 52, 79, 41, 48, 108, 150, 181, 24, 5, 252, 185, 235, 179, 28, 3, 116, 170, 36, 15, 232, 35, 116, 61, 110, 4, 109, 227, 91, 205, 0, 180, 179, 146, 112, 235, 96, 212, 206, 205 }; - try testing.expectEqualSlices(u8, &expected1, &out); - st.clear(0, 10); - st.extract(&out); - const expected2 = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 108, 150, 181, 24, 5, 252, 185, 235, 179, 28, 3, 116, 170, 36, 15, 232, 35, 116, 61, 110, 4, 109, 227, 91, 205, 0, 180, 179, 146, 112, 235, 96, 212, 206, 205 }; - try testing.expectEqualSlices(u8, &expected2, &out); - st.addByte(1, 5); - st.addByte(2, 5); - st.extract(&out); - const expected3 = [_]u8{ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 48, 108, 150, 181, 24, 5, 252, 185, 235, 179, 28, 3, 116, 170, 36, 15, 232, 35, 116, 61, 110, 4, 109, 227, 91, 205, 0, 180, 179, 146, 112, 235, 96, 212, 206, 205 }; - try testing.expectEqualSlices(u8, &expected3, &out); - st.addBytes(&bytes); - st.extract(&out); - const expected4 = [_]u8{ 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 49, 109, 151, 180, 25, 4, 253, 184, 234, 178, 29, 2, 117, 171, 37, 14, 233, 34, 117, 60, 111, 5, 108, 226, 90, 204, 1, 181, 178, 147, 113, 234, 97, 213, 207, 204 }; - try testing.expectEqualSlices(u8, &expected4, &out); -} diff --git a/lib/std/rand.zig b/lib/std/rand.zig index 9722a47682..4f9cb0db56 100644 --- a/lib/std/rand.zig +++ b/lib/std/rand.zig @@ -18,11 +18,12 @@ const maxInt = std.math.maxInt; pub const DefaultPrng = Xoshiro256; /// Cryptographically secure random numbers. -pub const DefaultCsprng = Ascon; +pub const DefaultCsprng = ChaCha; pub const Ascon = @import("rand/Ascon.zig"); +pub const ChaCha = @import("rand/ChaCha.zig"); + pub const Isaac64 = @import("rand/Isaac64.zig"); -pub const Xoodoo = @import("rand/Xoodoo.zig"); pub const Pcg = @import("rand/Pcg.zig"); pub const Xoroshiro128 = @import("rand/Xoroshiro128.zig"); pub const Xoshiro256 = @import("rand/Xoshiro256.zig"); diff --git a/lib/std/rand/Ascon.zig b/lib/std/rand/Ascon.zig index b6e8ce4899..3600e02905 100644 --- a/lib/std/rand/Ascon.zig +++ b/lib/std/rand/Ascon.zig @@ -1,4 +1,12 @@ -//! CSPRNG based on the Ascon XOFa construction +//! CSPRNG based on the Reverie construction, a permutation-based PRNG +//! with forward security, instantiated with the Ascon(128,12,8) permutation. +//! +//! Compared to ChaCha, this PRNG is has a much smaller state, and can be +//! a better choice for constrained environments. +//! +//! References: +//! - A Robust and Sponge-Like PRNG with Improved Efficiency https://eprint.iacr.org/2016/886.pdf +//! - Ascon https://ascon.iaik.tugraz.at/files/asconv12-nist.pdf const std = @import("std"); const min = std.math.min; @@ -6,30 +14,38 @@ const mem = std.mem; const Random = std.rand.Random; const Self = @This(); -state: std.crypto.core.Ascon(.Little), +const Ascon = std.crypto.core.Ascon(.Little); -const rate = 8; +state: Ascon, + +const rate = 16; pub const secret_seed_length = 32; /// The seed must be uniform, secret and `secret_seed_length` bytes long. pub fn init(secret_seed: [secret_seed_length]u8) Self { - var state = std.crypto.core.Ascon(.Little).initXofA(); - var i: usize = 0; - while (i + rate <= secret_seed.len) : (i += rate) { - state.addBytes(secret_seed[i..][0..rate]); - state.permuteR(8); - } - const left = secret_seed.len - i; - if (left > 0) state.addBytes(secret_seed[i..]); - state.addByte(0x80, left); - state.permute(); - return Self{ .state = state }; + var self = Self{ .state = Ascon.initXof() }; + self.addEntropy(&secret_seed); + return self; } +/// Inserts entropy to refresh the internal state. +pub fn addEntropy(self: *Self, bytes: []const u8) void { + comptime std.debug.assert(secret_seed_length % rate == 0); + var i: usize = 0; + while (i + rate < bytes.len) : (i += rate) { + self.state.addBytes(bytes[i..][0..rate]); + self.state.permuteR(8); + } + if (i != bytes.len) self.state.addBytes(bytes[i..]); + self.state.permute(); +} + +/// Returns a `std.rand.Random` structure backed by the current RNG. pub fn random(self: *Self) Random { return Random.init(self, fill); } +/// Fills the buffer with random bytes. pub fn fill(self: *Self, buf: []u8) void { var i: usize = 0; while (true) { @@ -40,6 +56,5 @@ pub fn fill(self: *Self, buf: []u8) void { self.state.permuteR(8); i += n; } - self.state.clear(0, rate); - self.state.permuteR(8); + self.state.permuteRatchet(6, rate); } diff --git a/lib/std/rand/ChaCha.zig b/lib/std/rand/ChaCha.zig new file mode 100644 index 0000000000..0992aeb97e --- /dev/null +++ b/lib/std/rand/ChaCha.zig @@ -0,0 +1,97 @@ +//! CSPRNG based on the ChaCha8 stream cipher, with forward security. +//! +//! References: +//! - Fast-key-erasure random-number generators https://blog.cr.yp.to/20170723-random.html + +const std = @import("std"); +const mem = std.mem; +const Random = std.rand.Random; +const Self = @This(); + +const Cipher = std.crypto.stream.chacha.ChaCha8IETF; + +const State = [2 * Cipher.block_length]u8; + +state: State, +offset: usize, + +const nonce = [_]u8{0} ** Cipher.nonce_length; + +pub const secret_seed_length = Cipher.key_length; + +/// The seed must be uniform, secret and `secret_seed_length` bytes long. +pub fn init(secret_seed: [secret_seed_length]u8) Self { + var self = Self{ .state = undefined, .offset = 0 }; + Cipher.stream(&self.state, 0, secret_seed, nonce); + return self; +} + +/// Inserts entropy to refresh the internal state. +pub fn addEntropy(self: *Self, bytes: []const u8) void { + var i: usize = 0; + while (i + Cipher.key_length <= bytes.len) : (i += Cipher.key_length) { + Cipher.xor( + self.state[0..Cipher.key_length], + self.state[0..Cipher.key_length], + 0, + bytes[i..][0..Cipher.key_length].*, + nonce, + ); + } + if (i < bytes.len) { + var k = [_]u8{0} ** Cipher.key_length; + mem.copy(u8, k[0..], bytes[i..]); + Cipher.xor( + self.state[0..Cipher.key_length], + self.state[0..Cipher.key_length], + 0, + k, + nonce, + ); + } + self.refill(); +} + +/// Returns a `std.rand.Random` structure backed by the current RNG. +pub fn random(self: *Self) Random { + return Random.init(self, fill); +} + +// Refills the buffer with random bytes, overwriting the previous key. +fn refill(self: *Self) void { + Cipher.stream(&self.state, 0, self.state[0..Cipher.key_length].*, nonce); + self.offset = 0; +} + +/// Fills the buffer with random bytes. +pub fn fill(self: *Self, buf_: []u8) void { + const bytes = self.state[Cipher.key_length..]; + var buf = buf_; + + const avail = bytes.len - self.offset; + if (avail > 0) { + // Bytes from the current block + const n = @min(avail, buf.len); + mem.copy(u8, buf[0..n], bytes[self.offset..][0..n]); + mem.set(u8, bytes[self.offset..][0..n], 0); + buf = buf[n..]; + self.offset += n; + } + if (buf.len == 0) return; + + self.refill(); + + // Full blocks + while (buf.len >= bytes.len) { + mem.copy(u8, buf[0..bytes.len], bytes); + buf = buf[bytes.len..]; + self.refill(); + } + + // Remaining bytes + if (buf.len > 0) { + mem.copy(u8, buf, bytes[0..buf.len]); + mem.set(u8, bytes[0..buf.len], 0); + self.offset = buf.len; + } +} diff --git a/lib/std/rand/Gimli.zig b/lib/std/rand/Gimli.zig deleted file mode 100644 index 7b7720503e..0000000000 --- a/lib/std/rand/Gimli.zig +++ /dev/null @@ -1,34 +0,0 @@ -//! CSPRNG - -const std = @import("std"); -const Random = std.rand.Random; -const mem = std.mem; -const Gimli = @This(); - -state: std.crypto.core.Gimli, - -pub const secret_seed_length = 32; - -/// The seed must be uniform, secret and `secret_seed_length` bytes long. -pub fn init(secret_seed: [secret_seed_length]u8) Gimli { - var initial_state: [std.crypto.core.Gimli.BLOCKBYTES]u8 = undefined; - mem.copy(u8, initial_state[0..secret_seed_length], &secret_seed); - mem.set(u8, initial_state[secret_seed_length..], 0); - var self = Gimli{ - .state = std.crypto.core.Gimli.init(initial_state), - }; - return self; -} - -pub fn random(self: *Gimli) Random { - return Random.init(self, fill); -} - -pub fn fill(self: *Gimli, buf: []u8) void { - if (buf.len != 0) { - self.state.squeeze(buf); - } else { - self.state.permute(); - } - mem.set(u8, self.state.toSlice()[0..std.crypto.core.Gimli.RATE], 0); -} diff --git a/lib/std/rand/Xoodoo.zig b/lib/std/rand/Xoodoo.zig deleted file mode 100644 index 3e16f2a864..0000000000 --- a/lib/std/rand/Xoodoo.zig +++ /dev/null @@ -1,42 +0,0 @@ -//! CSPRNG - -const std = @import("std"); -const Random = std.rand.Random; -const min = std.math.min; -const mem = std.mem; -const Xoodoo = @This(); - -const State = std.crypto.core.Xoodoo; - -state: State, - -const rate = 16; -pub const secret_seed_length = 32; - -/// The seed must be uniform, secret and `secret_seed_length` bytes long. -pub fn init(secret_seed: [secret_seed_length]u8) Xoodoo { - var initial_state: [State.block_bytes]u8 = undefined; - mem.copy(u8, initial_state[0..secret_seed_length], &secret_seed); - mem.set(u8, initial_state[secret_seed_length..], 0); - var state = State.init(initial_state); - state.permute(); - return Xoodoo{ .state = state }; -} - -pub fn random(self: *Xoodoo) Random { - return Random.init(self, fill); -} - -pub fn fill(self: *Xoodoo, buf: []u8) void { - var i: usize = 0; - while (true) { - const left = buf.len - i; - const n = min(left, rate); - self.state.extract(buf[i..][0..n]); - if (left == 0) break; - self.state.permute(); - i += n; - } - self.state.clear(0, rate); - self.state.permute(); -} diff --git a/lib/std/rand/benchmark.zig b/lib/std/rand/benchmark.zig new file mode 100644 index 0000000000..668b664c27 --- /dev/null +++ b/lib/std/rand/benchmark.zig @@ -0,0 +1,217 @@ +// zig run -O ReleaseFast --zig-lib-dir ../.. benchmark.zig + +const std = @import("std"); +const builtin = @import("builtin"); +const time = std.time; +const Timer = time.Timer; +const rand = std.rand; + +const KiB = 1024; +const MiB = 1024 * KiB; +const GiB = 1024 * MiB; + +const Rng = struct { + ty: type, + name: []const u8, + init_u8s: ?[]const u8 = null, + init_u64: ?u64 = null, +}; + +const prngs = [_]Rng{ + Rng{ + .ty = rand.Isaac64, + .name = "isaac64", + .init_u64 = 0, + }, + Rng{ + .ty = rand.Pcg, + .name = "pcg", + .init_u64 = 0, + }, + Rng{ + .ty = rand.RomuTrio, + .name = "romutrio", + .init_u64 = 0, + }, + Rng{ + .ty = std.rand.Sfc64, + .name = "sfc64", + .init_u64 = 0, + }, + Rng{ + .ty = std.rand.Xoroshiro128, + .name = "xoroshiro128", + .init_u64 = 0, + }, + Rng{ + .ty = std.rand.Xoshiro256, + .name = "xoshiro256", + .init_u64 = 0, + }, +}; + +const csprngs = [_]Rng{ + Rng{ + .ty = rand.Ascon, + .name = "ascon", + .init_u8s = &[_]u8{0} ** 32, + }, + Rng{ + .ty = rand.ChaCha, + .name = "chacha", + .init_u8s = &[_]u8{0} ** 32, + }, +}; + +const Result = struct { + throughput: u64, +}; + +const long_block_size: usize = 8 * 8192; +const short_block_size: usize = 8; + +pub fn benchmark(comptime H: anytype, bytes: usize, comptime block_size: usize) !Result { + var rng = blk: { + if (H.init_u8s) |init| { + break :blk H.ty.init(init[0..].*); + } + if (H.init_u64) |init| { + break :blk H.ty.init(init); + } + break :blk H.ty.init(); + }; + + var block: [block_size]u8 = undefined; + + var offset: usize = 0; + var timer = try Timer.start(); + const start = timer.lap(); + while (offset < bytes) : (offset += block.len) { + rng.fill(block[0..]); + } + const end = timer.read(); + + const elapsed_s = @intToFloat(f64, end - start) / time.ns_per_s; + const throughput = @floatToInt(u64, @intToFloat(f64, bytes) / elapsed_s); + + std.debug.assert(rng.random().int(u64) != 0); + + return Result{ + .throughput = throughput, + }; +} + +fn usage() void { + std.debug.print( + \\throughput_test [options] + \\ + \\Options: + \\ --filter [test-name] + \\ --count [int] + \\ --prngs-only + \\ --csprngs-only + \\ --short-only + \\ --long-only + \\ --help + \\ + , .{}); +} + +fn mode(comptime x: comptime_int) comptime_int { + return if (builtin.mode == .Debug) x / 64 else x; +} + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + + var buffer: [1024]u8 = undefined; + var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]); + const args = try std.process.argsAlloc(fixed.allocator()); + + var filter: ?[]u8 = ""; + var count: usize = mode(128 * MiB); + var bench_prngs = true; + var bench_csprngs = true; + var bench_long = true; + var bench_short = true; + + var i: usize = 1; + while (i < args.len) : (i += 1) { + if (std.mem.eql(u8, args[i], "--mode")) { + try stdout.print("{}\n", .{builtin.mode}); + return; + } else if (std.mem.eql(u8, args[i], "--filter")) { + i += 1; + if (i == args.len) { + usage(); + std.os.exit(1); + } + + filter = args[i]; + } else if (std.mem.eql(u8, args[i], "--count")) { + i += 1; + if (i == args.len) { + usage(); + std.os.exit(1); + } + + const c = try std.fmt.parseUnsigned(usize, args[i], 10); + count = c * MiB; + } else if (std.mem.eql(u8, args[i], "--csprngs-only")) { + bench_prngs = false; + } else if (std.mem.eql(u8, args[i], "--prngs-only")) { + bench_csprngs = false; + } else if (std.mem.eql(u8, args[i], "--short-only")) { + bench_long = false; + } else if (std.mem.eql(u8, args[i], "--long-only")) { + bench_short = false; + } else if (std.mem.eql(u8, args[i], "--help")) { + usage(); + return; + } else { + usage(); + std.os.exit(1); + } + } + + if (bench_prngs) { + if (bench_long) { + inline for (prngs) |R| { + if (filter == null or std.mem.indexOf(u8, R.name, filter.?) != null) { + try stdout.print("{s} (long outputs)\n", .{R.name}); + const result_long = try benchmark(R, count, long_block_size); + try stdout.print(" {:5} MiB/s\n", .{result_long.throughput / (1 * MiB)}); + } + } + } + if (bench_short) { + inline for (prngs) |R| { + if (filter == null or std.mem.indexOf(u8, R.name, filter.?) != null) { + try stdout.print("{s} (short outputs)\n", .{R.name}); + const result_short = try benchmark(R, count, short_block_size); + try stdout.print(" {:5} MiB/s\n", .{result_short.throughput / (1 * MiB)}); + } + } + } + } + if (bench_csprngs) { + if (bench_long) { + inline for (csprngs) |R| { + if (filter == null or std.mem.indexOf(u8, R.name, filter.?) != null) { + try stdout.print("{s} (cryptographic, long outputs)\n", .{R.name}); + const result_long = try benchmark(R, count, long_block_size); + try stdout.print(" {:5} MiB/s\n", .{result_long.throughput / (1 * MiB)}); + } + } + } + if (bench_short) { + inline for (csprngs) |R| { + if (filter == null or std.mem.indexOf(u8, R.name, filter.?) != null) { + try stdout.print("{s} (cryptographic, short outputs)\n", .{R.name}); + const result_short = try benchmark(R, count, short_block_size); + try stdout.print(" {:5} MiB/s\n", .{result_short.throughput / (1 * MiB)}); + } + } + } + } +} From 29e6aedc95766f960d7dbc92c862a82bf40faafd Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 17 Mar 2023 20:07:08 -0400 Subject: [PATCH 047/216] x86_64: implement min and max as commutative binary ops --- src/arch/x86_64/CodeGen.zig | 194 +++++++++++++++++++----------------- src/arch/x86_64/Emit.zig | 28 +++++- src/arch/x86_64/Mir.zig | 24 +++-- src/arch/x86_64/bits.zig | 7 +- 4 files changed, 146 insertions(+), 107 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 5dfce901f7..4e4fe8823f 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -402,8 +402,8 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { _ = try self.addInst(.{ .tag = .setcc, - .ops = .r_c, - .data = .{ .r_c = .{ + .ops = .r_cc, + .data = .{ .r_cc = .{ .r1 = reg, .cc = cc, } }, @@ -413,8 +413,8 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bits.Condition) !void { _ = try self.addInst(.{ .tag = .cmovcc, - .ops = .rr_c, - .data = .{ .rr_c = .{ + .ops = .rr_cc, + .data = .{ .rr_cc = .{ .r1 = reg1, .r2 = reg2, .cc = cc, @@ -422,6 +422,26 @@ fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bi }); } +fn asmCmovccRegisterMemory(self: *Self, reg: Register, m: Memory, cc: bits.Condition) !void { + _ = try self.addInst(.{ + .tag = .cmovcc, + .ops = switch (m) { + .sib => .rm_sib_cc, + .rip => .rm_rip_cc, + else => unreachable, + }, + .data = .{ .rx_cc = .{ + .r1 = reg, + .cc = cc, + .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + }, + } }, + }); +} + fn asmJmpReloc(self: *Self, target: Mir.Inst.Index) !Mir.Inst.Index { return self.addInst(.{ .tag = .jmp_reloc, @@ -793,18 +813,20 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { switch (air_tags[inst]) { // zig fmt: off - .add => try self.airBinOp(inst, .add), - .addwrap => try self.airBinOp(inst, .addwrap), - .sub => try self.airBinOp(inst, .sub), - .subwrap => try self.airBinOp(inst, .subwrap), - .bool_and => try self.airBinOp(inst, .bool_and), - .bool_or => try self.airBinOp(inst, .bool_or), - .bit_and => try self.airBinOp(inst, .bit_and), - .bit_or => try self.airBinOp(inst, .bit_or), - .xor => try self.airBinOp(inst, .xor), + .add, + .addwrap, + .sub, + .subwrap, + .bool_and, + .bool_or, + .bit_and, + .bit_or, + .xor, + .min, + .max, + => |tag| try self.airBinOp(inst, tag), - .ptr_add => try self.airPtrArithmetic(inst, .ptr_add), - .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub), + .ptr_add, .ptr_sub => |tag| try self.airPtrArithmetic(inst, tag), .shr, .shr_exact => try self.airShlShrBinOp(inst), .shl, .shl_exact => try self.airShlShrBinOp(inst), @@ -818,8 +840,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .sub_sat => try self.airSubSat(inst), .mul_sat => try self.airMulSat(inst), .shl_sat => try self.airShlSat(inst), - .min => try self.airMin(inst), - .max => try self.airMax(inst), .slice => try self.airSlice(inst), .sqrt, @@ -1466,61 +1486,6 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } -fn airMin(self: *Self, inst: Air.Inst.Index) !void { - const bin_op = self.air.instructions.items(.data)[inst].bin_op; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } - - const ty = self.air.typeOfIndex(inst); - if (ty.zigTypeTag() != .Int) { - return self.fail("TODO implement min for type {}", .{ty.fmtDebug()}); - } - const signedness = ty.intInfo(self.target.*).signedness; - const result: MCValue = result: { - // TODO improve by checking if any operand can be reused. - // TODO audit register allocation - const lhs = try self.resolveInst(bin_op.lhs); - const lhs_lock: ?RegisterLock = switch (lhs) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); - - const lhs_reg = try self.copyToTmpRegister(ty, lhs); - const lhs_reg_lock = self.register_manager.lockRegAssumeUnused(lhs_reg); - defer self.register_manager.unlockReg(lhs_reg_lock); - - const rhs_mcv = try self.limitImmediateType(bin_op.rhs, i32); - const rhs_lock: ?RegisterLock = switch (rhs_mcv) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); - - try self.genBinOpMir(.cmp, ty, .{ .register = lhs_reg }, rhs_mcv); - - const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, rhs_mcv); - const cc: Condition = switch (signedness) { - .unsigned => .b, - .signed => .l, - }; - try self.asmCmovccRegisterRegister(dst_mcv.register, lhs_reg, cc); - - break :result dst_mcv; - }; - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); -} - -fn airMax(self: *Self, inst: Air.Inst.Index) !void { - const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement max for {}", .{self.target.cpu.arch}); - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); -} - fn airSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; @@ -1545,11 +1510,10 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } - - const result = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); + const result = if (self.liveness.isUnused(inst)) + .dead + else + try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -1557,11 +1521,10 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } - - const result = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); + const result = if (self.liveness.isUnused(inst)) + .dead + else + try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -3486,10 +3449,10 @@ fn genBinOp( const lhs_ty = self.air.typeOf(lhs_air); const rhs_ty = self.air.typeOf(rhs_air); if (lhs_ty.zigTypeTag() == .Vector) { - return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmtDebug()}); + return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)}); } if (lhs_ty.abiSize(self.target.*) > 8) { - return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmtDebug()}); + return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)}); } const is_commutative: bool = switch (tag) { @@ -3500,6 +3463,8 @@ fn genBinOp( .bool_and, .bit_and, .xor, + .min, + .max, => true, else => false, @@ -3520,10 +3485,10 @@ fn genBinOp( var flipped: bool = false; const dst_mcv: MCValue = blk: { if (maybe_inst) |inst| { - if (self.reuseOperand(inst, lhs_air, 0, lhs) and lhs.isRegister()) { + if (lhs.isRegister() and self.reuseOperand(inst, lhs_air, 0, lhs)) { break :blk lhs; } - if (is_commutative and self.reuseOperand(inst, rhs_air, 1, rhs) and rhs.isRegister()) { + if (rhs.isRegister() and is_commutative and self.reuseOperand(inst, rhs_air, 1, rhs)) { flipped = true; break :blk rhs; } @@ -3580,6 +3545,58 @@ fn genBinOp( .xor => try self.genBinOpMir(.xor, lhs_ty, dst_mcv, src_mcv), + .min, + .max, + => { + if (!lhs_ty.isAbiInt() or !rhs_ty.isAbiInt()) { + return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }); + } + + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(rhs_ty, src_mcv) }, + else => src_mcv, + }; + const mat_mcv_lock = switch (mat_src_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_mcv_lock) |lock| self.register_manager.unlockReg(lock); + + try self.genBinOpMir(.cmp, lhs_ty, dst_mcv, mat_src_mcv); + + const int_info = lhs_ty.intInfo(self.target.*); + const cc: Condition = switch (int_info.signedness) { + .unsigned => switch (tag) { + .min => .a, + .max => .b, + else => unreachable, + }, + .signed => switch (tag) { + .min => .g, + .max => .l, + else => unreachable, + }, + }; + + const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); + switch (dst_mcv) { + .register => |dst_reg| switch (mat_src_mcv) { + .register => |src_reg| try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, abi_size), + registerAlias(src_reg, abi_size), + cc, + ), + .stack_offset => |off| try self.asmCmovccRegisterMemory( + registerAlias(dst_reg, abi_size), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), + cc, + ), + else => unreachable, + }, + else => unreachable, + } + }, + else => unreachable, } return dst_mcv; @@ -3660,13 +3677,10 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu Immediate.s(small), ); } else { - const tmp_reg = try self.register_manager.allocReg(null, gp); - const tmp_alias = registerAlias(tmp_reg, abi_size); - try self.asmRegisterImmediate(.mov, tmp_alias, Immediate.u(imm)); try self.asmRegisterRegister( mir_tag, registerAlias(dst_reg, abi_size), - tmp_alias, + registerAlias(try self.copyToTmpRegister(dst_ty, src_mcv), abi_size), ); } }, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 32699d35cb..4e2c1db9af 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -374,23 +374,41 @@ fn mnemonicFromConditionCode(comptime basename: []const u8, cc: bits.Condition) fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const ops = emit.mir.instructions.items(.ops)[inst]; switch (ops) { - .rr_c => { - const data = emit.mir.instructions.items(.data)[inst].rr_c; + .rr_cc => { + const data = emit.mir.instructions.items(.data)[inst].rr_cc; const mnemonic = mnemonicFromConditionCode("cmov", data.cc); return emit.encode(mnemonic, .{ .op1 = .{ .reg = data.r1 }, .op2 = .{ .reg = data.r2 }, }); }, - else => unreachable, // TODO + .rm_sib_cc => { + const data = emit.mir.instructions.items(.data)[inst].rx_cc; + const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data; + const mnemonic = mnemonicFromConditionCode("cmov", data.cc); + return emit.encode(mnemonic, .{ + .op1 = .{ .reg = data.r1 }, + .op2 = .{ .mem = Mir.MemorySib.decode(extra) }, + }); + }, + .rm_rip_cc => { + const data = emit.mir.instructions.items(.data)[inst].rx_cc; + const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data; + const mnemonic = mnemonicFromConditionCode("cmov", data.cc); + return emit.encode(mnemonic, .{ + .op1 = .{ .reg = data.r1 }, + .op2 = .{ .mem = Mir.MemoryRip.decode(extra) }, + }); + }, + else => unreachable, } } fn mirSetcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const ops = emit.mir.instructions.items(.ops)[inst]; switch (ops) { - .r_c => { - const data = emit.mir.instructions.items(.data)[inst].r_c; + .r_cc => { + const data = emit.mir.instructions.items(.data)[inst].r_cc; const mnemonic = mnemonicFromConditionCode("set", data.cc); return emit.encode(mnemonic, .{ .op1 = .{ .reg = data.r1 }, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 3951108e3a..ed0606e87a 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -186,10 +186,10 @@ pub const Inst = struct { rri_u, /// Register with condition code (CC). /// Uses `r_c` payload. - r_c, + r_cc, /// Register, register with condition code (CC). /// Uses `rr_c` payload. - rr_c, + rr_cc, /// Register, immediate (sign-extended) operands. /// Uses `ri` payload. ri_s, @@ -214,6 +214,12 @@ pub const Inst = struct { /// Register, memory (RIP) operands. /// Uses `rx` payload. rm_rip, + /// Register, memory (SIB) operands with condition code (CC). + /// Uses `rx_cc` payload. + rm_sib_cc, + /// Register, memory (RIP) operands with condition code (CC). + /// Uses `rx_cc` payload. + rm_rip_cc, /// Single memory (SIB) operand. /// Uses `payload` with extra data of type `MemorySib`. m_sib, @@ -250,10 +256,6 @@ pub const Inst = struct { /// References another Mir instruction directly with condition code (CC). /// Uses `inst_cc` payload. inst_cc, - /// Uses `payload` payload with data of type `MemoryConditionCode`. - m_cc, - /// Uses `rx` payload with extra data of type `MemoryConditionCode`. - rm_cc, /// Uses `reloc` payload. reloc, /// Linker relocation - GOT indirection. @@ -296,12 +298,12 @@ pub const Inst = struct { imm: u32, }, /// Register with condition code (CC). - r_c: struct { + r_cc: struct { r1: Register, cc: bits.Condition, }, /// Register, register with condition code (CC). - rr_c: struct { + rr_cc: struct { r1: Register, r2: Register, cc: bits.Condition, @@ -316,6 +318,12 @@ pub const Inst = struct { r1: Register, payload: u32, }, + /// Register with condition code (CC), followed by custom payload found in extra. + rx_cc: struct { + r1: Register, + cc: bits.Condition, + payload: u32, + }, /// Custom payload followed by an immediate. xi: struct { payload: u32, diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index 043e589af4..72d7b159cf 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -97,8 +97,7 @@ pub const Condition = enum(u5) { }; } - /// Returns the condition which is true iff the given condition is - /// false (if such a condition exists) + /// Returns the condition which is true iff the given condition is false pub fn negate(cond: Condition) Condition { return switch (cond) { .a => .na, @@ -127,8 +126,8 @@ pub const Condition = enum(u5) { .nz => .z, .o => .no, .p => .np, - .pe => unreachable, - .po => unreachable, + .pe => .po, + .po => .pe, .s => .ns, .z => .nz, }; From 30e1daa7463c766e23f57e6a89e4e0ffd4918be5 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 17 Mar 2023 22:07:32 -0400 Subject: [PATCH 048/216] x86_64: implement basic float ops --- src/arch/x86_64/CodeGen.zig | 174 ++++++++++++++++-------------- src/arch/x86_64/Emit.zig | 10 ++ src/arch/x86_64/Encoding.zig | 8 ++ src/arch/x86_64/Mir.zig | 24 ++++- src/arch/x86_64/encodings.zig | 20 ++++ test/behavior/maximum_minimum.zig | 2 - 6 files changed, 155 insertions(+), 83 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 4e4fe8823f..d18f99923e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1530,21 +1530,23 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const result = result: { + if (self.liveness.isUnused(inst)) break :result .dead; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } + const tag = self.air.instructions.items(.tag)[inst]; + const ty = self.air.typeOfIndex(inst); - const tag = self.air.instructions.items(.tag)[inst]; - const ty = self.air.typeOfIndex(inst); + if (ty.zigTypeTag() == .Float) { + break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); + } - try self.spillRegisters(2, .{ .rax, .rdx }); + try self.spillRegisters(2, .{ .rax, .rdx }); - const lhs = try self.resolveInst(bin_op.lhs); - const rhs = try self.resolveInst(bin_op.rhs); - - const result = try self.genMulDivBinOp(tag, inst, ty, lhs, rhs); + const lhs = try self.resolveInst(bin_op.lhs); + const rhs = try self.resolveInst(bin_op.rhs); + break :result try self.genMulDivBinOp(tag, inst, ty, lhs, rhs); + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -3288,10 +3290,10 @@ fn genMulDivBinOp( rhs: MCValue, ) !MCValue { if (ty.zigTypeTag() == .Vector or ty.zigTypeTag() == .Float) { - return self.fail("TODO implement genBinOp for {}", .{ty.fmtDebug()}); + return self.fail("TODO implement genMulDivBinOp for {}", .{ty.fmtDebug()}); } if (ty.abiSize(self.target.*) > 8) { - return self.fail("TODO implement genBinOp for {}", .{ty.fmtDebug()}); + return self.fail("TODO implement genMulDivBinOp for {}", .{ty.fmtDebug()}); } if (tag == .div_float) { return self.fail("TODO implement genMulDivBinOp for div_float", .{}); @@ -3516,11 +3518,31 @@ fn genBinOp( switch (tag) { .add, .addwrap, - => try self.genBinOpMir(.add, lhs_ty, dst_mcv, src_mcv), + => try self.genBinOpMir(switch (lhs_ty.tag()) { + else => .add, + .f32 => .addss, + .f64 => .addsd, + }, lhs_ty, dst_mcv, src_mcv), .sub, .subwrap, - => try self.genBinOpMir(.sub, lhs_ty, dst_mcv, src_mcv), + => try self.genBinOpMir(switch (lhs_ty.tag()) { + else => .sub, + .f32 => .subss, + .f64 => .subsd, + }, lhs_ty, dst_mcv, src_mcv), + + .mul => try self.genBinOpMir(switch (lhs_ty.tag()) { + .f32 => .mulss, + .f64 => .mulsd, + else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), + }, lhs_ty, dst_mcv, src_mcv), + + .div_float => try self.genBinOpMir(switch (lhs_ty.tag()) { + .f32 => .divss, + .f64 => .divsd, + else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), + }, lhs_ty, dst_mcv, src_mcv), .ptr_add, .ptr_sub, @@ -3547,54 +3569,66 @@ fn genBinOp( .min, .max, - => { - if (!lhs_ty.isAbiInt() or !rhs_ty.isAbiInt()) { - return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }); - } + => switch (lhs_ty.zigTypeTag()) { + .Int => { + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(rhs_ty, src_mcv) }, + else => src_mcv, + }; + const mat_mcv_lock = switch (mat_src_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_mcv_lock) |lock| self.register_manager.unlockReg(lock); - const mat_src_mcv = switch (src_mcv) { - .immediate => MCValue{ .register = try self.copyToTmpRegister(rhs_ty, src_mcv) }, - else => src_mcv, - }; - const mat_mcv_lock = switch (mat_src_mcv) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (mat_mcv_lock) |lock| self.register_manager.unlockReg(lock); + try self.genBinOpMir(.cmp, lhs_ty, dst_mcv, mat_src_mcv); - try self.genBinOpMir(.cmp, lhs_ty, dst_mcv, mat_src_mcv); + const int_info = lhs_ty.intInfo(self.target.*); + const cc: Condition = switch (int_info.signedness) { + .unsigned => switch (tag) { + .min => .a, + .max => .b, + else => unreachable, + }, + .signed => switch (tag) { + .min => .g, + .max => .l, + else => unreachable, + }, + }; - const int_info = lhs_ty.intInfo(self.target.*); - const cc: Condition = switch (int_info.signedness) { - .unsigned => switch (tag) { - .min => .a, - .max => .b, + const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); + switch (dst_mcv) { + .register => |dst_reg| switch (mat_src_mcv) { + .register => |src_reg| try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, abi_size), + registerAlias(src_reg, abi_size), + cc, + ), + .stack_offset => |off| try self.asmCmovccRegisterMemory( + registerAlias(dst_reg, abi_size), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), + cc, + ), + else => unreachable, + }, + else => unreachable, + } + }, + .Float => try self.genBinOpMir(switch (lhs_ty.tag()) { + .f32 => switch (tag) { + .min => .minss, + .max => .maxss, else => unreachable, }, - .signed => switch (tag) { - .min => .g, - .max => .l, + .f64 => switch (tag) { + .min => .minsd, + .max => .maxsd, else => unreachable, }, - }; - - const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); - switch (dst_mcv) { - .register => |dst_reg| switch (mat_src_mcv) { - .register => |src_reg| try self.asmCmovccRegisterRegister( - registerAlias(dst_reg, abi_size), - registerAlias(src_reg, abi_size), - cc, - ), - .stack_offset => |off| try self.asmCmovccRegisterMemory( - registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), - cc, - ), - else => unreachable, - }, - else => unreachable, - } + else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), + }, lhs_ty, dst_mcv, src_mcv), + else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), }, else => unreachable, @@ -3626,29 +3660,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu .register => |src_reg| switch (dst_ty.zigTypeTag()) { .Float => { if (intrinsicsAllowed(self.target.*, dst_ty)) { - const actual_tag: Mir.Inst.Tag = switch (dst_ty.tag()) { - .f32 => switch (mir_tag) { - .add => .addss, - .cmp => .ucomiss, - else => return self.fail( - "TODO genBinOpMir for f32 register-register with MIR tag {}", - .{mir_tag}, - ), - }, - .f64 => switch (mir_tag) { - .add => .addsd, - .cmp => .ucomisd, - else => return self.fail( - "TODO genBinOpMir for f64 register-register with MIR tag {}", - .{mir_tag}, - ), - }, - else => return self.fail( - "TODO genBinOpMir for float register-register and type {}", - .{dst_ty.fmtDebug()}, - ), - }; - return self.asmRegisterRegister(actual_tag, dst_reg.to128(), src_reg.to128()); + return self.asmRegisterRegister(mir_tag, dst_reg.to128(), src_reg.to128()); } return self.fail("TODO genBinOpMir for float register-register and no intrinsics", .{}); @@ -4307,7 +4319,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { }; defer if (src_lock) |lock| self.register_manager.unlockReg(lock); - try self.genBinOpMir(.cmp, ty, dst_mcv, src_mcv); + try self.genBinOpMir(switch (ty.tag()) { + else => .cmp, + .f32 => .ucomiss, + .f64 => .ucomisd, + }, ty, dst_mcv, src_mcv); break :result switch (signedness) { .signed => MCValue{ .eflags = Condition.fromCompareOperatorSigned(op) }, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 4e2c1db9af..e9d09a4ef6 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -110,11 +110,21 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .addss, .cmpss, + .divss, + .maxss, + .minss, .movss, + .mulss, + .subss, .ucomiss, .addsd, .cmpsd, + .divsd, + .maxsd, + .minsd, .movsd, + .mulsd, + .subsd, .ucomisd, => try emit.mirEncodeGeneric(tag, inst), diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index a51f954aed..d0ede962cb 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -342,12 +342,20 @@ pub const Mnemonic = enum { // SSE addss, cmpss, + divss, + maxss, minss, movss, + mulss, + subss, ucomiss, // SSE2 addsd, cmpsd, + divsd, + maxsd, minsd, movq, movsd, + mulsd, + subsd, ucomisd, // zig fmt: on }; diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index ed0606e87a..6f3bf6c745 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -109,20 +109,40 @@ pub const Inst = struct { /// Logical exclusive-or xor, - /// Add single precision floating point + /// Add single precision floating point values addss, /// Compare scalar single-precision floating-point values cmpss, + /// Divide scalar single-precision floating-point values + divss, + /// Return maximum single-precision floating-point value + maxss, + /// Return minimum single-precision floating-point value + minss, /// Move scalar single-precision floating-point value movss, + /// Multiply scalar single-precision floating-point values + mulss, + /// Subtract scalar single-precision floating-point values + subss, /// Unordered compare scalar single-precision floating-point values ucomiss, - /// Add double precision floating point + /// Add double precision floating point values addsd, /// Compare scalar double-precision floating-point values cmpsd, + /// Divide scalar double-precision floating-point values + divsd, + /// Return maximum double-precision floating-point value + maxsd, + /// Return minimum double-precision floating-point value + minsd, /// Move scalar double-precision floating-point value movsd, + /// Multiply scalar double-precision floating-point values + mulsd, + /// Subtract scalar double-precision floating-point values + subsd, /// Unordered compare scalar double-precision floating-point values ucomisd, diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index b008eb9f3e..dc7b51521d 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -599,9 +599,19 @@ pub const table = &[_]Entry{ .{ .cmpss, .rmi, .xmm, .xmm_m32, .imm8, .none, 3, 0xf3, 0x0f, 0xc2, 0, .sse }, + .{ .divss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5e, 0, .sse }, + + .{ .maxss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5f, 0, .sse }, + + .{ .minss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5d, 0, .sse }, + .{ .movss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x10, 0, .sse }, .{ .movss, .mr, .xmm_m32, .xmm, .none, .none, 3, 0xf3, 0x0f, 0x11, 0, .sse }, + .{ .mulss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x59, 0, .sse }, + + .{ .subss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5c, 0, .sse }, + .{ .ucomiss, .rm, .xmm, .xmm_m32, .none, .none, 2, 0x0f, 0x2e, 0x00, 0, .sse }, // SSE2 @@ -609,9 +619,19 @@ pub const table = &[_]Entry{ .{ .cmpsd, .rmi, .xmm, .xmm_m64, .imm8, .none, 3, 0xf2, 0x0f, 0xc2, 0, .sse2 }, + .{ .divsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x5e, 0, .sse2 }, + + .{ .maxsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x5f, 0, .sse2 }, + + .{ .minsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x5d, 0, .sse2 }, + .{ .movq, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf3, 0x0f, 0x7e, 0, .sse2 }, .{ .movq, .mr, .xmm_m64, .xmm, .none, .none, 3, 0x66, 0x0f, 0xd6, 0, .sse2 }, + .{ .mulsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x59, 0, .sse2 }, + + .{ .subsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x5c, 0, .sse2 }, + .{ .movsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x10, 0, .sse2 }, .{ .movsd, .mr, .xmm_m64, .xmm, .none, .none, 3, 0xf2, 0x0f, 0x11, 0, .sse2 }, diff --git a/test/behavior/maximum_minimum.zig b/test/behavior/maximum_minimum.zig index 34a7d0976a..d538e2db65 100644 --- a/test/behavior/maximum_minimum.zig +++ b/test/behavior/maximum_minimum.zig @@ -5,7 +5,6 @@ const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; test "@max" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -52,7 +51,6 @@ test "@max on vectors" { } test "@min" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From b6eebb709fdb8aff62105f60b275527c306b97b8 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 18 Mar 2023 00:02:07 -0400 Subject: [PATCH 049/216] x86_64: fix OBO These loops were skipping over the top stack entry, and there's already a function that does this correctly. --- src/arch/x86_64/CodeGen.zig | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index d18f99923e..de9031f48c 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5006,14 +5006,8 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran if (target_value == .dead) continue; // The instruction is only overridden in the else branch. - var i: usize = self.branch_stack.items.len - 1; - while (true) { - i -= 1; // If this overflows, the question is: why wasn't the instruction marked dead? - if (self.branch_stack.items[i].inst_table.get(target_key)) |mcv| { - assert(mcv != .dead); - break :blk mcv; - } - } + // If integer overflows occurs, the question is: why wasn't the instruction marked dead? + break :blk self.getResolvedInstValue(target_key).?; }; log.debug("consolidating target_entry {d} {}=>{}", .{ target_key, target_value, canon_mcv }); // TODO make sure the destination stack offset / register does not already have something @@ -5030,16 +5024,7 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran log.debug("canon_value = {}", .{canon_value}); if (canon_value == .dead) continue; - const parent_mcv = blk: { - var i: usize = self.branch_stack.items.len - 1; - while (true) { - i -= 1; - if (self.branch_stack.items[i].inst_table.get(canon_key)) |mcv| { - assert(mcv != .dead); - break :blk mcv; - } - } - }; + const parent_mcv = self.getResolvedInstValue(canon_key).?; log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value }); // TODO make sure the destination stack offset / register does not already have something // going on there. From c865c8fb2a910e73e38192a8bd484935bae8f6fc Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 18 Mar 2023 01:37:13 -0400 Subject: [PATCH 050/216] x86_64: implement float division intrinsics --- src/arch/x86_64/CodeGen.zig | 27 +- src/arch/x86_64/Emit.zig | 2 + src/arch/x86_64/Encoding.zig | 23 +- src/arch/x86_64/Mir.zig | 4 + src/arch/x86_64/encodings.zig | 1134 +++++++++++++++++---------------- 5 files changed, 614 insertions(+), 576 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index de9031f48c..04e8a7ebe3 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3538,12 +3538,37 @@ fn genBinOp( else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), }, lhs_ty, dst_mcv, src_mcv), - .div_float => try self.genBinOpMir(switch (lhs_ty.tag()) { + .div_float, + .div_exact, + => try self.genBinOpMir(switch (lhs_ty.tag()) { .f32 => .divss, .f64 => .divsd, else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), }, lhs_ty, dst_mcv, src_mcv), + .div_trunc, + .div_floor, + => { + try self.genBinOpMir(switch (lhs_ty.tag()) { + .f32 => .divss, + .f64 => .divsd, + else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), + }, lhs_ty, dst_mcv, src_mcv); + if (Target.x86.featureSetHas(self.target.cpu.features, .sse4_1)) { + const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); + const dst_alias = registerAlias(dst_mcv.register, abi_size); + try self.asmRegisterRegisterImmediate(switch (lhs_ty.tag()) { + .f32 => .roundss, + .f64 => .roundsd, + else => unreachable, + }, dst_alias, dst_alias, Immediate.u(switch (tag) { + .div_trunc => 0b1_0_11, + .div_floor => 0b1_0_01, + else => unreachable, + })); + } else return self.fail("TODO implement round without sse4_1", .{}); + }, + .ptr_add, .ptr_sub, => { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index e9d09a4ef6..95c5c41170 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -115,6 +115,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .minss, .movss, .mulss, + .roundss, .subss, .ucomiss, .addsd, @@ -124,6 +125,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .minsd, .movsd, .mulsd, + .roundsd, .subsd, .ucomisd, => try emit.mirEncodeGeneric(tag, inst), diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index d0ede962cb..275c001bd7 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -19,8 +19,8 @@ op1: Op, op2: Op, op3: Op, op4: Op, -opc_len: u2, -opc: [3]u8, +opc_len: u3, +opc: [7]u8, modrm_ext: u3, mode: Mode, @@ -69,18 +69,19 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct { var candidates: [10]Encoding = undefined; var count: usize = 0; for (table) |entry| { - const enc = Encoding{ + var enc = Encoding{ .mnemonic = entry[0], .op_en = entry[1], .op1 = entry[2], .op2 = entry[3], .op3 = entry[4], .op4 = entry[5], - .opc_len = entry[6], - .opc = .{ entry[7], entry[8], entry[9] }, - .modrm_ext = entry[10], - .mode = entry[11], + .opc_len = @intCast(u3, entry[6].len), + .opc = undefined, + .modrm_ext = entry[7], + .mode = entry[8], }; + std.mem.copy(u8, &enc.opc, entry[6]); if (enc.mnemonic == mnemonic and input_op1.isSubset(enc.op1, enc.mode) and input_op2.isSubset(enc.op2, enc.mode) and @@ -184,7 +185,7 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct { if (match) { if (prefixes.rex.w) { switch (enc.mode) { - .fpu, .sse, .sse2, .none => {}, + .fpu, .sse, .sse2, .sse4_1, .none => {}, .long, .rex => return enc, } } else if (prefixes.rex.present and !prefixes.rex.isSet()) { @@ -357,6 +358,9 @@ pub const Mnemonic = enum { mulsd, subsd, ucomisd, + // SSE4.1 + roundss, + roundsd, // zig fmt: on }; @@ -550,7 +554,7 @@ pub const Op = enum { else => { if (op.isRegister() and target.isRegister()) { switch (mode) { - .sse, .sse2 => return op.isFloatingPointRegister() and target.isFloatingPointRegister(), + .sse, .sse2, .sse4_1 => return op.isFloatingPointRegister() and target.isFloatingPointRegister(), else => switch (target) { .cl, .al, .ax, .eax, .rax => return op == target, else => return op.bitSize() == target.bitSize(), @@ -592,4 +596,5 @@ pub const Mode = enum { long, sse, sse2, + sse4_1, }; diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 6f3bf6c745..ed10bed9b6 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -123,6 +123,8 @@ pub const Inst = struct { movss, /// Multiply scalar single-precision floating-point values mulss, + /// Round scalar single-precision floating-point values + roundss, /// Subtract scalar single-precision floating-point values subss, /// Unordered compare scalar single-precision floating-point values @@ -141,6 +143,8 @@ pub const Inst = struct { movsd, /// Multiply scalar double-precision floating-point values mulsd, + /// Round scalar double-precision floating-point values + roundsd, /// Subtract scalar double-precision floating-point values subsd, /// Unordered compare scalar double-precision floating-point values diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index dc7b51521d..57b330b9ce 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -4,638 +4,640 @@ const OpEn = Encoding.OpEn; const Op = Encoding.Op; const Mode = Encoding.Mode; -const opcode_len = u2; const modrm_ext = u3; -const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, opcode_len, u8, u8, u8, modrm_ext, Mode }; +const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, []const u8, modrm_ext, Mode }; // TODO move this into a .zon file when Zig is capable of importing .zon files // zig fmt: off pub const table = &[_]Entry{ // General-purpose - .{ .adc, .zi, .al, .imm8, .none, .none, 1, 0x14, 0x00, 0x00, 0, .none }, - .{ .adc, .zi, .ax, .imm16, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none }, - .{ .adc, .zi, .eax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none }, - .{ .adc, .zi, .rax, .imm32s, .none, .none, 1, 0x15, 0x00, 0x00, 0, .long }, - .{ .adc, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 2, .none }, - .{ .adc, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 2, .rex }, - .{ .adc, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none }, - .{ .adc, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none }, - .{ .adc, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 2, .long }, - .{ .adc, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none }, - .{ .adc, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none }, - .{ .adc, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .long }, - .{ .adc, .mr, .rm8, .r8, .none, .none, 1, 0x10, 0x00, 0x00, 0, .none }, - .{ .adc, .mr, .rm8, .r8, .none, .none, 1, 0x10, 0x00, 0x00, 0, .rex }, - .{ .adc, .mr, .rm16, .r16, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none }, - .{ .adc, .mr, .rm32, .r32, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none }, - .{ .adc, .mr, .rm64, .r64, .none, .none, 1, 0x11, 0x00, 0x00, 0, .long }, - .{ .adc, .rm, .r8, .rm8, .none, .none, 1, 0x12, 0x00, 0x00, 0, .none }, - .{ .adc, .rm, .r8, .rm8, .none, .none, 1, 0x12, 0x00, 0x00, 0, .rex }, - .{ .adc, .rm, .r16, .rm16, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none }, - .{ .adc, .rm, .r32, .rm32, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none }, - .{ .adc, .rm, .r64, .rm64, .none, .none, 1, 0x13, 0x00, 0x00, 0, .long }, + .{ .adc, .zi, .al, .imm8, .none, .none, &.{ 0x14 }, 0, .none }, + .{ .adc, .zi, .ax, .imm16, .none, .none, &.{ 0x15 }, 0, .none }, + .{ .adc, .zi, .eax, .imm32, .none, .none, &.{ 0x15 }, 0, .none }, + .{ .adc, .zi, .rax, .imm32s, .none, .none, &.{ 0x15 }, 0, .long }, + .{ .adc, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 2, .none }, + .{ .adc, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 2, .rex }, + .{ .adc, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 2, .none }, + .{ .adc, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 2, .none }, + .{ .adc, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 2, .long }, + .{ .adc, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 2, .none }, + .{ .adc, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 2, .none }, + .{ .adc, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 2, .long }, + .{ .adc, .mr, .rm8, .r8, .none, .none, &.{ 0x10 }, 0, .none }, + .{ .adc, .mr, .rm8, .r8, .none, .none, &.{ 0x10 }, 0, .rex }, + .{ .adc, .mr, .rm16, .r16, .none, .none, &.{ 0x11 }, 0, .none }, + .{ .adc, .mr, .rm32, .r32, .none, .none, &.{ 0x11 }, 0, .none }, + .{ .adc, .mr, .rm64, .r64, .none, .none, &.{ 0x11 }, 0, .long }, + .{ .adc, .rm, .r8, .rm8, .none, .none, &.{ 0x12 }, 0, .none }, + .{ .adc, .rm, .r8, .rm8, .none, .none, &.{ 0x12 }, 0, .rex }, + .{ .adc, .rm, .r16, .rm16, .none, .none, &.{ 0x13 }, 0, .none }, + .{ .adc, .rm, .r32, .rm32, .none, .none, &.{ 0x13 }, 0, .none }, + .{ .adc, .rm, .r64, .rm64, .none, .none, &.{ 0x13 }, 0, .long }, - .{ .add, .zi, .al, .imm8, .none, .none, 1, 0x04, 0x00, 0x00, 0, .none }, - .{ .add, .zi, .ax, .imm16, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none }, - .{ .add, .zi, .eax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none }, - .{ .add, .zi, .rax, .imm32s, .none, .none, 1, 0x05, 0x00, 0x00, 0, .long }, - .{ .add, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 0, .none }, - .{ .add, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 0, .rex }, - .{ .add, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none }, - .{ .add, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none }, - .{ .add, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 0, .long }, - .{ .add, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none }, - .{ .add, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none }, - .{ .add, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .long }, - .{ .add, .mr, .rm8, .r8, .none, .none, 1, 0x00, 0x00, 0x00, 0, .none }, - .{ .add, .mr, .rm8, .r8, .none, .none, 1, 0x00, 0x00, 0x00, 0, .rex }, - .{ .add, .mr, .rm16, .r16, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none }, - .{ .add, .mr, .rm32, .r32, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none }, - .{ .add, .mr, .rm64, .r64, .none, .none, 1, 0x01, 0x00, 0x00, 0, .long }, - .{ .add, .rm, .r8, .rm8, .none, .none, 1, 0x02, 0x00, 0x00, 0, .none }, - .{ .add, .rm, .r8, .rm8, .none, .none, 1, 0x02, 0x00, 0x00, 0, .rex }, - .{ .add, .rm, .r16, .rm16, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none }, - .{ .add, .rm, .r32, .rm32, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none }, - .{ .add, .rm, .r64, .rm64, .none, .none, 1, 0x03, 0x00, 0x00, 0, .long }, + .{ .add, .zi, .al, .imm8, .none, .none, &.{ 0x04 }, 0, .none }, + .{ .add, .zi, .ax, .imm16, .none, .none, &.{ 0x05 }, 0, .none }, + .{ .add, .zi, .eax, .imm32, .none, .none, &.{ 0x05 }, 0, .none }, + .{ .add, .zi, .rax, .imm32s, .none, .none, &.{ 0x05 }, 0, .long }, + .{ .add, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 0, .none }, + .{ .add, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 0, .rex }, + .{ .add, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 0, .none }, + .{ .add, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 0, .none }, + .{ .add, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 0, .long }, + .{ .add, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 0, .none }, + .{ .add, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 0, .none }, + .{ .add, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 0, .long }, + .{ .add, .mr, .rm8, .r8, .none, .none, &.{ 0x00 }, 0, .none }, + .{ .add, .mr, .rm8, .r8, .none, .none, &.{ 0x00 }, 0, .rex }, + .{ .add, .mr, .rm16, .r16, .none, .none, &.{ 0x01 }, 0, .none }, + .{ .add, .mr, .rm32, .r32, .none, .none, &.{ 0x01 }, 0, .none }, + .{ .add, .mr, .rm64, .r64, .none, .none, &.{ 0x01 }, 0, .long }, + .{ .add, .rm, .r8, .rm8, .none, .none, &.{ 0x02 }, 0, .none }, + .{ .add, .rm, .r8, .rm8, .none, .none, &.{ 0x02 }, 0, .rex }, + .{ .add, .rm, .r16, .rm16, .none, .none, &.{ 0x03 }, 0, .none }, + .{ .add, .rm, .r32, .rm32, .none, .none, &.{ 0x03 }, 0, .none }, + .{ .add, .rm, .r64, .rm64, .none, .none, &.{ 0x03 }, 0, .long }, - .{ .@"and", .zi, .al, .imm8, .none, .none, 1, 0x24, 0x00, 0x00, 0, .none }, - .{ .@"and", .zi, .ax, .imm16, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none }, - .{ .@"and", .zi, .eax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none }, - .{ .@"and", .zi, .rax, .imm32s, .none, .none, 1, 0x25, 0x00, 0x00, 0, .long }, - .{ .@"and", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 4, .none }, - .{ .@"and", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 4, .rex }, - .{ .@"and", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none }, - .{ .@"and", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none }, - .{ .@"and", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 4, .long }, - .{ .@"and", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none }, - .{ .@"and", .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none }, - .{ .@"and", .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .long }, - .{ .@"and", .mr, .rm8, .r8, .none, .none, 1, 0x20, 0x00, 0x00, 0, .none }, - .{ .@"and", .mr, .rm8, .r8, .none, .none, 1, 0x20, 0x00, 0x00, 0, .rex }, - .{ .@"and", .mr, .rm16, .r16, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none }, - .{ .@"and", .mr, .rm32, .r32, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none }, - .{ .@"and", .mr, .rm64, .r64, .none, .none, 1, 0x21, 0x00, 0x00, 0, .long }, - .{ .@"and", .rm, .r8, .rm8, .none, .none, 1, 0x22, 0x00, 0x00, 0, .none }, - .{ .@"and", .rm, .r8, .rm8, .none, .none, 1, 0x22, 0x00, 0x00, 0, .rex }, - .{ .@"and", .rm, .r16, .rm16, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none }, - .{ .@"and", .rm, .r32, .rm32, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none }, - .{ .@"and", .rm, .r64, .rm64, .none, .none, 1, 0x23, 0x00, 0x00, 0, .long }, + .{ .@"and", .zi, .al, .imm8, .none, .none, &.{ 0x24 }, 0, .none }, + .{ .@"and", .zi, .ax, .imm16, .none, .none, &.{ 0x25 }, 0, .none }, + .{ .@"and", .zi, .eax, .imm32, .none, .none, &.{ 0x25 }, 0, .none }, + .{ .@"and", .zi, .rax, .imm32s, .none, .none, &.{ 0x25 }, 0, .long }, + .{ .@"and", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 4, .none }, + .{ .@"and", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 4, .rex }, + .{ .@"and", .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 4, .none }, + .{ .@"and", .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 4, .none }, + .{ .@"and", .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 4, .long }, + .{ .@"and", .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 4, .none }, + .{ .@"and", .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 4, .none }, + .{ .@"and", .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 4, .long }, + .{ .@"and", .mr, .rm8, .r8, .none, .none, &.{ 0x20 }, 0, .none }, + .{ .@"and", .mr, .rm8, .r8, .none, .none, &.{ 0x20 }, 0, .rex }, + .{ .@"and", .mr, .rm16, .r16, .none, .none, &.{ 0x21 }, 0, .none }, + .{ .@"and", .mr, .rm32, .r32, .none, .none, &.{ 0x21 }, 0, .none }, + .{ .@"and", .mr, .rm64, .r64, .none, .none, &.{ 0x21 }, 0, .long }, + .{ .@"and", .rm, .r8, .rm8, .none, .none, &.{ 0x22 }, 0, .none }, + .{ .@"and", .rm, .r8, .rm8, .none, .none, &.{ 0x22 }, 0, .rex }, + .{ .@"and", .rm, .r16, .rm16, .none, .none, &.{ 0x23 }, 0, .none }, + .{ .@"and", .rm, .r32, .rm32, .none, .none, &.{ 0x23 }, 0, .none }, + .{ .@"and", .rm, .r64, .rm64, .none, .none, &.{ 0x23 }, 0, .long }, // This is M encoding according to Intel, but D makes more sense here. - .{ .call, .d, .rel32, .none, .none, .none, 1, 0xe8, 0x00, 0x00, 0, .none }, - .{ .call, .m, .rm64, .none, .none, .none, 1, 0xff, 0x00, 0x00, 2, .none }, + .{ .call, .d, .rel32, .none, .none, .none, &.{ 0xe8 }, 0, .none }, + .{ .call, .m, .rm64, .none, .none, .none, &.{ 0xff }, 2, .none }, - .{ .cbw, .np, .o16, .none, .none, .none, 1, 0x98, 0x00, 0x00, 0, .none }, - .{ .cwde, .np, .o32, .none, .none, .none, 1, 0x98, 0x00, 0x00, 0, .none }, - .{ .cdqe, .np, .o64, .none, .none, .none, 1, 0x98, 0x00, 0x00, 0, .long }, + .{ .cbw, .np, .o16, .none, .none, .none, &.{ 0x98 }, 0, .none }, + .{ .cwde, .np, .o32, .none, .none, .none, &.{ 0x98 }, 0, .none }, + .{ .cdqe, .np, .o64, .none, .none, .none, &.{ 0x98 }, 0, .long }, - .{ .cwd, .np, .o16, .none, .none, .none, 1, 0x99, 0x00, 0x00, 0, .none }, - .{ .cdq, .np, .o32, .none, .none, .none, 1, 0x99, 0x00, 0x00, 0, .none }, - .{ .cqo, .np, .o64, .none, .none, .none, 1, 0x99, 0x00, 0x00, 0, .long }, + .{ .cwd, .np, .o16, .none, .none, .none, &.{ 0x99 }, 0, .none }, + .{ .cdq, .np, .o32, .none, .none, .none, &.{ 0x99 }, 0, .none }, + .{ .cqo, .np, .o64, .none, .none, .none, &.{ 0x99 }, 0, .long }, - .{ .cmova, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none }, - .{ .cmova, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none }, - .{ .cmova, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .long }, - .{ .cmovae, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none }, - .{ .cmovae, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none }, - .{ .cmovae, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .long }, - .{ .cmovb, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none }, - .{ .cmovb, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none }, - .{ .cmovb, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .long }, - .{ .cmovbe, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none }, - .{ .cmovbe, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none }, - .{ .cmovbe, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .long }, - .{ .cmovc, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none }, - .{ .cmovc, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none }, - .{ .cmovc, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .long }, - .{ .cmove, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none }, - .{ .cmove, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none }, - .{ .cmove, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long }, - .{ .cmovg, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none }, - .{ .cmovg, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none }, - .{ .cmovg, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .long }, - .{ .cmovge, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none }, - .{ .cmovge, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none }, - .{ .cmovge, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .long }, - .{ .cmovl, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none }, - .{ .cmovl, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none }, - .{ .cmovl, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .long }, - .{ .cmovle, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none }, - .{ .cmovle, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none }, - .{ .cmovle, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .long }, - .{ .cmovna, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none }, - .{ .cmovna, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none }, - .{ .cmovna, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .long }, - .{ .cmovnae, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none }, - .{ .cmovnae, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none }, - .{ .cmovnae, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .long }, - .{ .cmovnb, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none }, - .{ .cmovnb, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none }, - .{ .cmovnb, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .long }, - .{ .cmovnbe, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none }, - .{ .cmovnbe, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none }, - .{ .cmovnbe, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .long }, - .{ .cmovnc, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none }, - .{ .cmovnc, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none }, - .{ .cmovnc, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .long }, - .{ .cmovne, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none }, - .{ .cmovne, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none }, - .{ .cmovne, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .long }, - .{ .cmovng, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none }, - .{ .cmovng, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none }, - .{ .cmovng, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .long }, - .{ .cmovnge, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none }, - .{ .cmovnge, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none }, - .{ .cmovnge, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .long }, - .{ .cmovnl, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none }, - .{ .cmovnl, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none }, - .{ .cmovnl, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .long }, - .{ .cmovnle, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none }, - .{ .cmovnle, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none }, - .{ .cmovnle, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .long }, - .{ .cmovno, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x41, 0x00, 0, .none }, - .{ .cmovno, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x41, 0x00, 0, .none }, - .{ .cmovno, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x41, 0x00, 0, .long }, - .{ .cmovnp, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none }, - .{ .cmovnp, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none }, - .{ .cmovnp, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .long }, - .{ .cmovns, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x49, 0x00, 0, .none }, - .{ .cmovns, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x49, 0x00, 0, .none }, - .{ .cmovns, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x49, 0x00, 0, .long }, - .{ .cmovnz, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none }, - .{ .cmovnz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none }, - .{ .cmovnz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .long }, - .{ .cmovo, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x40, 0x00, 0, .none }, - .{ .cmovo, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x40, 0x00, 0, .none }, - .{ .cmovo, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x40, 0x00, 0, .long }, - .{ .cmovp, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none }, - .{ .cmovp, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none }, - .{ .cmovp, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .long }, - .{ .cmovpe, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none }, - .{ .cmovpe, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none }, - .{ .cmovpe, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .long }, - .{ .cmovpo, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none }, - .{ .cmovpo, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none }, - .{ .cmovpo, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .long }, - .{ .cmovs, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x48, 0x00, 0, .none }, - .{ .cmovs, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x48, 0x00, 0, .none }, - .{ .cmovs, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x48, 0x00, 0, .long }, - .{ .cmovz, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none }, - .{ .cmovz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none }, - .{ .cmovz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long }, + .{ .cmova, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmova, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmova, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x47 }, 0, .long }, + .{ .cmovae, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovae, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovae, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long }, + .{ .cmovb, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovb, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovb, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long }, + .{ .cmovbe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovbe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovbe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x46 }, 0, .long }, + .{ .cmovc, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovc, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovc, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long }, + .{ .cmove, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmove, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmove, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x44 }, 0, .long }, + .{ .cmovg, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovg, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovg, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4f }, 0, .long }, + .{ .cmovge, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovge, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovge, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4d }, 0, .long }, + .{ .cmovl, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovl, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovl, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4c }, 0, .long }, + .{ .cmovle, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovle, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovle, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4e }, 0, .long }, + .{ .cmovna, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovna, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovna, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x46 }, 0, .long }, + .{ .cmovnae, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovnae, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovnae, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long }, + .{ .cmovnb, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnb, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnb, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long }, + .{ .cmovnbe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmovnbe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmovnbe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x47 }, 0, .long }, + .{ .cmovnc, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnc, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnc, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long }, + .{ .cmovne, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovne, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovne, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x45 }, 0, .long }, + .{ .cmovng, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovng, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovng, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4e }, 0, .long }, + .{ .cmovnge, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovnge, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovnge, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4c }, 0, .long }, + .{ .cmovnl, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovnl, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovnl, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4d }, 0, .long }, + .{ .cmovnle, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovnle, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovnle, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4f }, 0, .long }, + .{ .cmovno, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x41 }, 0, .none }, + .{ .cmovno, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x41 }, 0, .none }, + .{ .cmovno, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x41 }, 0, .long }, + .{ .cmovnp, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovnp, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovnp, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4b }, 0, .long }, + .{ .cmovns, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x49 }, 0, .none }, + .{ .cmovns, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x49 }, 0, .none }, + .{ .cmovns, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x49 }, 0, .long }, + .{ .cmovnz, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovnz, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovnz, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x45 }, 0, .long }, + .{ .cmovo, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x40 }, 0, .none }, + .{ .cmovo, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x40 }, 0, .none }, + .{ .cmovo, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x40 }, 0, .long }, + .{ .cmovp, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovp, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovp, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4a }, 0, .long }, + .{ .cmovpe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovpe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovpe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4a }, 0, .long }, + .{ .cmovpo, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovpo, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovpo, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4b }, 0, .long }, + .{ .cmovs, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x48 }, 0, .none }, + .{ .cmovs, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x48 }, 0, .none }, + .{ .cmovs, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x48 }, 0, .long }, + .{ .cmovz, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmovz, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmovz, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x44 }, 0, .long }, - .{ .cmp, .zi, .al, .imm8, .none, .none, 1, 0x3c, 0x00, 0x00, 0, .none }, - .{ .cmp, .zi, .ax, .imm16, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none }, - .{ .cmp, .zi, .eax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none }, - .{ .cmp, .zi, .rax, .imm32s, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .long }, - .{ .cmp, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 7, .none }, - .{ .cmp, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 7, .rex }, - .{ .cmp, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none }, - .{ .cmp, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none }, - .{ .cmp, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 7, .long }, - .{ .cmp, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none }, - .{ .cmp, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none }, - .{ .cmp, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .long }, - .{ .cmp, .mr, .rm8, .r8, .none, .none, 1, 0x38, 0x00, 0x00, 0, .none }, - .{ .cmp, .mr, .rm8, .r8, .none, .none, 1, 0x38, 0x00, 0x00, 0, .rex }, - .{ .cmp, .mr, .rm16, .r16, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none }, - .{ .cmp, .mr, .rm32, .r32, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none }, - .{ .cmp, .mr, .rm64, .r64, .none, .none, 1, 0x39, 0x00, 0x00, 0, .long }, - .{ .cmp, .rm, .r8, .rm8, .none, .none, 1, 0x3a, 0x00, 0x00, 0, .none }, - .{ .cmp, .rm, .r8, .rm8, .none, .none, 1, 0x3a, 0x00, 0x00, 0, .rex }, - .{ .cmp, .rm, .r16, .rm16, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none }, - .{ .cmp, .rm, .r32, .rm32, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none }, - .{ .cmp, .rm, .r64, .rm64, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .long }, + .{ .cmp, .zi, .al, .imm8, .none, .none, &.{ 0x3c }, 0, .none }, + .{ .cmp, .zi, .ax, .imm16, .none, .none, &.{ 0x3d }, 0, .none }, + .{ .cmp, .zi, .eax, .imm32, .none, .none, &.{ 0x3d }, 0, .none }, + .{ .cmp, .zi, .rax, .imm32s, .none, .none, &.{ 0x3d }, 0, .long }, + .{ .cmp, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 7, .none }, + .{ .cmp, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 7, .rex }, + .{ .cmp, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 7, .none }, + .{ .cmp, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 7, .none }, + .{ .cmp, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 7, .long }, + .{ .cmp, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 7, .none }, + .{ .cmp, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 7, .none }, + .{ .cmp, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 7, .long }, + .{ .cmp, .mr, .rm8, .r8, .none, .none, &.{ 0x38 }, 0, .none }, + .{ .cmp, .mr, .rm8, .r8, .none, .none, &.{ 0x38 }, 0, .rex }, + .{ .cmp, .mr, .rm16, .r16, .none, .none, &.{ 0x39 }, 0, .none }, + .{ .cmp, .mr, .rm32, .r32, .none, .none, &.{ 0x39 }, 0, .none }, + .{ .cmp, .mr, .rm64, .r64, .none, .none, &.{ 0x39 }, 0, .long }, + .{ .cmp, .rm, .r8, .rm8, .none, .none, &.{ 0x3a }, 0, .none }, + .{ .cmp, .rm, .r8, .rm8, .none, .none, &.{ 0x3a }, 0, .rex }, + .{ .cmp, .rm, .r16, .rm16, .none, .none, &.{ 0x3b }, 0, .none }, + .{ .cmp, .rm, .r32, .rm32, .none, .none, &.{ 0x3b }, 0, .none }, + .{ .cmp, .rm, .r64, .rm64, .none, .none, &.{ 0x3b }, 0, .long }, - .{ .div, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .none }, - .{ .div, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .rex }, - .{ .div, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none }, - .{ .div, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none }, - .{ .div, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .long }, + .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .none }, + .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .rex }, + .{ .div, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 6, .none }, + .{ .div, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 6, .none }, + .{ .div, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 6, .long }, - .{ .fisttp, .m, .m16, .none, .none, .none, 1, 0xdf, 0x00, 0x00, 1, .fpu }, - .{ .fisttp, .m, .m32, .none, .none, .none, 1, 0xdb, 0x00, 0x00, 1, .fpu }, - .{ .fisttp, .m, .m64, .none, .none, .none, 1, 0xdd, 0x00, 0x00, 1, .fpu }, + .{ .fisttp, .m, .m16, .none, .none, .none, &.{ 0xdf }, 1, .fpu }, + .{ .fisttp, .m, .m32, .none, .none, .none, &.{ 0xdb }, 1, .fpu }, + .{ .fisttp, .m, .m64, .none, .none, .none, &.{ 0xdd }, 1, .fpu }, - .{ .fld, .m, .m32, .none, .none, .none, 1, 0xd9, 0x00, 0x00, 0, .fpu }, - .{ .fld, .m, .m64, .none, .none, .none, 1, 0xdd, 0x00, 0x00, 0, .fpu }, - .{ .fld, .m, .m80, .none, .none, .none, 1, 0xdb, 0x00, 0x00, 5, .fpu }, + .{ .fld, .m, .m32, .none, .none, .none, &.{ 0xd9 }, 0, .fpu }, + .{ .fld, .m, .m64, .none, .none, .none, &.{ 0xdd }, 0, .fpu }, + .{ .fld, .m, .m80, .none, .none, .none, &.{ 0xdb }, 5, .fpu }, - .{ .idiv, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 7, .none }, - .{ .idiv, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 7, .rex }, - .{ .idiv, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none }, - .{ .idiv, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none }, - .{ .idiv, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .long }, + .{ .idiv, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 7, .none }, + .{ .idiv, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 7, .rex }, + .{ .idiv, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 7, .none }, + .{ .idiv, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 7, .none }, + .{ .idiv, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 7, .long }, - .{ .imul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 5, .none }, - .{ .imul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 5, .rex }, - .{ .imul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none }, - .{ .imul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none }, - .{ .imul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .long }, - .{ .imul, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none }, - .{ .imul, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none }, - .{ .imul, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .long }, - .{ .imul, .rmi, .r16, .rm16, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none }, - .{ .imul, .rmi, .r32, .rm32, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none }, - .{ .imul, .rmi, .r64, .rm64, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .long }, - .{ .imul, .rmi, .r16, .rm16, .imm16, .none, 1, 0x69, 0x00, 0x00, 0, .none }, - .{ .imul, .rmi, .r32, .rm32, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .none }, - .{ .imul, .rmi, .r64, .rm64, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .long }, + .{ .imul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 5, .none }, + .{ .imul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 5, .rex }, + .{ .imul, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 5, .none }, + .{ .imul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 5, .none }, + .{ .imul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 5, .long }, + .{ .imul, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xaf }, 0, .none }, + .{ .imul, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xaf }, 0, .none }, + .{ .imul, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xaf }, 0, .long }, + .{ .imul, .rmi, .r16, .rm16, .imm8s, .none, &.{ 0x6b }, 0, .none }, + .{ .imul, .rmi, .r32, .rm32, .imm8s, .none, &.{ 0x6b }, 0, .none }, + .{ .imul, .rmi, .r64, .rm64, .imm8s, .none, &.{ 0x6b }, 0, .long }, + .{ .imul, .rmi, .r16, .rm16, .imm16, .none, &.{ 0x69 }, 0, .none }, + .{ .imul, .rmi, .r32, .rm32, .imm32, .none, &.{ 0x69 }, 0, .none }, + .{ .imul, .rmi, .r64, .rm64, .imm32, .none, &.{ 0x69 }, 0, .long }, - .{ .int3, .np, .none, .none, .none, .none, 1, 0xcc, 0x00, 0x00, 0, .none }, + .{ .int3, .np, .none, .none, .none, .none, &.{ 0xcc }, 0, .none }, - .{ .ja, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x87, 0x00, 0, .none }, - .{ .jae, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x83, 0x00, 0, .none }, - .{ .jb, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x82, 0x00, 0, .none }, - .{ .jbe, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x86, 0x00, 0, .none }, - .{ .jc, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x82, 0x00, 0, .none }, - .{ .jrcxz, .d, .rel32, .none, .none, .none, 1, 0xe3, 0x00, 0x00, 0, .none }, - .{ .je, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x84, 0x00, 0, .none }, - .{ .jg, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8f, 0x00, 0, .none }, - .{ .jge, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8d, 0x00, 0, .none }, - .{ .jl, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8c, 0x00, 0, .none }, - .{ .jle, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8e, 0x00, 0, .none }, - .{ .jna, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x86, 0x00, 0, .none }, - .{ .jnae, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x82, 0x00, 0, .none }, - .{ .jnb, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x83, 0x00, 0, .none }, - .{ .jnbe, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x87, 0x00, 0, .none }, - .{ .jnc, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x83, 0x00, 0, .none }, - .{ .jne, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x85, 0x00, 0, .none }, - .{ .jng, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8e, 0x00, 0, .none }, - .{ .jnge, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8c, 0x00, 0, .none }, - .{ .jnl, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8d, 0x00, 0, .none }, - .{ .jnle, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8f, 0x00, 0, .none }, - .{ .jno, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x81, 0x00, 0, .none }, - .{ .jnp, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8b, 0x00, 0, .none }, - .{ .jns, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x89, 0x00, 0, .none }, - .{ .jnz, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x85, 0x00, 0, .none }, - .{ .jo, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x80, 0x00, 0, .none }, - .{ .jp, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8a, 0x00, 0, .none }, - .{ .jpe, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8a, 0x00, 0, .none }, - .{ .jpo, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8b, 0x00, 0, .none }, - .{ .js, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x88, 0x00, 0, .none }, - .{ .jz, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x84, 0x00, 0, .none }, + .{ .ja, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x87 }, 0, .none }, + .{ .jae, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none }, + .{ .jb, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none }, + .{ .jbe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x86 }, 0, .none }, + .{ .jc, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none }, + .{ .jrcxz, .d, .rel32, .none, .none, .none, &.{ 0xe3 }, 0, .none }, + .{ .je, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x84 }, 0, .none }, + .{ .jg, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8f }, 0, .none }, + .{ .jge, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8d }, 0, .none }, + .{ .jl, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8c }, 0, .none }, + .{ .jle, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8e }, 0, .none }, + .{ .jna, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x86 }, 0, .none }, + .{ .jnae, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none }, + .{ .jnb, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none }, + .{ .jnbe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x87 }, 0, .none }, + .{ .jnc, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none }, + .{ .jne, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x85 }, 0, .none }, + .{ .jng, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8e }, 0, .none }, + .{ .jnge, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8c }, 0, .none }, + .{ .jnl, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8d }, 0, .none }, + .{ .jnle, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8f }, 0, .none }, + .{ .jno, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x81 }, 0, .none }, + .{ .jnp, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8b }, 0, .none }, + .{ .jns, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x89 }, 0, .none }, + .{ .jnz, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x85 }, 0, .none }, + .{ .jo, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x80 }, 0, .none }, + .{ .jp, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8a }, 0, .none }, + .{ .jpe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8a }, 0, .none }, + .{ .jpo, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8b }, 0, .none }, + .{ .js, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x88 }, 0, .none }, + .{ .jz, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x84 }, 0, .none }, - .{ .jmp, .d, .rel32, .none, .none, .none, 1, 0xe9, 0x00, 0x00, 0, .none }, - .{ .jmp, .m, .rm64, .none, .none, .none, 1, 0xff, 0x00, 0x00, 4, .none }, + .{ .jmp, .d, .rel32, .none, .none, .none, &.{ 0xe9 }, 0, .none }, + .{ .jmp, .m, .rm64, .none, .none, .none, &.{ 0xff }, 4, .none }, - .{ .lea, .rm, .r16, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none }, - .{ .lea, .rm, .r32, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none }, - .{ .lea, .rm, .r64, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .long }, + .{ .lea, .rm, .r16, .m, .none, .none, &.{ 0x8d }, 0, .none }, + .{ .lea, .rm, .r32, .m, .none, .none, &.{ 0x8d }, 0, .none }, + .{ .lea, .rm, .r64, .m, .none, .none, &.{ 0x8d }, 0, .long }, - .{ .mov, .mr, .rm8, .r8, .none, .none, 1, 0x88, 0x00, 0x00, 0, .none }, - .{ .mov, .mr, .rm8, .r8, .none, .none, 1, 0x88, 0x00, 0x00, 0, .rex }, - .{ .mov, .mr, .rm16, .r16, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none }, - .{ .mov, .mr, .rm32, .r32, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none }, - .{ .mov, .mr, .rm64, .r64, .none, .none, 1, 0x89, 0x00, 0x00, 0, .long }, - .{ .mov, .rm, .r8, .rm8, .none, .none, 1, 0x8a, 0x00, 0x00, 0, .none }, - .{ .mov, .rm, .r8, .rm8, .none, .none, 1, 0x8a, 0x00, 0x00, 0, .rex }, - .{ .mov, .rm, .r16, .rm16, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none }, - .{ .mov, .rm, .r32, .rm32, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none }, - .{ .mov, .rm, .r64, .rm64, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .long }, - .{ .mov, .mr, .rm16, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .none }, - .{ .mov, .mr, .rm64, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .long }, - .{ .mov, .rm, .sreg, .rm16, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .none }, - .{ .mov, .rm, .sreg, .rm64, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .long }, - .{ .mov, .fd, .al, .moffs, .none, .none, 1, 0xa0, 0x00, 0x00, 0, .none }, - .{ .mov, .fd, .ax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none }, - .{ .mov, .fd, .eax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none }, - .{ .mov, .fd, .rax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .long }, - .{ .mov, .td, .moffs, .al, .none, .none, 1, 0xa2, 0x00, 0x00, 0, .none }, - .{ .mov, .td, .moffs, .ax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none }, - .{ .mov, .td, .moffs, .eax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none }, - .{ .mov, .td, .moffs, .rax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .long }, - .{ .mov, .oi, .r8, .imm8, .none, .none, 1, 0xb0, 0x00, 0x00, 0, .none }, - .{ .mov, .oi, .r8, .imm8, .none, .none, 1, 0xb0, 0x00, 0x00, 0, .rex }, - .{ .mov, .oi, .r16, .imm16, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none }, - .{ .mov, .oi, .r32, .imm32, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none }, - .{ .mov, .oi, .r64, .imm64, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .long }, - .{ .mov, .mi, .rm8, .imm8, .none, .none, 1, 0xc6, 0x00, 0x00, 0, .none }, - .{ .mov, .mi, .rm8, .imm8, .none, .none, 1, 0xc6, 0x00, 0x00, 0, .rex }, - .{ .mov, .mi, .rm16, .imm16, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none }, - .{ .mov, .mi, .rm32, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none }, - .{ .mov, .mi, .rm64, .imm32s, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .long }, + .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .none }, + .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .rex }, + .{ .mov, .mr, .rm16, .r16, .none, .none, &.{ 0x89 }, 0, .none }, + .{ .mov, .mr, .rm32, .r32, .none, .none, &.{ 0x89 }, 0, .none }, + .{ .mov, .mr, .rm64, .r64, .none, .none, &.{ 0x89 }, 0, .long }, + .{ .mov, .rm, .r8, .rm8, .none, .none, &.{ 0x8a }, 0, .none }, + .{ .mov, .rm, .r8, .rm8, .none, .none, &.{ 0x8a }, 0, .rex }, + .{ .mov, .rm, .r16, .rm16, .none, .none, &.{ 0x8b }, 0, .none }, + .{ .mov, .rm, .r32, .rm32, .none, .none, &.{ 0x8b }, 0, .none }, + .{ .mov, .rm, .r64, .rm64, .none, .none, &.{ 0x8b }, 0, .long }, + .{ .mov, .mr, .rm16, .sreg, .none, .none, &.{ 0x8c }, 0, .none }, + .{ .mov, .mr, .rm64, .sreg, .none, .none, &.{ 0x8c }, 0, .long }, + .{ .mov, .rm, .sreg, .rm16, .none, .none, &.{ 0x8e }, 0, .none }, + .{ .mov, .rm, .sreg, .rm64, .none, .none, &.{ 0x8e }, 0, .long }, + .{ .mov, .fd, .al, .moffs, .none, .none, &.{ 0xa0 }, 0, .none }, + .{ .mov, .fd, .ax, .moffs, .none, .none, &.{ 0xa1 }, 0, .none }, + .{ .mov, .fd, .eax, .moffs, .none, .none, &.{ 0xa1 }, 0, .none }, + .{ .mov, .fd, .rax, .moffs, .none, .none, &.{ 0xa1 }, 0, .long }, + .{ .mov, .td, .moffs, .al, .none, .none, &.{ 0xa2 }, 0, .none }, + .{ .mov, .td, .moffs, .ax, .none, .none, &.{ 0xa3 }, 0, .none }, + .{ .mov, .td, .moffs, .eax, .none, .none, &.{ 0xa3 }, 0, .none }, + .{ .mov, .td, .moffs, .rax, .none, .none, &.{ 0xa3 }, 0, .long }, + .{ .mov, .oi, .r8, .imm8, .none, .none, &.{ 0xb0 }, 0, .none }, + .{ .mov, .oi, .r8, .imm8, .none, .none, &.{ 0xb0 }, 0, .rex }, + .{ .mov, .oi, .r16, .imm16, .none, .none, &.{ 0xb8 }, 0, .none }, + .{ .mov, .oi, .r32, .imm32, .none, .none, &.{ 0xb8 }, 0, .none }, + .{ .mov, .oi, .r64, .imm64, .none, .none, &.{ 0xb8 }, 0, .long }, + .{ .mov, .mi, .rm8, .imm8, .none, .none, &.{ 0xc6 }, 0, .none }, + .{ .mov, .mi, .rm8, .imm8, .none, .none, &.{ 0xc6 }, 0, .rex }, + .{ .mov, .mi, .rm16, .imm16, .none, .none, &.{ 0xc7 }, 0, .none }, + .{ .mov, .mi, .rm32, .imm32, .none, .none, &.{ 0xc7 }, 0, .none }, + .{ .mov, .mi, .rm64, .imm32s, .none, .none, &.{ 0xc7 }, 0, .long }, - .{ .movsx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none }, - .{ .movsx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .rex }, - .{ .movsx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none }, - .{ .movsx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .rex }, - .{ .movsx, .rm, .r64, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .long }, - .{ .movsx, .rm, .r32, .rm16, .none, .none, 2, 0x0f, 0xbf, 0x00, 0, .none }, - .{ .movsx, .rm, .r64, .rm16, .none, .none, 2, 0x0f, 0xbf, 0x00, 0, .long }, + .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none }, + .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex }, + .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none }, + .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex }, + .{ .movsx, .rm, .r64, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .long }, + .{ .movsx, .rm, .r32, .rm16, .none, .none, &.{ 0x0f, 0xbf }, 0, .none }, + .{ .movsx, .rm, .r64, .rm16, .none, .none, &.{ 0x0f, 0xbf }, 0, .long }, // This instruction is discouraged. - .{ .movsxd, .rm, .r32, .rm32, .none, .none, 1, 0x63, 0x00, 0x00, 0, .none }, - .{ .movsxd, .rm, .r64, .rm32, .none, .none, 1, 0x63, 0x00, 0x00, 0, .long }, + .{ .movsxd, .rm, .r32, .rm32, .none, .none, &.{ 0x63 }, 0, .none }, + .{ .movsxd, .rm, .r64, .rm32, .none, .none, &.{ 0x63 }, 0, .long }, - .{ .movzx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xb6, 0x00, 0, .none }, - .{ .movzx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xb6, 0x00, 0, .none }, - .{ .movzx, .rm, .r64, .rm8, .none, .none, 2, 0x0f, 0xb6, 0x00, 0, .long }, - .{ .movzx, .rm, .r32, .rm16, .none, .none, 2, 0x0f, 0xb7, 0x00, 0, .none }, - .{ .movzx, .rm, .r64, .rm16, .none, .none, 2, 0x0f, 0xb7, 0x00, 0, .long }, + .{ .movzx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .none }, + .{ .movzx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .none }, + .{ .movzx, .rm, .r64, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .long }, + .{ .movzx, .rm, .r32, .rm16, .none, .none, &.{ 0x0f, 0xb7 }, 0, .none }, + .{ .movzx, .rm, .r64, .rm16, .none, .none, &.{ 0x0f, 0xb7 }, 0, .long }, - .{ .mul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 4, .none }, - .{ .mul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 4, .rex }, - .{ .mul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 4, .none }, - .{ .mul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 4, .none }, - .{ .mul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 4, .long }, + .{ .mul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 4, .none }, + .{ .mul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 4, .rex }, + .{ .mul, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 4, .none }, + .{ .mul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 4, .none }, + .{ .mul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 4, .long }, - .{ .nop, .np, .none, .none, .none, .none, 1, 0x90, 0x00, 0x00, 0, .none }, + .{ .nop, .np, .none, .none, .none, .none, &.{ 0x90 }, 0, .none }, - .{ .@"or", .zi, .al, .imm8, .none, .none, 1, 0x0c, 0x00, 0x00, 0, .none }, - .{ .@"or", .zi, .ax, .imm16, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none }, - .{ .@"or", .zi, .eax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none }, - .{ .@"or", .zi, .rax, .imm32s, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .long }, - .{ .@"or", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 1, .none }, - .{ .@"or", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 1, .rex }, - .{ .@"or", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none }, - .{ .@"or", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none }, - .{ .@"or", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 1, .long }, - .{ .@"or", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none }, - .{ .@"or", .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none }, - .{ .@"or", .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .long }, - .{ .@"or", .mr, .rm8, .r8, .none, .none, 1, 0x08, 0x00, 0x00, 0, .none }, - .{ .@"or", .mr, .rm8, .r8, .none, .none, 1, 0x08, 0x00, 0x00, 0, .rex }, - .{ .@"or", .mr, .rm16, .r16, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none }, - .{ .@"or", .mr, .rm32, .r32, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none }, - .{ .@"or", .mr, .rm64, .r64, .none, .none, 1, 0x09, 0x00, 0x00, 0, .long }, - .{ .@"or", .rm, .r8, .rm8, .none, .none, 1, 0x0a, 0x00, 0x00, 0, .none }, - .{ .@"or", .rm, .r8, .rm8, .none, .none, 1, 0x0a, 0x00, 0x00, 0, .rex }, - .{ .@"or", .rm, .r16, .rm16, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none }, - .{ .@"or", .rm, .r32, .rm32, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none }, - .{ .@"or", .rm, .r64, .rm64, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .long }, + .{ .@"or", .zi, .al, .imm8, .none, .none, &.{ 0x0c }, 0, .none }, + .{ .@"or", .zi, .ax, .imm16, .none, .none, &.{ 0x0d }, 0, .none }, + .{ .@"or", .zi, .eax, .imm32, .none, .none, &.{ 0x0d }, 0, .none }, + .{ .@"or", .zi, .rax, .imm32s, .none, .none, &.{ 0x0d }, 0, .long }, + .{ .@"or", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 1, .none }, + .{ .@"or", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 1, .rex }, + .{ .@"or", .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 1, .none }, + .{ .@"or", .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 1, .none }, + .{ .@"or", .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 1, .long }, + .{ .@"or", .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 1, .none }, + .{ .@"or", .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 1, .none }, + .{ .@"or", .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 1, .long }, + .{ .@"or", .mr, .rm8, .r8, .none, .none, &.{ 0x08 }, 0, .none }, + .{ .@"or", .mr, .rm8, .r8, .none, .none, &.{ 0x08 }, 0, .rex }, + .{ .@"or", .mr, .rm16, .r16, .none, .none, &.{ 0x09 }, 0, .none }, + .{ .@"or", .mr, .rm32, .r32, .none, .none, &.{ 0x09 }, 0, .none }, + .{ .@"or", .mr, .rm64, .r64, .none, .none, &.{ 0x09 }, 0, .long }, + .{ .@"or", .rm, .r8, .rm8, .none, .none, &.{ 0x0a }, 0, .none }, + .{ .@"or", .rm, .r8, .rm8, .none, .none, &.{ 0x0a }, 0, .rex }, + .{ .@"or", .rm, .r16, .rm16, .none, .none, &.{ 0x0b }, 0, .none }, + .{ .@"or", .rm, .r32, .rm32, .none, .none, &.{ 0x0b }, 0, .none }, + .{ .@"or", .rm, .r64, .rm64, .none, .none, &.{ 0x0b }, 0, .long }, - .{ .pop, .o, .r16, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none }, - .{ .pop, .o, .r64, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none }, - .{ .pop, .m, .rm16, .none, .none, .none, 1, 0x8f, 0x00, 0x00, 0, .none }, - .{ .pop, .m, .rm64, .none, .none, .none, 1, 0x8f, 0x00, 0x00, 0, .none }, + .{ .pop, .o, .r16, .none, .none, .none, &.{ 0x58 }, 0, .none }, + .{ .pop, .o, .r64, .none, .none, .none, &.{ 0x58 }, 0, .none }, + .{ .pop, .m, .rm16, .none, .none, .none, &.{ 0x8f }, 0, .none }, + .{ .pop, .m, .rm64, .none, .none, .none, &.{ 0x8f }, 0, .none }, - .{ .push, .o, .r16, .none, .none, .none, 1, 0x50, 0x00, 0x00, 0, .none }, - .{ .push, .o, .r64, .none, .none, .none, 1, 0x50, 0x00, 0x00, 0, .none }, - .{ .push, .m, .rm16, .none, .none, .none, 1, 0xff, 0x00, 0x00, 6, .none }, - .{ .push, .m, .rm64, .none, .none, .none, 1, 0xff, 0x00, 0x00, 6, .none }, - .{ .push, .i, .imm8, .none, .none, .none, 1, 0x6a, 0x00, 0x00, 0, .none }, - .{ .push, .i, .imm16, .none, .none, .none, 1, 0x68, 0x00, 0x00, 0, .none }, - .{ .push, .i, .imm32, .none, .none, .none, 1, 0x68, 0x00, 0x00, 0, .none }, + .{ .push, .o, .r16, .none, .none, .none, &.{ 0x50 }, 0, .none }, + .{ .push, .o, .r64, .none, .none, .none, &.{ 0x50 }, 0, .none }, + .{ .push, .m, .rm16, .none, .none, .none, &.{ 0xff }, 6, .none }, + .{ .push, .m, .rm64, .none, .none, .none, &.{ 0xff }, 6, .none }, + .{ .push, .i, .imm8, .none, .none, .none, &.{ 0x6a }, 0, .none }, + .{ .push, .i, .imm16, .none, .none, .none, &.{ 0x68 }, 0, .none }, + .{ .push, .i, .imm32, .none, .none, .none, &.{ 0x68 }, 0, .none }, - .{ .ret, .np, .none, .none, .none, .none, 1, 0xc3, 0x00, 0x00, 0, .none }, + .{ .ret, .np, .none, .none, .none, .none, &.{ 0xc3 }, 0, .none }, - .{ .sal, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .none }, - .{ .sal, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .rex }, - .{ .sal, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none }, - .{ .sal, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none }, - .{ .sal, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .long }, - .{ .sal, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 4, .none }, - .{ .sal, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 4, .rex }, - .{ .sal, .mc, .rm16, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none }, - .{ .sal, .mc, .rm32, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none }, - .{ .sal, .mc, .rm64, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 4, .long }, - .{ .sal, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 4, .none }, - .{ .sal, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 4, .rex }, - .{ .sal, .mi, .rm16, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none }, - .{ .sal, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none }, - .{ .sal, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 4, .long }, + .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none }, + .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex }, + .{ .sal, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, + .{ .sal, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, + .{ .sal, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 4, .long }, + .{ .sal, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .none }, + .{ .sal, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .rex }, + .{ .sal, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, + .{ .sal, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, + .{ .sal, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 4, .long }, + .{ .sal, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .none }, + .{ .sal, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .rex }, + .{ .sal, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, + .{ .sal, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, + .{ .sal, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long }, - .{ .sar, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 7, .none }, - .{ .sar, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 7, .rex }, - .{ .sar, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 7, .none }, - .{ .sar, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 7, .none }, - .{ .sar, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 7, .long }, - .{ .sar, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 7, .none }, - .{ .sar, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 7, .rex }, - .{ .sar, .mc, .rm16, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 7, .none }, - .{ .sar, .mc, .rm32, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 7, .none }, - .{ .sar, .mc, .rm64, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 7, .long }, - .{ .sar, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 7, .none }, - .{ .sar, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 7, .rex }, - .{ .sar, .mi, .rm16, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none }, - .{ .sar, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none }, - .{ .sar, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .long }, + .{ .sar, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 7, .none }, + .{ .sar, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 7, .rex }, + .{ .sar, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 7, .none }, + .{ .sar, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 7, .none }, + .{ .sar, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 7, .long }, + .{ .sar, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 7, .none }, + .{ .sar, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 7, .rex }, + .{ .sar, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 7, .none }, + .{ .sar, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 7, .none }, + .{ .sar, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 7, .long }, + .{ .sar, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 7, .none }, + .{ .sar, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 7, .rex }, + .{ .sar, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 7, .none }, + .{ .sar, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 7, .none }, + .{ .sar, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 7, .long }, - .{ .sbb, .zi, .al, .imm8, .none, .none, 1, 0x1c, 0x00, 0x00, 0, .none }, - .{ .sbb, .zi, .ax, .imm16, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none }, - .{ .sbb, .zi, .eax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none }, - .{ .sbb, .zi, .rax, .imm32s, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .long }, - .{ .sbb, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 3, .none }, - .{ .sbb, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 3, .rex }, - .{ .sbb, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none }, - .{ .sbb, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none }, - .{ .sbb, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 3, .long }, - .{ .sbb, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none }, - .{ .sbb, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none }, - .{ .sbb, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .long }, - .{ .sbb, .mr, .rm8, .r8, .none, .none, 1, 0x18, 0x00, 0x00, 0, .none }, - .{ .sbb, .mr, .rm8, .r8, .none, .none, 1, 0x18, 0x00, 0x00, 0, .rex }, - .{ .sbb, .mr, .rm16, .r16, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none }, - .{ .sbb, .mr, .rm32, .r32, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none }, - .{ .sbb, .mr, .rm64, .r64, .none, .none, 1, 0x19, 0x00, 0x00, 0, .long }, - .{ .sbb, .rm, .r8, .rm8, .none, .none, 1, 0x1a, 0x00, 0x00, 0, .none }, - .{ .sbb, .rm, .r8, .rm8, .none, .none, 1, 0x1a, 0x00, 0x00, 0, .rex }, - .{ .sbb, .rm, .r16, .rm16, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none }, - .{ .sbb, .rm, .r32, .rm32, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none }, - .{ .sbb, .rm, .r64, .rm64, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .long }, + .{ .sbb, .zi, .al, .imm8, .none, .none, &.{ 0x1c }, 0, .none }, + .{ .sbb, .zi, .ax, .imm16, .none, .none, &.{ 0x1d }, 0, .none }, + .{ .sbb, .zi, .eax, .imm32, .none, .none, &.{ 0x1d }, 0, .none }, + .{ .sbb, .zi, .rax, .imm32s, .none, .none, &.{ 0x1d }, 0, .long }, + .{ .sbb, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 3, .none }, + .{ .sbb, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 3, .rex }, + .{ .sbb, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 3, .none }, + .{ .sbb, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 3, .none }, + .{ .sbb, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 3, .long }, + .{ .sbb, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 3, .none }, + .{ .sbb, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 3, .none }, + .{ .sbb, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 3, .long }, + .{ .sbb, .mr, .rm8, .r8, .none, .none, &.{ 0x18 }, 0, .none }, + .{ .sbb, .mr, .rm8, .r8, .none, .none, &.{ 0x18 }, 0, .rex }, + .{ .sbb, .mr, .rm16, .r16, .none, .none, &.{ 0x19 }, 0, .none }, + .{ .sbb, .mr, .rm32, .r32, .none, .none, &.{ 0x19 }, 0, .none }, + .{ .sbb, .mr, .rm64, .r64, .none, .none, &.{ 0x19 }, 0, .long }, + .{ .sbb, .rm, .r8, .rm8, .none, .none, &.{ 0x1a }, 0, .none }, + .{ .sbb, .rm, .r8, .rm8, .none, .none, &.{ 0x1a }, 0, .rex }, + .{ .sbb, .rm, .r16, .rm16, .none, .none, &.{ 0x1b }, 0, .none }, + .{ .sbb, .rm, .r32, .rm32, .none, .none, &.{ 0x1b }, 0, .none }, + .{ .sbb, .rm, .r64, .rm64, .none, .none, &.{ 0x1b }, 0, .long }, - .{ .seta, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none }, - .{ .seta, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .rex }, - .{ .setae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none }, - .{ .setae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .rex }, - .{ .setb, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .none }, - .{ .setb, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .rex }, - .{ .setbe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .none }, - .{ .setbe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .rex }, - .{ .setc, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .none }, - .{ .setc, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .rex }, - .{ .sete, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .none }, - .{ .sete, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .rex }, - .{ .setg, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .none }, - .{ .setg, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .rex }, - .{ .setge, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .none }, - .{ .setge, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .rex }, - .{ .setl, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .none }, - .{ .setl, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .rex }, - .{ .setle, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .none }, - .{ .setle, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .rex }, - .{ .setna, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .none }, - .{ .setna, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .rex }, - .{ .setnae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .none }, - .{ .setnae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .rex }, - .{ .setnb, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none }, - .{ .setnb, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .rex }, - .{ .setnbe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none }, - .{ .setnbe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .rex }, - .{ .setnc, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none }, - .{ .setnc, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .rex }, - .{ .setne, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .none }, - .{ .setne, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .rex }, - .{ .setng, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .none }, - .{ .setng, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .rex }, - .{ .setnge, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .none }, - .{ .setnge, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .rex }, - .{ .setnl, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .none }, - .{ .setnl, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .rex }, - .{ .setnle, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .none }, - .{ .setnle, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .rex }, - .{ .setno, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x91, 0x00, 0, .none }, - .{ .setno, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x91, 0x00, 0, .rex }, - .{ .setnp, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .none }, - .{ .setnp, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .rex }, - .{ .setns, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x99, 0x00, 0, .none }, - .{ .setns, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x99, 0x00, 0, .rex }, - .{ .setnz, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .none }, - .{ .setnz, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .rex }, - .{ .seto, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x90, 0x00, 0, .none }, - .{ .seto, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x90, 0x00, 0, .rex }, - .{ .setp, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .none }, - .{ .setp, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .rex }, - .{ .setpe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .none }, - .{ .setpe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .rex }, - .{ .setpo, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .none }, - .{ .setpo, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .rex }, - .{ .sets, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x98, 0x00, 0, .none }, - .{ .sets, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x98, 0x00, 0, .rex }, - .{ .setz, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .none }, - .{ .setz, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .rex }, + .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none }, + .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex }, + .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, + .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex }, + .{ .setb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none }, + .{ .setb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex }, + .{ .setbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .none }, + .{ .setbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .rex }, + .{ .setc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none }, + .{ .setc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex }, + .{ .sete, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none }, + .{ .sete, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex }, + .{ .setg, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .none }, + .{ .setg, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .rex }, + .{ .setge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .none }, + .{ .setge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .rex }, + .{ .setl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .none }, + .{ .setl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .rex }, + .{ .setle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .none }, + .{ .setle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .rex }, + .{ .setna, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .none }, + .{ .setna, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .rex }, + .{ .setnae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none }, + .{ .setnae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex }, + .{ .setnb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, + .{ .setnb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex }, + .{ .setnbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none }, + .{ .setnbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex }, + .{ .setnc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, + .{ .setnc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex }, + .{ .setne, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .none }, + .{ .setne, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .rex }, + .{ .setng, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .none }, + .{ .setng, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .rex }, + .{ .setnge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .none }, + .{ .setnge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .rex }, + .{ .setnl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .none }, + .{ .setnl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .rex }, + .{ .setnle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .none }, + .{ .setnle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .rex }, + .{ .setno, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x91 }, 0, .none }, + .{ .setno, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x91 }, 0, .rex }, + .{ .setnp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .none }, + .{ .setnp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .rex }, + .{ .setns, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x99 }, 0, .none }, + .{ .setns, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x99 }, 0, .rex }, + .{ .setnz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .none }, + .{ .setnz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .rex }, + .{ .seto, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x90 }, 0, .none }, + .{ .seto, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x90 }, 0, .rex }, + .{ .setp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .none }, + .{ .setp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .rex }, + .{ .setpe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .none }, + .{ .setpe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .rex }, + .{ .setpo, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .none }, + .{ .setpo, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .rex }, + .{ .sets, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x98 }, 0, .none }, + .{ .sets, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x98 }, 0, .rex }, + .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none }, + .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex }, - .{ .shl, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .none }, - .{ .shl, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .rex }, - .{ .shl, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none }, - .{ .shl, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none }, - .{ .shl, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .long }, - .{ .shl, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 4, .none }, - .{ .shl, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 4, .rex }, - .{ .shl, .mc, .rm16, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none }, - .{ .shl, .mc, .rm32, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none }, - .{ .shl, .mc, .rm64, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 4, .long }, - .{ .shl, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 4, .none }, - .{ .shl, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 4, .rex }, - .{ .shl, .mi, .rm16, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none }, - .{ .shl, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none }, - .{ .shl, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 4, .long }, + .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none }, + .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex }, + .{ .shl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, + .{ .shl, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, + .{ .shl, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 4, .long }, + .{ .shl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .none }, + .{ .shl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .rex }, + .{ .shl, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, + .{ .shl, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, + .{ .shl, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 4, .long }, + .{ .shl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .none }, + .{ .shl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .rex }, + .{ .shl, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, + .{ .shl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, + .{ .shl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long }, - .{ .shr, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 5, .none }, - .{ .shr, .m1, .rm8, .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 5, .rex }, - .{ .shr, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 5, .none }, - .{ .shr, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 5, .none }, - .{ .shr, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 5, .long }, - .{ .shr, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 5, .none }, - .{ .shr, .mc, .rm8, .cl, .none, .none, 1, 0xd2, 0x00, 0x00, 5, .rex }, - .{ .shr, .mc, .rm16, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 5, .none }, - .{ .shr, .mc, .rm32, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 5, .none }, - .{ .shr, .mc, .rm64, .cl, .none, .none, 1, 0xd3, 0x00, 0x00, 5, .long }, - .{ .shr, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 5, .none }, - .{ .shr, .mi, .rm8, .imm8, .none, .none, 1, 0xc0, 0x00, 0x00, 5, .rex }, - .{ .shr, .mi, .rm16, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none }, - .{ .shr, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none }, - .{ .shr, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .long }, + .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .none }, + .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .rex }, + .{ .shr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 5, .none }, + .{ .shr, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 5, .none }, + .{ .shr, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 5, .long }, + .{ .shr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 5, .none }, + .{ .shr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 5, .rex }, + .{ .shr, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 5, .none }, + .{ .shr, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 5, .none }, + .{ .shr, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 5, .long }, + .{ .shr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 5, .none }, + .{ .shr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 5, .rex }, + .{ .shr, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 5, .none }, + .{ .shr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 5, .none }, + .{ .shr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 5, .long }, - .{ .sub, .zi, .al, .imm8, .none, .none, 1, 0x2c, 0x00, 0x00, 0, .none }, - .{ .sub, .zi, .ax, .imm16, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none }, - .{ .sub, .zi, .eax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none }, - .{ .sub, .zi, .rax, .imm32s, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .long }, - .{ .sub, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 5, .none }, - .{ .sub, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 5, .rex }, - .{ .sub, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none }, - .{ .sub, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none }, - .{ .sub, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 5, .long }, - .{ .sub, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none }, - .{ .sub, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none }, - .{ .sub, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .long }, - .{ .sub, .mr, .rm8, .r8, .none, .none, 1, 0x28, 0x00, 0x00, 0, .none }, - .{ .sub, .mr, .rm8, .r8, .none, .none, 1, 0x28, 0x00, 0x00, 0, .rex }, - .{ .sub, .mr, .rm16, .r16, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none }, - .{ .sub, .mr, .rm32, .r32, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none }, - .{ .sub, .mr, .rm64, .r64, .none, .none, 1, 0x29, 0x00, 0x00, 0, .long }, - .{ .sub, .rm, .r8, .rm8, .none, .none, 1, 0x2a, 0x00, 0x00, 0, .none }, - .{ .sub, .rm, .r8, .rm8, .none, .none, 1, 0x2a, 0x00, 0x00, 0, .rex }, - .{ .sub, .rm, .r16, .rm16, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none }, - .{ .sub, .rm, .r32, .rm32, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none }, - .{ .sub, .rm, .r64, .rm64, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .long }, + .{ .sub, .zi, .al, .imm8, .none, .none, &.{ 0x2c }, 0, .none }, + .{ .sub, .zi, .ax, .imm16, .none, .none, &.{ 0x2d }, 0, .none }, + .{ .sub, .zi, .eax, .imm32, .none, .none, &.{ 0x2d }, 0, .none }, + .{ .sub, .zi, .rax, .imm32s, .none, .none, &.{ 0x2d }, 0, .long }, + .{ .sub, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 5, .none }, + .{ .sub, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 5, .rex }, + .{ .sub, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 5, .none }, + .{ .sub, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 5, .none }, + .{ .sub, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 5, .long }, + .{ .sub, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 5, .none }, + .{ .sub, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 5, .none }, + .{ .sub, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 5, .long }, + .{ .sub, .mr, .rm8, .r8, .none, .none, &.{ 0x28 }, 0, .none }, + .{ .sub, .mr, .rm8, .r8, .none, .none, &.{ 0x28 }, 0, .rex }, + .{ .sub, .mr, .rm16, .r16, .none, .none, &.{ 0x29 }, 0, .none }, + .{ .sub, .mr, .rm32, .r32, .none, .none, &.{ 0x29 }, 0, .none }, + .{ .sub, .mr, .rm64, .r64, .none, .none, &.{ 0x29 }, 0, .long }, + .{ .sub, .rm, .r8, .rm8, .none, .none, &.{ 0x2a }, 0, .none }, + .{ .sub, .rm, .r8, .rm8, .none, .none, &.{ 0x2a }, 0, .rex }, + .{ .sub, .rm, .r16, .rm16, .none, .none, &.{ 0x2b }, 0, .none }, + .{ .sub, .rm, .r32, .rm32, .none, .none, &.{ 0x2b }, 0, .none }, + .{ .sub, .rm, .r64, .rm64, .none, .none, &.{ 0x2b }, 0, .long }, - .{ .syscall, .np, .none, .none, .none, .none, 2, 0x0f, 0x05, 0x00, 0, .none }, + .{ .syscall, .np, .none, .none, .none, .none, &.{ 0x0f, 0x05 }, 0, .none }, - .{ .@"test", .zi, .al, .imm8, .none, .none, 1, 0xa8, 0x00, 0x00, 0, .none }, - .{ .@"test", .zi, .ax, .imm16, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none }, - .{ .@"test", .zi, .eax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none }, - .{ .@"test", .zi, .rax, .imm32s, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .long }, - .{ .@"test", .mi, .rm8, .imm8, .none, .none, 1, 0xf6, 0x00, 0x00, 0, .none }, - .{ .@"test", .mi, .rm8, .imm8, .none, .none, 1, 0xf6, 0x00, 0x00, 0, .rex }, - .{ .@"test", .mi, .rm16, .imm16, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none }, - .{ .@"test", .mi, .rm32, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none }, - .{ .@"test", .mi, .rm64, .imm32s, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .long }, - .{ .@"test", .mr, .rm8, .r8, .none, .none, 1, 0x84, 0x00, 0x00, 0, .none }, - .{ .@"test", .mr, .rm8, .r8, .none, .none, 1, 0x84, 0x00, 0x00, 0, .rex }, - .{ .@"test", .mr, .rm16, .r16, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none }, - .{ .@"test", .mr, .rm32, .r32, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none }, - .{ .@"test", .mr, .rm64, .r64, .none, .none, 1, 0x85, 0x00, 0x00, 0, .long }, + .{ .@"test", .zi, .al, .imm8, .none, .none, &.{ 0xa8 }, 0, .none }, + .{ .@"test", .zi, .ax, .imm16, .none, .none, &.{ 0xa9 }, 0, .none }, + .{ .@"test", .zi, .eax, .imm32, .none, .none, &.{ 0xa9 }, 0, .none }, + .{ .@"test", .zi, .rax, .imm32s, .none, .none, &.{ 0xa9 }, 0, .long }, + .{ .@"test", .mi, .rm8, .imm8, .none, .none, &.{ 0xf6 }, 0, .none }, + .{ .@"test", .mi, .rm8, .imm8, .none, .none, &.{ 0xf6 }, 0, .rex }, + .{ .@"test", .mi, .rm16, .imm16, .none, .none, &.{ 0xf7 }, 0, .none }, + .{ .@"test", .mi, .rm32, .imm32, .none, .none, &.{ 0xf7 }, 0, .none }, + .{ .@"test", .mi, .rm64, .imm32s, .none, .none, &.{ 0xf7 }, 0, .long }, + .{ .@"test", .mr, .rm8, .r8, .none, .none, &.{ 0x84 }, 0, .none }, + .{ .@"test", .mr, .rm8, .r8, .none, .none, &.{ 0x84 }, 0, .rex }, + .{ .@"test", .mr, .rm16, .r16, .none, .none, &.{ 0x85 }, 0, .none }, + .{ .@"test", .mr, .rm32, .r32, .none, .none, &.{ 0x85 }, 0, .none }, + .{ .@"test", .mr, .rm64, .r64, .none, .none, &.{ 0x85 }, 0, .long }, - .{ .ud2, .np, .none, .none, .none, .none, 2, 0x0f, 0x0b, 0x00, 0, .none }, + .{ .ud2, .np, .none, .none, .none, .none, &.{ 0x0f, 0x0b }, 0, .none }, - .{ .xor, .zi, .al, .imm8, .none, .none, 1, 0x34, 0x00, 0x00, 0, .none }, - .{ .xor, .zi, .ax, .imm16, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none }, - .{ .xor, .zi, .eax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none }, - .{ .xor, .zi, .rax, .imm32s, .none, .none, 1, 0x35, 0x00, 0x00, 0, .long }, - .{ .xor, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 6, .none }, - .{ .xor, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 6, .rex }, - .{ .xor, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none }, - .{ .xor, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none }, - .{ .xor, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 6, .long }, - .{ .xor, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none }, - .{ .xor, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none }, - .{ .xor, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .long }, - .{ .xor, .mr, .rm8, .r8, .none, .none, 1, 0x30, 0x00, 0x00, 0, .none }, - .{ .xor, .mr, .rm8, .r8, .none, .none, 1, 0x30, 0x00, 0x00, 0, .rex }, - .{ .xor, .mr, .rm16, .r16, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none }, - .{ .xor, .mr, .rm32, .r32, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none }, - .{ .xor, .mr, .rm64, .r64, .none, .none, 1, 0x31, 0x00, 0x00, 0, .long }, - .{ .xor, .rm, .r8, .rm8, .none, .none, 1, 0x32, 0x00, 0x00, 0, .none }, - .{ .xor, .rm, .r8, .rm8, .none, .none, 1, 0x32, 0x00, 0x00, 0, .rex }, - .{ .xor, .rm, .r16, .rm16, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none }, - .{ .xor, .rm, .r32, .rm32, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none }, - .{ .xor, .rm, .r64, .rm64, .none, .none, 1, 0x33, 0x00, 0x00, 0, .long }, + .{ .xor, .zi, .al, .imm8, .none, .none, &.{ 0x34 }, 0, .none }, + .{ .xor, .zi, .ax, .imm16, .none, .none, &.{ 0x35 }, 0, .none }, + .{ .xor, .zi, .eax, .imm32, .none, .none, &.{ 0x35 }, 0, .none }, + .{ .xor, .zi, .rax, .imm32s, .none, .none, &.{ 0x35 }, 0, .long }, + .{ .xor, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 6, .none }, + .{ .xor, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 6, .rex }, + .{ .xor, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 6, .none }, + .{ .xor, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 6, .none }, + .{ .xor, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 6, .long }, + .{ .xor, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 6, .none }, + .{ .xor, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 6, .none }, + .{ .xor, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 6, .long }, + .{ .xor, .mr, .rm8, .r8, .none, .none, &.{ 0x30 }, 0, .none }, + .{ .xor, .mr, .rm8, .r8, .none, .none, &.{ 0x30 }, 0, .rex }, + .{ .xor, .mr, .rm16, .r16, .none, .none, &.{ 0x31 }, 0, .none }, + .{ .xor, .mr, .rm32, .r32, .none, .none, &.{ 0x31 }, 0, .none }, + .{ .xor, .mr, .rm64, .r64, .none, .none, &.{ 0x31 }, 0, .long }, + .{ .xor, .rm, .r8, .rm8, .none, .none, &.{ 0x32 }, 0, .none }, + .{ .xor, .rm, .r8, .rm8, .none, .none, &.{ 0x32 }, 0, .rex }, + .{ .xor, .rm, .r16, .rm16, .none, .none, &.{ 0x33 }, 0, .none }, + .{ .xor, .rm, .r32, .rm32, .none, .none, &.{ 0x33 }, 0, .none }, + .{ .xor, .rm, .r64, .rm64, .none, .none, &.{ 0x33 }, 0, .long }, // SSE - .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x58, 0, .sse }, + .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x58 }, 0, .sse }, - .{ .cmpss, .rmi, .xmm, .xmm_m32, .imm8, .none, 3, 0xf3, 0x0f, 0xc2, 0, .sse }, + .{ .cmpss, .rmi, .xmm, .xmm_m32, .imm8, .none, &.{ 0xf3, 0x0f, 0xc2 }, 0, .sse }, - .{ .divss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5e, 0, .sse }, + .{ .divss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5e }, 0, .sse }, - .{ .maxss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5f, 0, .sse }, + .{ .maxss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5f }, 0, .sse }, - .{ .minss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5d, 0, .sse }, + .{ .minss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5d }, 0, .sse }, - .{ .movss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x10, 0, .sse }, - .{ .movss, .mr, .xmm_m32, .xmm, .none, .none, 3, 0xf3, 0x0f, 0x11, 0, .sse }, + .{ .movss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x10 }, 0, .sse }, + .{ .movss, .mr, .xmm_m32, .xmm, .none, .none, &.{ 0xf3, 0x0f, 0x11 }, 0, .sse }, - .{ .mulss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x59, 0, .sse }, + .{ .mulss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x59 }, 0, .sse }, - .{ .subss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x5c, 0, .sse }, + .{ .subss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5c }, 0, .sse }, - .{ .ucomiss, .rm, .xmm, .xmm_m32, .none, .none, 2, 0x0f, 0x2e, 0x00, 0, .sse }, + .{ .ucomiss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0x0f, 0x2e }, 0, .sse }, // SSE2 - .{ .addsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x58, 0, .sse2 }, + .{ .addsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x58 }, 0, .sse2 }, - .{ .cmpsd, .rmi, .xmm, .xmm_m64, .imm8, .none, 3, 0xf2, 0x0f, 0xc2, 0, .sse2 }, + .{ .cmpsd, .rmi, .xmm, .xmm_m64, .imm8, .none, &.{ 0xf2, 0x0f, 0xc2 }, 0, .sse2 }, - .{ .divsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x5e, 0, .sse2 }, + .{ .divsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5e }, 0, .sse2 }, - .{ .maxsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x5f, 0, .sse2 }, + .{ .maxsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5f }, 0, .sse2 }, - .{ .minsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x5d, 0, .sse2 }, + .{ .minsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5d }, 0, .sse2 }, - .{ .movq, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf3, 0x0f, 0x7e, 0, .sse2 }, - .{ .movq, .mr, .xmm_m64, .xmm, .none, .none, 3, 0x66, 0x0f, 0xd6, 0, .sse2 }, + .{ .movq, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf3, 0x0f, 0x7e }, 0, .sse2 }, + .{ .movq, .mr, .xmm_m64, .xmm, .none, .none, &.{ 0x66, 0x0f, 0xd6 }, 0, .sse2 }, - .{ .mulsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x59, 0, .sse2 }, + .{ .mulsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x59 }, 0, .sse2 }, - .{ .subsd, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf2, 0x0f, 0x5c, 0, .sse2 }, + .{ .subsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5c }, 0, .sse2 }, - .{ .movsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x10, 0, .sse2 }, - .{ .movsd, .mr, .xmm_m64, .xmm, .none, .none, 3, 0xf2, 0x0f, 0x11, 0, .sse2 }, + .{ .movsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x10 }, 0, .sse2 }, + .{ .movsd, .mr, .xmm_m64, .xmm, .none, .none, &.{ 0xf2, 0x0f, 0x11 }, 0, .sse2 }, - .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0x66, 0x0f, 0x2e, 0, .sse2 }, + .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0x66, 0x0f, 0x2e }, 0, .sse2 }, + + // SSE4.1 + .{ .roundss, .rmi, .xmm, .xmm_m32, .imm8, .none, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 }, + .{ .roundsd, .rmi, .xmm, .xmm_m64, .imm8, .none, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 }, }; // zig fmt: on - From edd63f9abaa7dae1786a4cd91cc3031264bd3ef0 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 18 Mar 2023 05:49:20 -0400 Subject: [PATCH 051/216] x86_64: reimplement inline memcpy and memset --- src/arch/x86_64/CodeGen.zig | 225 +++++++++++++--------------------- src/arch/x86_64/Emit.zig | 50 +++++--- src/arch/x86_64/Encoding.zig | 48 ++++---- src/arch/x86_64/Mir.zig | 43 +++++++ src/arch/x86_64/bits.zig | 3 + src/arch/x86_64/encoder.zig | 71 +++++------ src/arch/x86_64/encodings.zig | 45 +++++++ 7 files changed, 270 insertions(+), 215 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 04e8a7ebe3..7271f8f7f6 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1286,7 +1286,7 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { } } -pub fn spillRegisters(self: *Self, comptime count: comptime_int, registers: [count]Register) !void { +pub fn spillRegisters(self: *Self, registers: []const Register) !void { for (registers) |reg| { try self.register_manager.getReg(reg, null); } @@ -1540,7 +1540,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); } - try self.spillRegisters(2, .{ .rax, .rdx }); + try self.spillRegisters(&.{ .rax, .rdx }); const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); @@ -1594,7 +1594,7 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { try self.spillEflagsIfOccupied(); if (tag == .shl_with_overflow) { - try self.spillRegisters(1, .{.rcx}); + try self.spillRegisters(&.{.rcx}); } const partial: MCValue = switch (tag) { @@ -1721,7 +1721,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { try self.spillEflagsIfOccupied(); self.eflags_inst = inst; - try self.spillRegisters(2, .{ .rax, .rdx }); + try self.spillRegisters(&.{ .rax, .rdx }); const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); @@ -1774,7 +1774,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { break :dst_reg dst_reg; }, .unsigned => { - try self.spillRegisters(2, .{ .rax, .rdx }); + try self.spillRegisters(&.{ .rax, .rdx }); const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); @@ -1888,7 +1888,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); } - try self.spillRegisters(1, .{.rcx}); + try self.spillRegisters(&.{.rcx}); const tag = self.air.instructions.items(.tag)[inst]; const lhs = try self.resolveInst(bin_op.lhs); @@ -2832,6 +2832,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .unreach => unreachable, .eflags => unreachable, .undef => { + if (!self.wantSafety()) return; // The already existing value will do just fine. switch (abi_size) { 1 => try self.store(ptr, .{ .immediate = 0xaa }, ptr_ty, value_ty), 2 => try self.store(ptr, .{ .immediate = 0xaaaa }, ptr_ty, value_ty), @@ -4035,11 +4036,40 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier defer info.deinit(self); try self.spillEflagsIfOccupied(); + try self.spillRegisters(abi.getCallerPreservedRegs(self.target.*)); - for (abi.getCallerPreservedRegs(self.target.*)) |reg| { - try self.register_manager.getReg(reg, null); + // set stack arguments first because this can clobber registers + // also clobber spill arguments as we go + if (info.return_value == .stack_offset) { + try self.spillRegisters(&.{abi.getCAbiIntParamRegs(self.target.*)[0]}); + } + for (args, info.args) |arg, mc_arg| { + const arg_ty = self.air.typeOf(arg); + const arg_mcv = try self.resolveInst(arg); + // Here we do not use setRegOrMem even though the logic is similar, because + // the function call will move the stack pointer, so the offsets are different. + switch (mc_arg) { + .none => {}, + .register => |reg| try self.spillRegisters(&.{reg}), + .stack_offset => |off| { + // TODO rewrite using `genSetStack` + try self.genSetStackArg(arg_ty, off, arg_mcv); + }, + .ptr_stack_offset => { + return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); + }, + .undef => unreachable, + .immediate => unreachable, + .unreach => unreachable, + .dead => unreachable, + .memory => unreachable, + .linker_load => unreachable, + .eflags => unreachable, + .register_overflow => unreachable, + } } + // now we are free to set register arguments const ret_reg_lock: ?RegisterLock = blk: { if (info.return_value == .stack_offset) { const ret_ty = fn_ty.fnReturnType(); @@ -4049,7 +4079,6 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier log.debug("airCall: return value on stack at offset {}", .{stack_offset}); const ret_reg = abi.getCAbiIntParamRegs(self.target.*)[0]; - try self.register_manager.getReg(ret_reg, null); try self.genSetReg(Type.usize, ret_reg, .{ .ptr_stack_offset = stack_offset }); const ret_reg_lock = self.register_manager.lockRegAssumeUnused(ret_reg); @@ -4061,25 +4090,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }; defer if (ret_reg_lock) |lock| self.register_manager.unlockReg(lock); - for (args, info.args) |arg, info_arg| { - const mc_arg = info_arg; + for (args, info.args) |arg, mc_arg| { const arg_ty = self.air.typeOf(arg); const arg_mcv = try self.resolveInst(arg); - // Here we do not use setRegOrMem even though the logic is similar, because - // the function call will move the stack pointer, so the offsets are different. switch (mc_arg) { - .none => continue, - .register => |reg| { - try self.register_manager.getReg(reg, null); - try self.genSetReg(arg_ty, reg, arg_mcv); - }, - .stack_offset => |off| { - // TODO rewrite using `genSetStack` - try self.genSetStackArg(arg_ty, off, arg_mcv); - }, - .ptr_stack_offset => { - return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); - }, + .none, .stack_offset, .ptr_stack_offset => {}, + .register => |reg| try self.genSetReg(arg_ty, reg, arg_mcv), .undef => unreachable, .immediate => unreachable, .unreach => unreachable, @@ -5277,6 +5293,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE .dead => unreachable, .unreach, .none => return, .undef => { + if (!self.wantSafety()) return; // The already existing value will do just fine. if (abi_size <= 8) { const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); @@ -5384,8 +5401,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl .dead => unreachable, .unreach, .none => return, // Nothing to do. .undef => { - if (!self.wantSafety()) - return; // The already existing value will do just fine. + if (!self.wantSafety()) return; // The already existing value will do just fine. // TODO Upgrade this to a memset call when we have that available. switch (abi_size) { 1, 2, 4 => { @@ -5607,19 +5623,14 @@ fn genInlineMemcpy( null; defer if (dsbase_lock) |lock| self.register_manager.unlockReg(lock); - const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); - const dst_addr_reg = regs[0]; - const src_addr_reg = regs[1]; - const index_reg = regs[2].to64(); - const count_reg = regs[3].to64(); - const tmp_reg = regs[4].to8(); + try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); switch (dst_ptr) { .memory, .linker_load => { - try self.loadMemPtrIntoRegister(dst_addr_reg, Type.usize, dst_ptr); + try self.loadMemPtrIntoRegister(.rdi, Type.usize, dst_ptr); }, .ptr_stack_offset, .stack_offset => |off| { - try self.asmRegisterMemory(.lea, dst_addr_reg.to64(), Memory.sib(.qword, .{ + try self.asmRegisterMemory(.lea, .rdi, Memory.sib(.qword, .{ .base = opts.dest_stack_base orelse .rbp, .disp = -off, })); @@ -5627,7 +5638,7 @@ fn genInlineMemcpy( .register => |reg| { try self.asmRegisterRegister( .mov, - registerAlias(dst_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))), + registerAlias(.rdi, @intCast(u32, @divExact(reg.bitSize(), 8))), reg, ); }, @@ -5638,10 +5649,10 @@ fn genInlineMemcpy( switch (src_ptr) { .memory, .linker_load => { - try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_ptr); + try self.loadMemPtrIntoRegister(.rsi, Type.usize, src_ptr); }, .ptr_stack_offset, .stack_offset => |off| { - try self.asmRegisterMemory(.lea, src_addr_reg.to64(), Memory.sib(.qword, .{ + try self.asmRegisterMemory(.lea, .rsi, Memory.sib(.qword, .{ .base = opts.source_stack_base orelse .rbp, .disp = -off, })); @@ -5649,7 +5660,7 @@ fn genInlineMemcpy( .register => |reg| { try self.asmRegisterRegister( .mov, - registerAlias(src_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))), + registerAlias(.rsi, @intCast(u32, @divExact(reg.bitSize(), 8))), reg, ); }, @@ -5658,37 +5669,12 @@ fn genInlineMemcpy( }, } - try self.genSetReg(Type.usize, count_reg, len); - try self.asmRegisterImmediate(.mov, index_reg, Immediate.u(0)); - const loop_start = try self.addInst(.{ - .tag = .cmp, - .ops = .ri_u, - .data = .{ .ri = .{ - .r1 = count_reg, - .imm = 0, - } }, + try self.genSetReg(Type.usize, .rcx, len); + _ = try self.addInst(.{ + .tag = .movs, + .ops = .string, + .data = .{ .string = .{ .repeat = .rep, .width = .b } }, }); - const loop_reloc = try self.asmJccReloc(undefined, .e); - try self.asmRegisterMemory(.mov, tmp_reg.to8(), Memory.sib(.byte, .{ - .base = src_addr_reg, - .scale_index = .{ - .scale = 1, - .index = index_reg, - }, - .disp = 0, - })); - try self.asmMemoryRegister(.mov, Memory.sib(.byte, .{ - .base = dst_addr_reg, - .scale_index = .{ - .scale = 1, - .index = index_reg, - }, - .disp = 0, - }), tmp_reg.to8()); - try self.asmRegisterImmediate(.add, index_reg, Immediate.u(1)); - try self.asmRegisterImmediate(.sub, count_reg, Immediate.u(1)); - _ = try self.asmJmpReloc(loop_start); - try self.performReloc(loop_reloc); } fn genInlineMemset( @@ -5698,28 +5684,20 @@ fn genInlineMemset( len: MCValue, opts: InlineMemcpyOpts, ) InnerError!void { - const ssbase_lock: ?RegisterLock = if (opts.source_stack_base) |reg| - self.register_manager.lockReg(reg) - else - null; - defer if (ssbase_lock) |reg| self.register_manager.unlockReg(reg); - const dsbase_lock: ?RegisterLock = if (opts.dest_stack_base) |reg| self.register_manager.lockReg(reg) else null; defer if (dsbase_lock) |lock| self.register_manager.unlockReg(lock); - const regs = try self.register_manager.allocRegs(2, .{ null, null }, gp); - const addr_reg = regs[0]; - const index_reg = regs[1].to64(); + try self.spillRegisters(&.{ .rdi, .al, .rcx }); switch (dst_ptr) { .memory, .linker_load => { - try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_ptr); + try self.loadMemPtrIntoRegister(.rdi, Type.usize, dst_ptr); }, .ptr_stack_offset, .stack_offset => |off| { - try self.asmRegisterMemory(.lea, addr_reg.to64(), Memory.sib(.qword, .{ + try self.asmRegisterMemory(.lea, .rdi, Memory.sib(.qword, .{ .base = opts.dest_stack_base orelse .rbp, .disp = -off, })); @@ -5727,48 +5705,22 @@ fn genInlineMemset( .register => |reg| { try self.asmRegisterRegister( .mov, - registerAlias(addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))), + registerAlias(.rdi, @intCast(u32, @divExact(reg.bitSize(), 8))), reg, ); }, else => { - return self.fail("TODO implement memcpy for setting stack when dest is {}", .{dst_ptr}); + return self.fail("TODO implement memset for setting stack when dest is {}", .{dst_ptr}); }, } - try self.genSetReg(Type.usize, index_reg, len); - try self.genBinOpMir(.sub, Type.usize, .{ .register = index_reg }, .{ .immediate = 1 }); - - const loop_start = try self.addInst(.{ - .tag = .cmp, - .ops = .ri_s, - .data = .{ .ri = .{ - .r1 = index_reg, - .imm = @bitCast(u32, @as(i32, -1)), - } }, + try self.genSetReg(Type.u8, .al, value); + try self.genSetReg(Type.usize, .rcx, len); + _ = try self.addInst(.{ + .tag = .stos, + .ops = .string, + .data = .{ .string = .{ .repeat = .rep, .width = .b } }, }); - const loop_reloc = try self.asmJccReloc(undefined, .e); - - switch (value) { - .immediate => |x| { - if (x > math.maxInt(i32)) { - return self.fail("TODO inline memset for value immediate larger than 32bits", .{}); - } - try self.asmMemoryImmediate(.mov, Memory.sib(.byte, .{ - .base = addr_reg, - .scale_index = .{ - .scale = 1, - .index = index_reg, - }, - .disp = 0, - }), Immediate.u(@intCast(u8, x))); - }, - else => return self.fail("TODO inline memset for value of type {}", .{value}), - } - - try self.asmRegisterImmediate(.sub, index_reg, Immediate.u(1)); - _ = try self.asmJmpReloc(loop_start); - try self.performReloc(loop_reloc); } fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { @@ -5788,8 +5740,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void }, .unreach, .none => return, // Nothing to do. .undef => { - if (!self.wantSafety()) - return; // The already existing value will do just fine. + if (!self.wantSafety()) return; // The already existing value will do just fine. // Write the debug undefined value. switch (registerAlias(reg, abi_size).bitSize()) { 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }), @@ -5802,27 +5753,27 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .eflags => |cc| { return self.asmSetccRegister(reg.to8(), cc); }, - .immediate => |x| { - if (x == 0) { + .immediate => |imm| { + if (imm == 0) { // 32-bit moves zero-extend to 64-bit, so xoring the 32-bit // register is the fastest way to zero a register. - return self.asmRegisterRegister(.xor, reg.to32(), reg.to32()); + try self.asmRegisterRegister(.xor, reg.to32(), reg.to32()); + } else if (abi_size > 4 and math.cast(u32, imm) != null) { + // 32-bit moves zero-extend to 64-bit. + try self.asmRegisterImmediate(.mov, reg.to32(), Immediate.u(imm)); + } else if (abi_size <= 4 and @bitCast(i64, imm) < 0) { + try self.asmRegisterImmediate( + .mov, + registerAlias(reg, abi_size), + Immediate.s(@intCast(i32, @bitCast(i64, imm))), + ); + } else { + try self.asmRegisterImmediate( + .mov, + registerAlias(reg, abi_size), + Immediate.u(imm), + ); } - if (ty.isSignedInt()) { - const signed_x = @bitCast(i64, x); - if (math.minInt(i32) <= signed_x and signed_x <= math.maxInt(i32)) { - return self.asmRegisterImmediate( - .mov, - registerAlias(reg, abi_size), - Immediate.s(@intCast(i32, signed_x)), - ); - } - } - return self.asmRegisterImmediate( - .mov, - registerAlias(reg, abi_size), - Immediate.u(x), - ); }, .register => |src_reg| { // If the registers are the same, nothing to do. @@ -6136,7 +6087,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void { _ = inst; - return self.fail("TODO implement x86 airAtomicRaw", .{}); + return self.fail("TODO implement x86 airAtomicRmw", .{}); } fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void { @@ -6177,7 +6128,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index) !void { try self.genInlineMemset(dst_ptr, src_val, len, .{}); - return self.finishAir(inst, .none, .{ pl_op.operand, .none, .none }); + return self.finishAir(inst, .none, .{ pl_op.operand, extra.lhs, extra.rhs }); } fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { @@ -6229,7 +6180,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { try self.genInlineMemcpy(dst_ptr, src, len, .{}); - return self.finishAir(inst, .none, .{ pl_op.operand, .none, .none }); + return self.finishAir(inst, .none, .{ pl_op.operand, extra.lhs, extra.rhs }); } fn airTagName(self: *Self, inst: Air.Inst.Index) !void { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 95c5c41170..cf948f6023 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -130,6 +130,13 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .ucomisd, => try emit.mirEncodeGeneric(tag, inst), + .cmps, + .lods, + .movs, + .scas, + .stos, + => try emit.mirString(tag, inst), + .jmp_reloc => try emit.mirJmpReloc(inst), .call_extern => try emit.mirCallExtern(inst), @@ -183,18 +190,8 @@ fn fixupRelocs(emit: *Emit) InnerError!void { } } -fn encode(emit: *Emit, mnemonic: Instruction.Mnemonic, ops: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, -}) InnerError!void { - const inst = try Instruction.new(mnemonic, .{ - .op1 = ops.op1, - .op2 = ops.op2, - .op3 = ops.op3, - .op4 = ops.op4, - }); +fn encode(emit: *Emit, mnemonic: Instruction.Mnemonic, ops: Instruction.Init) InnerError!void { + const inst = try Instruction.new(mnemonic, ops); return inst.encode(emit.code.writer()); } @@ -318,6 +315,28 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE }); } +fn mirString(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { + const ops = emit.mir.instructions.items(.ops)[inst]; + switch (ops) { + .string => { + const data = emit.mir.instructions.items(.data)[inst].string; + const mnemonic = switch (tag) { + inline .cmps, .lods, .movs, .scas, .stos => |comptime_tag| switch (data.width) { + inline else => |comptime_width| @field( + Instruction.Mnemonic, + @tagName(comptime_tag) ++ @tagName(comptime_width), + ), + }, + else => unreachable, + }; + return emit.encode(mnemonic, .{ .prefix = switch (data.repeat) { + inline else => |comptime_repeat| @field(Instruction.Prefix, @tagName(comptime_repeat)), + } }); + }, + else => unreachable, + } +} + fn mirMovMoffs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const ops = emit.mir.instructions.items(.ops)[inst]; const payload = emit.mir.instructions.items(.data)[inst].payload; @@ -377,10 +396,9 @@ fn mirMovsx(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { } fn mnemonicFromConditionCode(comptime basename: []const u8, cc: bits.Condition) Instruction.Mnemonic { - inline for (@typeInfo(bits.Condition).Enum.fields) |field| { - if (mem.eql(u8, field.name, @tagName(cc))) - return @field(Instruction.Mnemonic, basename ++ field.name); - } else unreachable; + return switch (cc) { + inline else => |comptime_cc| @field(Instruction.Mnemonic, basename ++ @tagName(comptime_cc)), + }; } fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 275c001bd7..96396640d6 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -24,12 +24,7 @@ opc: [7]u8, modrm_ext: u3, mode: Mode, -pub fn findByMnemonic(mnemonic: Mnemonic, args: struct { - op1: Instruction.Operand, - op2: Instruction.Operand, - op3: Instruction.Operand, - op4: Instruction.Operand, -}) !?Encoding { +pub fn findByMnemonic(mnemonic: Mnemonic, args: Instruction.Init) !?Encoding { const input_op1 = Op.fromOperand(args.op1); const input_op2 = Op.fromOperand(args.op2); const input_op3 = Op.fromOperand(args.op3); @@ -109,17 +104,13 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct { if (count == 1) return candidates[0]; const EncodingLength = struct { - fn estimate(encoding: Encoding, params: struct { - op1: Instruction.Operand, - op2: Instruction.Operand, - op3: Instruction.Operand, - op4: Instruction.Operand, - }) usize { + fn estimate(encoding: Encoding, params: Instruction.Init) usize { var inst = Instruction{ .op1 = params.op1, .op2 = params.op2, .op3 = params.op3, .op4 = params.op4, + .prefix = params.prefix, .encoding = encoding, }; var cwriter = std.io.countingWriter(std.io.null_writer); @@ -140,12 +131,7 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct { else => {}, } - const len = EncodingLength.estimate(candidate, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - }); + const len = EncodingLength.estimate(candidate, args); const current = shortest_encoding orelse { shortest_encoding = .{ .index = i, .len = len }; continue; @@ -228,7 +214,11 @@ pub fn modRmExt(encoding: Encoding) u3 { } pub fn operandBitSize(encoding: Encoding) u64 { - if (encoding.mode == .long) return 64; + switch (encoding.mode) { + .short => return 16, + .long => return 64, + else => {}, + } const bit_size: u64 = switch (encoding.op_en) { .np => switch (encoding.op1) { .o16 => 16, @@ -317,10 +307,13 @@ pub const Mnemonic = enum { // zig fmt: off // General-purpose adc, add, @"and", - call, cbw, cwde, cdqe, cwd, cdq, cqo, cmp, + call, cbw, cdq, cdqe, cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna, cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno, cmovnp, cmovns, cmovnz, cmovo, cmovp, cmovpe, cmovpo, cmovs, cmovz, + cmp, + cmps, cmpsb, cmpsd, cmpsq, cmpsw, + cqo, cwd, cwde, div, fisttp, fld, idiv, imul, int3, @@ -328,15 +321,21 @@ pub const Mnemonic = enum { jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz, jmp, lea, - mov, movsx, movsxd, movzx, mul, + lods, lodsb, lodsd, lodsq, lodsw, + mov, + movs, movsb, movsd, movsq, movsw, + movsx, movsxd, movzx, mul, nop, @"or", pop, push, ret, - sal, sar, sbb, shl, shr, sub, syscall, + sal, sar, sbb, + scas, scasb, scasd, scasq, scasw, + shl, shr, sub, syscall, seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae, setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns, setnz, seto, setp, setpe, setpo, sets, setz, + stos, stosb, stosd, stosq, stosw, @"test", ud2, xor, @@ -351,10 +350,10 @@ pub const Mnemonic = enum { ucomiss, // SSE2 addsd, - cmpsd, + //cmpsd, divsd, maxsd, minsd, - movq, movsd, + movq, //movsd, mulsd, subsd, ucomisd, @@ -591,6 +590,7 @@ pub const Op = enum { pub const Mode = enum { none, + short, fpu, rex, long, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index ed10bed9b6..2f2c424517 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -150,6 +150,17 @@ pub const Inst = struct { /// Unordered compare scalar double-precision floating-point values ucomisd, + /// Compare string operands + cmps, + /// Load string + lods, + /// Move data from string to string + movs, + /// Scan string + scas, + /// Store string + stos, + /// Conditional move cmovcc, /// Conditional jump @@ -268,6 +279,30 @@ pub const Inst = struct { /// Memory (RIP), register operands. /// Uses `rx` payload with extra data of type `MemoryRip`. mr_rip, + /// Single memory (SIB) operand with lock prefix. + /// Uses `payload` with extra data of type `MemorySib`. + lock_m_sib, + /// Single memory (RIP) operand with lock prefix. + /// Uses `payload` with extra data of type `MemoryRip`. + lock_m_rip, + /// Memory (SIB), immediate (unsigned) operands with lock prefix. + /// Uses `xi` payload with extra data of type `MemorySib`. + lock_mi_u_sib, + /// Memory (RIP), immediate (unsigned) operands with lock prefix. + /// Uses `xi` payload with extra data of type `MemoryRip`. + lock_mi_u_rip, + /// Memory (SIB), immediate (sign-extend) operands with lock prefix. + /// Uses `xi` payload with extra data of type `MemorySib`. + lock_mi_s_sib, + /// Memory (RIP), immediate (sign-extend) operands with lock prefix. + /// Uses `xi` payload with extra data of type `MemoryRip`. + lock_mi_s_rip, + /// Memory (SIB), register operands with lock prefix. + /// Uses `rx` payload with extra data of type `MemorySib`. + lock_mr_sib, + /// Memory (RIP), register operands with lock prefix. + /// Uses `rx` payload with extra data of type `MemoryRip`. + lock_mr_rip, /// Rax, Memory moffs. /// Uses `payload` with extra data of type `MemoryMoffs`. rax_moffs, @@ -280,6 +315,9 @@ pub const Inst = struct { /// References another Mir instruction directly with condition code (CC). /// Uses `inst_cc` payload. inst_cc, + /// String repeat and width + /// Uses `string` payload. + string, /// Uses `reloc` payload. reloc, /// Linker relocation - GOT indirection. @@ -353,6 +391,11 @@ pub const Inst = struct { payload: u32, imm: u32, }, + /// String instruction prefix and width. + string: struct { + repeat: bits.StringRepeat, + width: bits.StringWidth, + }, /// Relocation for the linker where: /// * `atom_index` is the index of the source /// * `sym_index` is the index of the target diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index 72d7b159cf..48a3c64093 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -6,6 +6,9 @@ const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; const DW = std.dwarf; +pub const StringRepeat = enum(u3) { none, rep, repe, repz, repne, repnz }; +pub const StringWidth = enum(u2) { b, w, d, q }; + /// EFLAGS condition codes pub const Condition = enum(u5) { /// above diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 7e29f95069..2a2d6ea031 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -15,10 +15,21 @@ pub const Instruction = struct { op2: Operand = .none, op3: Operand = .none, op4: Operand = .none, + prefix: Prefix = .none, encoding: Encoding, pub const Mnemonic = Encoding.Mnemonic; + pub const Prefix = enum(u3) { + none, + lock, + rep, + repe, + repz, + repne, + repnz, + }; + pub const Operand = union(enum) { none, reg: Register, @@ -96,18 +107,16 @@ pub const Instruction = struct { } }; - pub fn new(mnemonic: Mnemonic, args: struct { + pub const Init = struct { + prefix: Prefix = .none, op1: Operand = .none, op2: Operand = .none, op3: Operand = .none, op4: Operand = .none, - }) !Instruction { - const encoding = (try Encoding.findByMnemonic(mnemonic, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - })) orelse { + }; + + pub fn new(mnemonic: Mnemonic, args: Init) !Instruction { + const encoding = (try Encoding.findByMnemonic(mnemonic, args)) orelse { log.debug("no encoding found for: {s} {s} {s} {s} {s}", .{ @tagName(mnemonic), @tagName(Encoding.Op.fromOperand(args.op1)), @@ -119,6 +128,7 @@ pub const Instruction = struct { }; log.debug("selected encoding: {}", .{encoding}); return .{ + .prefix = args.prefix, .op1 = args.op1, .op2 = args.op2, .op3 = args.op3, @@ -128,6 +138,7 @@ pub const Instruction = struct { } pub fn fmtPrint(inst: Instruction, writer: anytype) !void { + if (inst.prefix != .none) try writer.print("{s} ", .{@tagName(inst.prefix)}); try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)}); const ops = [_]struct { Operand, Encoding.Op }{ .{ inst.op1, inst.encoding.op1 }, @@ -215,6 +226,14 @@ pub const Instruction = struct { const op_en = enc.op_en; var legacy = LegacyPrefixes{}; + + switch (inst.prefix) { + .none => {}, + .lock => legacy.prefix_f0 = true, + .repne, .repnz => legacy.prefix_f2 = true, + .rep, .repe, .repz => legacy.prefix_f3 = true, + } + if (enc.mode == .none) { const bit_size = enc.operandBitSize(); if (bit_size == 16) { @@ -811,15 +830,11 @@ const TestEncode = struct { buffer: [32]u8 = undefined, index: usize = 0, - fn encode(enc: *TestEncode, mnemonic: Instruction.Mnemonic, args: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, - }) !void { + fn encode(enc: *TestEncode, mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { var stream = std.io.fixedBufferStream(&enc.buffer); var count_writer = std.io.countingWriter(stream.writer()); const inst = try Instruction.new(mnemonic, .{ + .prefix = args.prefix, .op1 = args.op1, .op2 = args.op2, .op3 = args.op3, @@ -1447,18 +1462,8 @@ test "lower NP encoding" { try expectEqualHexStrings("\x0f\x05", enc.code(), "syscall"); } -fn invalidInstruction(mnemonic: Instruction.Mnemonic, args: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, -}) !void { - const err = Instruction.new(mnemonic, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - }); +fn invalidInstruction(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { + const err = Instruction.new(mnemonic, args); try testing.expectError(error.InvalidInstruction, err); } @@ -1479,18 +1484,8 @@ test "invalid instruction" { try invalidInstruction(.push, .{ .op1 = .{ .imm = Immediate.u(0x1000000000000000) } }); } -fn cannotEncode(mnemonic: Instruction.Mnemonic, args: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, -}) !void { - try testing.expectError(error.CannotEncode, Instruction.new(mnemonic, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - })); +fn cannotEncode(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { + try testing.expectError(error.CannotEncode, Instruction.new(mnemonic, args)); } test "cannot encode" { diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 57b330b9ce..6f2334ba4a 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -207,6 +207,15 @@ pub const table = &[_]Entry{ .{ .cmp, .rm, .r32, .rm32, .none, .none, &.{ 0x3b }, 0, .none }, .{ .cmp, .rm, .r64, .rm64, .none, .none, &.{ 0x3b }, 0, .long }, + .{ .cmps, .np, .m8, .m8, .none, .none, &.{ 0xa6 }, 0, .none }, + .{ .cmps, .np, .m16, .m16, .none, .none, &.{ 0xa7 }, 0, .none }, + .{ .cmps, .np, .m32, .m32, .none, .none, &.{ 0xa7 }, 0, .none }, + .{ .cmps, .np, .m64, .m64, .none, .none, &.{ 0xa7 }, 0, .long }, + .{ .cmpsb, .np, .none, .none, .none, .none, &.{ 0xa6 }, 0, .none }, + .{ .cmpsw, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .short }, + .{ .cmpsd, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .none }, + .{ .cmpsq, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .long }, + .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .none }, .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .rex }, .{ .div, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 6, .none }, @@ -283,6 +292,15 @@ pub const table = &[_]Entry{ .{ .lea, .rm, .r32, .m, .none, .none, &.{ 0x8d }, 0, .none }, .{ .lea, .rm, .r64, .m, .none, .none, &.{ 0x8d }, 0, .long }, + .{ .lods, .np, .m8, .none, .none, .none, &.{ 0xac }, 0, .none }, + .{ .lods, .np, .m16, .none, .none, .none, &.{ 0xad }, 0, .none }, + .{ .lods, .np, .m32, .none, .none, .none, &.{ 0xad }, 0, .none }, + .{ .lods, .np, .m64, .none, .none, .none, &.{ 0xad }, 0, .long }, + .{ .lodsb, .np, .none, .none, .none, .none, &.{ 0xac }, 0, .none }, + .{ .lodsw, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .short }, + .{ .lodsd, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .none }, + .{ .lodsq, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .long }, + .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .none }, .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .rex }, .{ .mov, .mr, .rm16, .r16, .none, .none, &.{ 0x89 }, 0, .none }, @@ -316,6 +334,15 @@ pub const table = &[_]Entry{ .{ .mov, .mi, .rm32, .imm32, .none, .none, &.{ 0xc7 }, 0, .none }, .{ .mov, .mi, .rm64, .imm32s, .none, .none, &.{ 0xc7 }, 0, .long }, + .{ .movs, .np, .m8, .m8, .none, .none, &.{ 0xa4 }, 0, .none }, + .{ .movs, .np, .m16, .m16, .none, .none, &.{ 0xa5 }, 0, .none }, + .{ .movs, .np, .m32, .m32, .none, .none, &.{ 0xa5 }, 0, .none }, + .{ .movs, .np, .m64, .m64, .none, .none, &.{ 0xa5 }, 0, .long }, + .{ .movsb, .np, .none, .none, .none, .none, &.{ 0xa4 }, 0, .none }, + .{ .movsw, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .short }, + .{ .movsd, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .none }, + .{ .movsq, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .long }, + .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none }, .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex }, .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none }, @@ -435,6 +462,15 @@ pub const table = &[_]Entry{ .{ .sbb, .rm, .r32, .rm32, .none, .none, &.{ 0x1b }, 0, .none }, .{ .sbb, .rm, .r64, .rm64, .none, .none, &.{ 0x1b }, 0, .long }, + .{ .scas, .np, .m8, .none, .none, .none, &.{ 0xae }, 0, .none }, + .{ .scas, .np, .m16, .none, .none, .none, &.{ 0xaf }, 0, .none }, + .{ .scas, .np, .m32, .none, .none, .none, &.{ 0xaf }, 0, .none }, + .{ .scas, .np, .m64, .none, .none, .none, &.{ 0xaf }, 0, .long }, + .{ .scasb, .np, .none, .none, .none, .none, &.{ 0xae }, 0, .none }, + .{ .scasw, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .short }, + .{ .scasd, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .none }, + .{ .scasq, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .long }, + .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none }, .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex }, .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, @@ -528,6 +564,15 @@ pub const table = &[_]Entry{ .{ .shr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 5, .none }, .{ .shr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 5, .long }, + .{ .stos, .np, .m8, .none, .none, .none, &.{ 0xaa }, 0, .none }, + .{ .stos, .np, .m16, .none, .none, .none, &.{ 0xab }, 0, .none }, + .{ .stos, .np, .m32, .none, .none, .none, &.{ 0xab }, 0, .none }, + .{ .stos, .np, .m64, .none, .none, .none, &.{ 0xab }, 0, .long }, + .{ .stosb, .np, .none, .none, .none, .none, &.{ 0xaa }, 0, .none }, + .{ .stosw, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .short }, + .{ .stosd, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .none }, + .{ .stosq, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .long }, + .{ .sub, .zi, .al, .imm8, .none, .none, &.{ 0x2c }, 0, .none }, .{ .sub, .zi, .ax, .imm16, .none, .none, &.{ 0x2d }, 0, .none }, .{ .sub, .zi, .eax, .imm32, .none, .none, &.{ 0x2d }, 0, .none }, From 53ec2a955eb02dc829af8610f17af42717d512fb Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 18 Mar 2023 08:02:17 -0400 Subject: [PATCH 052/216] x86_64: implement clz, ctz, and popCount --- src/arch/x86_64/CodeGen.zig | 141 ++++++++++++++++++++++++++++++---- src/arch/x86_64/Emit.zig | 5 ++ src/arch/x86_64/Encoding.zig | 6 +- src/arch/x86_64/Mir.zig | 10 +++ src/arch/x86_64/encodings.zig | 24 +++++- 5 files changed, 169 insertions(+), 17 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 7271f8f7f6..317a50e0ec 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2597,28 +2597,143 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { fn airClz(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airClz for {}", .{self.target.cpu.arch}); + const result = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const dst_ty = self.air.typeOfIndex(inst); + const src_ty = self.air.typeOf(ty_op.operand); + const src_bits = src_ty.bitSize(self.target.*); + + const src_mcv = try self.resolveInst(ty_op.operand); + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, + else => src_mcv, + }; + const mat_src_lock = switch (mat_src_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_mcv = MCValue{ .register = dst_reg }; + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + + if (Target.x86.featureSetHas(self.target.cpu.features, .lzcnt)) { + try self.genBinOpMir(.lzcnt, src_ty, dst_mcv, mat_src_mcv); + const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); + const extra_bits = registerAlias(dst_reg, src_abi_size).bitSize() - src_bits; + if (extra_bits > 0) { + try self.genBinOpMir(.sub, dst_ty, dst_mcv, .{ .immediate = extra_bits }); + } + break :result dst_mcv; + } + + const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); + const width_mcv = MCValue{ .register = width_reg }; + try self.genBinOpMir(.bsr, src_ty, dst_mcv, mat_src_mcv); + + const dst_abi_size = @intCast(u32, @max(dst_ty.abiSize(self.target.*), 2)); + try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, dst_abi_size), + registerAlias(width_reg, dst_abi_size), + .z, + ); + + try self.genBinOpMir(.sub, dst_ty, width_mcv, dst_mcv); + break :result width_mcv; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airCtz(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airCtz for {}", .{self.target.cpu.arch}); + const result = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const dst_ty = self.air.typeOfIndex(inst); + const src_ty = self.air.typeOf(ty_op.operand); + const src_bits = src_ty.bitSize(self.target.*); + + const src_mcv = try self.resolveInst(ty_op.operand); + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, + else => src_mcv, + }; + const mat_src_lock = switch (mat_src_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_mcv = MCValue{ .register = dst_reg }; + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + + if (Target.x86.featureSetHas(self.target.cpu.features, .bmi)) { + const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); + const extra_bits = registerAlias(dst_reg, src_abi_size).bitSize() - src_bits; + const masked_mcv = if (extra_bits > 0) masked: { + const mask_mcv = MCValue{ + .immediate = ((@as(u64, 1) << @intCast(u6, extra_bits)) - 1) << @intCast(u6, src_bits), + }; + const tmp_mcv = tmp: { + if (src_mcv.isImmediate() or self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) { + break :tmp src_mcv; + } + try self.genSetReg(src_ty, dst_reg, src_mcv); + break :tmp dst_mcv; + }; + try self.genBinOpMir(.@"or", src_ty, tmp_mcv, mask_mcv); + break :masked tmp_mcv; + } else mat_src_mcv; + try self.genBinOpMir(.tzcnt, src_ty, dst_mcv, masked_mcv); + break :result dst_mcv; + } + + const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); + try self.genBinOpMir(.bsf, src_ty, dst_mcv, mat_src_mcv); + + const abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); + try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, abi_size), + registerAlias(width_reg, abi_size), + .z, + ); + + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch}); + const result = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const op_ty = self.air.typeOf(ty_op.operand); + + if (Target.x86.featureSetHas(self.target.cpu.features, .popcnt)) { + const op_mcv = try self.resolveInst(ty_op.operand); + const mat_op_mcv = switch (op_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(op_ty, op_mcv) }, + else => op_mcv, + }; + const mat_op_lock = switch (mat_op_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_op_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, gp) }; + try self.genBinOpMir(.popcnt, op_ty, dst_mcv, mat_op_mcv); + break :result dst_mcv; + } + + return self.fail("TODO implement airPopcount for {}", .{op_ty.fmt(self.bin_file.options.module.?)}); + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -3491,7 +3606,7 @@ fn genBinOp( if (lhs.isRegister() and self.reuseOperand(inst, lhs_air, 0, lhs)) { break :blk lhs; } - if (rhs.isRegister() and is_commutative and self.reuseOperand(inst, rhs_air, 1, rhs)) { + if (is_commutative and rhs.isRegister() and self.reuseOperand(inst, rhs_air, 1, rhs)) { flipped = true; break :blk rhs; } diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index cf948f6023..2da56c08cd 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -73,6 +73,8 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .adc, .add, .@"and", + .bsf, + .bsr, .call, .cbw, .cwde, @@ -89,12 +91,14 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .int3, .jmp, .lea, + .lzcnt, .mov, .movzx, .mul, .nop, .@"or", .pop, + .popcnt, .push, .ret, .sal, @@ -105,6 +109,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .sub, .syscall, .@"test", + .tzcnt, .ud2, .xor, diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 96396640d6..177b996346 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -307,6 +307,7 @@ pub const Mnemonic = enum { // zig fmt: off // General-purpose adc, add, @"and", + bsf, bsr, call, cbw, cdq, cdqe, cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna, cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno, @@ -322,12 +323,13 @@ pub const Mnemonic = enum { jmp, lea, lods, lodsb, lodsd, lodsq, lodsw, + lzcnt, mov, movs, movsb, movsd, movsq, movsw, movsx, movsxd, movzx, mul, nop, @"or", - pop, push, + pop, popcnt, push, ret, sal, sar, sbb, scas, scasb, scasd, scasq, scasw, @@ -336,7 +338,7 @@ pub const Mnemonic = enum { setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns, setnz, seto, setp, setpe, setpo, sets, setz, stos, stosb, stosd, stosq, stosw, - @"test", + @"test", tzcnt, ud2, xor, // SSE diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 2f2c424517..befd1c692d 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -38,6 +38,10 @@ pub const Inst = struct { add, /// Logical and @"and", + /// Bit scan forward + bsf, + /// Bit scan reverse + bsr, /// Call call, /// Convert byte to word @@ -70,6 +74,8 @@ pub const Inst = struct { jmp, /// Load effective address lea, + /// Count the number of leading zero bits + lzcnt, /// Move mov, /// Move with sign extension @@ -84,6 +90,8 @@ pub const Inst = struct { @"or", /// Pop pop, + /// Return the count of number of bits set to 1 + popcnt, /// Push push, /// Return @@ -104,6 +112,8 @@ pub const Inst = struct { syscall, /// Test condition @"test", + /// Count the number of trailing zero bits + tzcnt, /// Undefined instruction ud2, /// Logical exclusive-or diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 6f2334ba4a..1d9663d6c4 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -81,6 +81,14 @@ pub const table = &[_]Entry{ .{ .@"and", .rm, .r32, .rm32, .none, .none, &.{ 0x23 }, 0, .none }, .{ .@"and", .rm, .r64, .rm64, .none, .none, &.{ 0x23 }, 0, .long }, + .{ .bsf, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xbc }, 0, .none }, + .{ .bsf, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbc }, 0, .none }, + .{ .bsf, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbc }, 0, .long }, + + .{ .bsr, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xbd }, 0, .none }, + .{ .bsr, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbd }, 0, .none }, + .{ .bsr, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbd }, 0, .long }, + // This is M encoding according to Intel, but D makes more sense here. .{ .call, .d, .rel32, .none, .none, .none, &.{ 0xe8 }, 0, .none }, .{ .call, .m, .rm64, .none, .none, .none, &.{ 0xff }, 2, .none }, @@ -301,6 +309,10 @@ pub const table = &[_]Entry{ .{ .lodsd, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .none }, .{ .lodsq, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .long }, + .{ .lzcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, + .{ .lzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, + .{ .lzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .long }, + .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .none }, .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .rex }, .{ .mov, .mr, .rm16, .r16, .none, .none, &.{ 0x89 }, 0, .none }, @@ -397,6 +409,10 @@ pub const table = &[_]Entry{ .{ .pop, .m, .rm16, .none, .none, .none, &.{ 0x8f }, 0, .none }, .{ .pop, .m, .rm64, .none, .none, .none, &.{ 0x8f }, 0, .none }, + .{ .popcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none }, + .{ .popcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none }, + .{ .popcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long }, + .{ .push, .o, .r16, .none, .none, .none, &.{ 0x50 }, 0, .none }, .{ .push, .o, .r64, .none, .none, .none, &.{ 0x50 }, 0, .none }, .{ .push, .m, .rm16, .none, .none, .none, &.{ 0xff }, 6, .none }, @@ -596,8 +612,8 @@ pub const table = &[_]Entry{ .{ .sub, .rm, .r32, .rm32, .none, .none, &.{ 0x2b }, 0, .none }, .{ .sub, .rm, .r64, .rm64, .none, .none, &.{ 0x2b }, 0, .long }, - .{ .syscall, .np, .none, .none, .none, .none, &.{ 0x0f, 0x05 }, 0, .none }, - + .{ .syscall, .np, .none, .none, .none, .none, &.{ 0x0f, 0x05 }, 0, .none } +, .{ .@"test", .zi, .al, .imm8, .none, .none, &.{ 0xa8 }, 0, .none }, .{ .@"test", .zi, .ax, .imm16, .none, .none, &.{ 0xa9 }, 0, .none }, .{ .@"test", .zi, .eax, .imm32, .none, .none, &.{ 0xa9 }, 0, .none }, @@ -613,6 +629,10 @@ pub const table = &[_]Entry{ .{ .@"test", .mr, .rm32, .r32, .none, .none, &.{ 0x85 }, 0, .none }, .{ .@"test", .mr, .rm64, .r64, .none, .none, &.{ 0x85 }, 0, .long }, + .{ .tzcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .none }, + .{ .tzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .none }, + .{ .tzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .long }, + .{ .ud2, .np, .none, .none, .none, .none, &.{ 0x0f, 0x0b }, 0, .none }, .{ .xor, .zi, .al, .imm8, .none, .none, &.{ 0x34 }, 0, .none }, From 80427796df5f8eb23ac7ca8ee03ac572b737757f Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 18 Mar 2023 23:10:44 -0400 Subject: [PATCH 053/216] x86_64: implement @returnAddress and @frameAddress --- src/arch/x86_64/CodeGen.zig | 11 +++++++++-- test/behavior/return_address.zig | 1 - 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 317a50e0ec..7cf6865053 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -4119,12 +4119,19 @@ fn airBreakpoint(self: *Self) !void { } fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void { - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for x86_64", .{}); + const result: MCValue = if (self.liveness.isUnused(inst)) + .dead + else + .{ .stack_offset = -@as(i32, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)) }; return self.finishAir(inst, result, .{ .none, .none, .none }); } fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for x86_64", .{}); + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const dst_mcv = try self.allocRegOrMem(inst, true); + try self.genBinOpMir(.mov, Type.usize, dst_mcv, .{ .register = .rbp }); + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ .none, .none, .none }); } diff --git a/test/behavior/return_address.zig b/test/behavior/return_address.zig index fe48f21ec2..123b90a66e 100644 --- a/test/behavior/return_address.zig +++ b/test/behavior/return_address.zig @@ -7,7 +7,6 @@ fn retAddr() usize { test "return address" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From bbd05e2d972b26038bf307f03aa569a7e7a2ac2c Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 02:43:55 -0400 Subject: [PATCH 054/216] x86_64: improve codegen for neg and not --- src/arch/x86_64/CodeGen.zig | 323 +++++++++++++++++++++++++--------- src/arch/x86_64/Emit.zig | 2 + src/arch/x86_64/Encoding.zig | 2 +- src/arch/x86_64/Mir.zig | 4 + src/arch/x86_64/encodings.zig | 12 ++ 5 files changed, 263 insertions(+), 80 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 7cf6865053..4d8c804a0d 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -813,6 +813,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { switch (air_tags[inst]) { // zig fmt: off + .not, + => |tag| try self.airUnOp(inst, tag), + .add, .addwrap, .sub, @@ -905,7 +908,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .is_err_ptr => try self.airIsErrPtr(inst), .load => try self.airLoad(inst), .loop => try self.airLoop(inst), - .not => try self.airNot(inst), .ptrtoint => try self.airPtrToInt(inst), .ret => try self.airRet(inst), .ret_load => try self.airRetLoad(inst), @@ -1419,8 +1421,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { // when truncating a `u16` to `u5`, for example, those top 3 bits in the result // have to be removed. this only happens if the dst if not a power-of-two size. - const dst_bit_size = dst_ty.bitSize(self.target.*); - if (!math.isPowerOfTwo(dst_bit_size) or dst_bit_size < 8) { + if (self.regExtraBits(dst_ty) > 0) { try self.truncateRegister(dst_ty, reg); } @@ -1434,58 +1435,6 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ un_op, .none, .none }); } -fn airNot(self: *Self, inst: Air.Inst.Index) !void { - const ty_op = self.air.instructions.items(.data)[inst].ty_op; - - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); - } - - const operand_ty = self.air.typeOf(ty_op.operand); - const operand = try self.resolveInst(ty_op.operand); - - const result: MCValue = result: { - switch (operand) { - .dead => unreachable, - .unreach => unreachable, - .eflags => |cc| { - break :result MCValue{ .eflags = cc.negate() }; - }, - else => {}, - } - - const operand_lock: ?RegisterLock = switch (operand) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); - - const dst_mcv: MCValue = blk: { - if (self.reuseOperand(inst, ty_op.operand, 0, operand) and operand.isRegister()) { - break :blk operand; - } - break :blk try self.copyToRegisterWithInstTracking(inst, operand_ty, operand); - }; - const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); - - const mask = switch (operand_ty.abiSize(self.target.*)) { - 1 => ~@as(u8, 0), - 2 => ~@as(u16, 0), - 4 => ~@as(u32, 0), - 8 => ~@as(u64, 0), - else => unreachable, - }; - try self.genBinOpMir(.xor, operand_ty, dst_mcv, .{ .immediate = mask }); - - break :result dst_mcv; - }; - return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); -} - fn airSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; @@ -1507,6 +1456,16 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } +fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + + const result = if (self.liveness.isUnused(inst)) + .dead + else + try self.genUnOp(inst, tag, ty_op.operand); + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); +} + fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; @@ -2602,7 +2561,6 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { const dst_ty = self.air.typeOfIndex(inst); const src_ty = self.air.typeOf(ty_op.operand); - const src_bits = src_ty.bitSize(self.target.*); const src_mcv = try self.resolveInst(ty_op.operand); const mat_src_mcv = switch (src_mcv) { @@ -2622,14 +2580,14 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { if (Target.x86.featureSetHas(self.target.cpu.features, .lzcnt)) { try self.genBinOpMir(.lzcnt, src_ty, dst_mcv, mat_src_mcv); - const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); - const extra_bits = registerAlias(dst_reg, src_abi_size).bitSize() - src_bits; + const extra_bits = self.regExtraBits(src_ty); if (extra_bits > 0) { try self.genBinOpMir(.sub, dst_ty, dst_mcv, .{ .immediate = extra_bits }); } break :result dst_mcv; } + const src_bits = src_ty.bitSize(self.target.*); const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); const width_mcv = MCValue{ .register = width_reg }; try self.genBinOpMir(.bsr, src_ty, dst_mcv, mat_src_mcv); @@ -2673,8 +2631,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); if (Target.x86.featureSetHas(self.target.cpu.features, .bmi)) { - const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); - const extra_bits = registerAlias(dst_reg, src_abi_size).bitSize() - src_bits; + const extra_bits = self.regExtraBits(src_ty); const masked_mcv = if (extra_bits > 0) masked: { const mask_mcv = MCValue{ .immediate = ((@as(u64, 1) << @intCast(u6, extra_bits)) - 1) << @intCast(u6, src_bits), @@ -3293,6 +3250,106 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } +fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue { + const src_ty = self.air.typeOf(src_air); + const src_mcv = try self.resolveInst(src_air); + if (src_ty.zigTypeTag() == .Vector) { + return self.fail("TODO implement genBinOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)}); + } + if (src_ty.abiSize(self.target.*) > 8) { + return self.fail("TODO implement genBinOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)}); + } + + switch (src_mcv) { + .eflags => |cc| switch (tag) { + .not => return .{ .eflags = cc.negate() }, + else => {}, + }, + else => {}, + } + + const src_lock = switch (src_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv: MCValue = if (maybe_inst) |inst| + if (self.reuseOperand(inst, src_air, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking(inst, src_ty, src_mcv) + else + .{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }; + const dst_lock = switch (dst_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + + switch (tag) { + .not => { + const int_info = if (src_ty.tag() == .bool) + std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 } + else + src_ty.intInfo(self.target.*); + const extra_bits = self.regExtraBits(src_ty); + if (int_info.signedness == .unsigned and extra_bits > 0) { + const mask = (@as(u64, 1) << @intCast(u6, src_ty.bitSize(self.target.*))) - 1; + try self.genBinOpMir(.xor, src_ty, dst_mcv, .{ .immediate = mask }); + } else try self.genUnOpMir(.not, src_ty, dst_mcv); + }, + + .neg => try self.genUnOpMir(.neg, src_ty, dst_mcv), + + else => unreachable, + } + return dst_mcv; +} + +fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue) !void { + const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); + switch (dst_mcv) { + .none => unreachable, + .undef => unreachable, + .dead, .unreach, .immediate => unreachable, + .eflags => unreachable, + .register_overflow => unreachable, + .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), + .ptr_stack_offset, .stack_offset => |off| { + if (off > math.maxInt(i32)) { + return self.fail("stack offset too large", .{}); + } + if (abi_size > 8) { + return self.fail("TODO implement {} for stack dst with large ABI", .{mir_tag}); + } + + try self.asmMemory(mir_tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = .rbp, + .disp = -off, + })); + }, + .memory, .linker_load => { + const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); + const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); + defer self.register_manager.unlockReg(addr_reg_lock); + + try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv); + + // To get the actual address of the value we want to modify we have to go through the GOT + try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ + .base = addr_reg, + .disp = 0, + })); + + try self.asmMemory(mir_tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = addr_reg, + .disp = 0, + })); + }, + } +} + /// Clobbers .rcx for non-immediate shift value. fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shift: MCValue) !void { assert(reg.to64() != .rcx); @@ -3573,6 +3630,17 @@ fn genBinOp( return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)}); } + switch (lhs) { + .immediate => |imm| switch (imm) { + 0 => switch (tag) { + .sub, .subwrap => return self.genUnOp(maybe_inst, .neg, rhs_air), + else => {}, + }, + else => {}, + }, + else => {}, + } + const is_commutative: bool = switch (tag) { .add, .addwrap, @@ -3595,7 +3663,7 @@ fn genBinOp( defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); const rhs_lock: ?RegisterLock = switch (rhs) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + .register => |reg| self.register_manager.lockReg(reg), else => null, }; defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); @@ -3740,7 +3808,28 @@ fn genBinOp( const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); switch (dst_mcv) { + .none, + .undef, + .dead, + .unreach, + .immediate, + .eflags, + .register_overflow, + .stack_offset, + .ptr_stack_offset, + .memory, + .linker_load, + => unreachable, .register => |dst_reg| switch (mat_src_mcv) { + .none, + .undef, + .dead, + .unreach, + .immediate, + .eflags, + .register_overflow, + .ptr_stack_offset, + => unreachable, .register => |src_reg| try self.asmCmovccRegisterRegister( registerAlias(dst_reg, abi_size), registerAlias(src_reg, abi_size), @@ -3748,12 +3837,36 @@ fn genBinOp( ), .stack_offset => |off| try self.asmCmovccRegisterMemory( registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = .rbp, + .disp = -off, + }), cc, ), - else => unreachable, + .memory, .linker_load => { + const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); + const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); + defer self.register_manager.unlockReg(addr_reg_lock); + + try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv); + + // To get the actual address of the value we want to modify we + // we have to go through the GOT + try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ + .base = addr_reg, + .disp = 0, + })); + + try self.asmCmovccRegisterMemory( + registerAlias(dst_reg, abi_size), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = addr_reg, + .disp = 0, + }), + cc, + ); + }, }, - else => unreachable, } }, .Float => try self.genBinOpMir(switch (lhs_ty.tag()) { @@ -3813,16 +3926,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu ), }, .immediate => |imm| { - switch (abi_size) { - 0 => unreachable, - 1...4 => { + switch (self.regBitSize(dst_ty)) { + 8, 16, 32 => { try self.asmRegisterImmediate( mir_tag, registerAlias(dst_reg, abi_size), Immediate.u(@intCast(u32, imm)), ); }, - 5...8 => { + 64 => { if (math.cast(i32, @bitCast(i64, imm))) |small| { try self.asmRegisterImmediate( mir_tag, @@ -3883,11 +3995,40 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu }), registerAlias(src_reg, abi_size)); }, .immediate => |imm| { - // TODO - try self.asmMemoryImmediate(mir_tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - }), Immediate.u(@intCast(u32, imm))); + switch (self.regBitSize(dst_ty)) { + 8, 16, 32 => { + try self.asmMemoryImmediate( + mir_tag, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = .rbp, + .disp = -off, + }), + Immediate.u(@intCast(u32, imm)), + ); + }, + 64 => { + if (math.cast(i32, @bitCast(i64, imm))) |small| { + try self.asmMemoryImmediate( + mir_tag, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = .rbp, + .disp = -off, + }), + Immediate.s(small), + ); + } else { + try self.asmMemoryRegister( + mir_tag, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = .rbp, + .disp = -off, + }), + registerAlias(try self.copyToTmpRegister(dst_ty, src_mcv), abi_size), + ); + } + }, + else => return self.fail("TODO getBinOpMir implement large immediate ABI", .{}), + } }, .memory, .stack_offset, @@ -4119,17 +4260,20 @@ fn airBreakpoint(self: *Self) !void { } fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void { - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - .{ .stack_offset = -@as(i32, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)) }; + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const dst_mcv = try self.allocRegOrMem(inst, true); + try self.setRegOrMem(Type.usize, dst_mcv, .{ + .stack_offset = -@as(i32, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)), + }); + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ .none, .none, .none }); } fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { const result = if (self.liveness.isUnused(inst)) .dead else result: { const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genBinOpMir(.mov, Type.usize, dst_mcv, .{ .register = .rbp }); + try self.setRegOrMem(Type.usize, dst_mcv, .{ .register = .rbp }); break :result dst_mcv; }; return self.finishAir(inst, result, .{ .none, .none, .none }); @@ -5864,7 +6008,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .undef => { if (!self.wantSafety()) return; // The already existing value will do just fine. // Write the debug undefined value. - switch (registerAlias(reg, abi_size).bitSize()) { + switch (self.regBitSize(ty)) { 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }), 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }), 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }), @@ -6763,6 +6907,27 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { } } +fn regBitSize(self: *Self, ty: Type) u64 { + return switch (ty.zigTypeTag()) { + else => switch (ty.abiSize(self.target.*)) { + 1 => 8, + 2 => 16, + 3...4 => 32, + 5...8 => 64, + else => unreachable, + }, + .Float => switch (ty.abiSize(self.target.*)) { + 1...16 => 128, + 17...32 => 256, + else => unreachable, + }, + }; +} + +fn regExtraBits(self: *Self, ty: Type) u64 { + return self.regBitSize(ty) - ty.bitSize(self.target.*); +} + fn intrinsicsAllowed(target: Target, ty: Type) bool { return switch (ty.tag()) { .f32, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 2da56c08cd..b2a13a192a 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -95,7 +95,9 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .mov, .movzx, .mul, + .neg, .nop, + .not, .@"or", .pop, .popcnt, diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 177b996346..c813f2bece 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -327,7 +327,7 @@ pub const Mnemonic = enum { mov, movs, movsb, movsd, movsq, movsw, movsx, movsxd, movzx, mul, - nop, + neg, nop, not, @"or", pop, popcnt, push, ret, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index befd1c692d..9f9122dd5e 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -84,8 +84,12 @@ pub const Inst = struct { movzx, /// Multiply mul, + /// Two's complement negation + neg, /// No-op nop, + /// One's complement negation + not, /// Logical or @"or", /// Pop diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 1d9663d6c4..7ade1be11b 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -379,8 +379,20 @@ pub const table = &[_]Entry{ .{ .mul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 4, .none }, .{ .mul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 4, .long }, + .{ .neg, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 3, .none }, + .{ .neg, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 3, .rex }, + .{ .neg, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 3, .none }, + .{ .neg, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 3, .none }, + .{ .neg, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 3, .long }, + .{ .nop, .np, .none, .none, .none, .none, &.{ 0x90 }, 0, .none }, + .{ .not, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 2, .none }, + .{ .not, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 2, .rex }, + .{ .not, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 2, .none }, + .{ .not, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 2, .none }, + .{ .not, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 2, .long }, + .{ .@"or", .zi, .al, .imm8, .none, .none, &.{ 0x0c }, 0, .none }, .{ .@"or", .zi, .ax, .imm16, .none, .none, &.{ 0x0d }, 0, .none }, .{ .@"or", .zi, .eax, .imm32, .none, .none, &.{ 0x0d }, 0, .none }, From 24f0900ecba3ea67b7c6df31836ed40de22b7ab8 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 03:51:51 -0400 Subject: [PATCH 055/216] x86_64: implement some error union ops --- src/arch/x86_64/CodeGen.zig | 121 ++++++++++++++++++++++++++++++------ test/behavior/error.zig | 1 - 2 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 4d8c804a0d..95068a2bee 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -994,10 +994,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .optional_payload => try self.airOptionalPayload(inst), .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), - .unwrap_errunion_err => try self.airUnwrapErrErr(inst), - .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst), - .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst), - .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst), + .unwrap_errunion_err => try self.airUnwrapErrUnionErr(inst), + .unwrap_errunion_payload => try self.airUnwrapErrUnionPayload(inst), + .unwrap_errunion_err_ptr => try self.airUnwrapErrUnionErrPtr(inst), + .unwrap_errunion_payload_ptr=> try self.airUnwrapErrUnionPayloadPtr(inst), .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst), .err_return_trace => try self.airErrReturnTrace(inst), .set_err_return_trace => try self.airSetErrReturnTrace(inst), @@ -1923,7 +1923,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } -fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { +fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; if (self.liveness.isUnused(inst)) { return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); @@ -1967,7 +1967,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } -fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { +fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; if (self.liveness.isUnused(inst)) { return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); @@ -2021,31 +2021,112 @@ fn genUnwrapErrorUnionPayloadMir( } // *(E!T) -> E -fn airUnwrapErrErrPtr(self: *Self, inst: Air.Inst.Index) !void { +fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement unwrap error union error ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const src_ty = self.air.typeOf(ty_op.operand); + const src_mcv = try self.resolveInst(ty_op.operand); + const src_reg = switch (src_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(src_ty, src_mcv), + }; + const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); + defer self.register_manager.unlockReg(src_lock); + + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const eu_ty = src_ty.childType(); + const pl_ty = eu_ty.errorUnionPayload(); + const err_ty = eu_ty.errorUnionSet(); + const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); + const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*)); + try self.asmRegisterMemory( + .mov, + registerAlias(dst_reg, err_abi_size), + Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{ .base = src_reg, .disp = err_off }), + ); + break :result .{ .register = dst_reg }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } // *(E!T) -> *T -fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { +fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement unwrap error union payload ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const src_ty = self.air.typeOf(ty_op.operand); + const src_mcv = try self.resolveInst(ty_op.operand); + const src_reg = switch (src_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(src_ty, src_mcv), + }; + const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); + defer self.register_manager.unlockReg(src_lock); + + const dst_ty = self.air.typeOfIndex(inst); + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const eu_ty = src_ty.childType(); + const pl_ty = eu_ty.errorUnionPayload(); + const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*)); + const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); + try self.asmRegisterMemory( + .lea, + registerAlias(dst_reg, dst_abi_size), + Memory.sib(.qword, .{ .base = src_reg, .disp = pl_off }), + ); + break :result .{ .register = dst_reg }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch}); + const result: MCValue = result: { + const src_ty = self.air.typeOf(ty_op.operand); + const src_mcv = try self.resolveInst(ty_op.operand); + const src_reg = switch (src_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(src_ty, src_mcv), + }; + const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); + defer self.register_manager.unlockReg(src_lock); + + const eu_ty = src_ty.childType(); + const pl_ty = eu_ty.errorUnionPayload(); + const err_ty = eu_ty.errorUnionSet(); + const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); + const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*)); + try self.asmMemoryImmediate( + .mov, + Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{ .base = src_reg, .disp = err_off }), + Immediate.u(0), + ); + + if (self.liveness.isUnused(inst)) break :result .dead; + + const dst_ty = self.air.typeOfIndex(inst); + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); + const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); + try self.asmRegisterMemory( + .lea, + registerAlias(dst_reg, dst_abi_size), + Memory.sib(.qword, .{ .base = src_reg, .disp = pl_off }), + ); + break :result .{ .register = dst_reg }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 9d4b154311..294b4ac2eb 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -731,7 +731,6 @@ test "pointer to error union payload" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var err_union: anyerror!u8 = 15; From f95faac5aeeebe0b77ff7023513cdd3e34b71de1 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 06:49:50 -0400 Subject: [PATCH 056/216] x86_64: (re)implement optional ops Note that this commit also changes the layout of optional for all other backends using `src/codegen.zig` without updating them! --- src/arch/x86_64/CodeGen.zig | 320 +++++++++++++++++++++------------- src/arch/x86_64/Emit.zig | 4 + src/arch/x86_64/Encoding.zig | 2 +- src/arch/x86_64/Mir.zig | 8 + src/arch/x86_64/encodings.zig | 28 +++ src/codegen.zig | 5 +- test/behavior/bugs/12984.zig | 1 - test/behavior/bugs/13785.zig | 1 - test/behavior/call.zig | 1 - test/behavior/cast.zig | 1 - test/behavior/error.zig | 1 - test/behavior/if.zig | 1 - test/behavior/null.zig | 2 - test/behavior/optional.zig | 7 - test/behavior/ptrcast.zig | 1 - test/behavior/struct.zig | 3 - test/behavior/tuple.zig | 4 - test/behavior/union.zig | 1 - test/behavior/while.zig | 1 - 19 files changed, 243 insertions(+), 149 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 95068a2bee..f788dbd531 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1871,55 +1871,74 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); - } - - const payload_ty = self.air.typeOfIndex(inst); - const optional_ty = self.air.typeOf(ty_op.operand); - const operand = try self.resolveInst(ty_op.operand); const result: MCValue = result: { - if (!payload_ty.hasRuntimeBits()) break :result MCValue.none; - if (optional_ty.isPtrLikeOptional()) { - if (self.reuseOperand(inst, ty_op.operand, 0, operand)) { - break :result operand; + if (self.liveness.isUnused(inst)) break :result .none; + + const pl_ty = self.air.typeOfIndex(inst); + const opt_mcv = try self.resolveInst(ty_op.operand); + + if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { + switch (opt_mcv) { + .register => |reg| try self.truncateRegister(pl_ty, reg), + else => {}, } - break :result try self.copyToRegisterWithInstTracking(inst, payload_ty, operand); + break :result opt_mcv; } - const offset = optional_ty.abiSize(self.target.*) - payload_ty.abiSize(self.target.*); - switch (operand) { - .stack_offset => |off| { - break :result MCValue{ .stack_offset = off - @intCast(i32, offset) }; - }, - .register => { - // TODO reuse the operand - const result = try self.copyToRegisterWithInstTracking(inst, optional_ty, operand); - const shift = @intCast(u8, offset * @sizeOf(usize)); - try self.genShiftBinOpMir(.shr, optional_ty, result.register, .{ .immediate = @intCast(u8, shift) }); - break :result result; - }, - else => return self.fail("TODO implement optional_payload when operand is {}", .{operand}), - } + const pl_mcv = try self.allocRegOrMem(inst, true); + try self.setRegOrMem(pl_ty, pl_mcv, opt_mcv); + break :result pl_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const dst_ty = self.air.typeOfIndex(inst); + const opt_mcv = try self.resolveInst(ty_op.operand); + + break :result if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) + opt_mcv + else + try self.copyToRegisterWithInstTracking(inst, dst_ty, opt_mcv); + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch}); + const result = result: { + const dst_ty = self.air.typeOfIndex(inst); + const src_ty = self.air.typeOf(ty_op.operand); + const opt_ty = src_ty.childType(); + const src_mcv = try self.resolveInst(ty_op.operand); + + if (opt_ty.optionalReprIsPayload()) { + break :result if (self.liveness.isUnused(inst)) + .dead + else if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); + } + + const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); + + const pl_ty = dst_ty.childType(); + const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*)); + try self.asmMemoryImmediate( + .mov, + Memory.sib(.byte, .{ .base = dst_mcv.register, .disp = pl_abi_size }), + Immediate.u(1), + ); + break :result if (self.liveness.isUnused(inst)) .dead else dst_mcv; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -2150,41 +2169,45 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); - } - - const payload_ty = self.air.typeOf(ty_op.operand); const result: MCValue = result: { - if (!payload_ty.hasRuntimeBits()) { - break :result MCValue{ .immediate = 1 }; - } + if (self.liveness.isUnused(inst)) break :result .dead; - const optional_ty = self.air.typeOfIndex(inst); - const operand = try self.resolveInst(ty_op.operand); - const operand_lock: ?RegisterLock = switch (operand) { + const pl_ty = self.air.typeOf(ty_op.operand); + if (!pl_ty.hasRuntimeBits()) break :result .{ .immediate = 1 }; + + const opt_ty = self.air.typeOfIndex(inst); + const pl_mcv = try self.resolveInst(ty_op.operand); + const same_repr = opt_ty.optionalReprIsPayload(); + if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv; + + const pl_lock: ?RegisterLock = switch (pl_mcv) { .register => |reg| self.register_manager.lockRegAssumeUnused(reg), else => null, }; - defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); + defer if (pl_lock) |lock| self.register_manager.unlockReg(lock); - if (optional_ty.isPtrLikeOptional()) { - // TODO should we check if we can reuse the operand? - if (self.reuseOperand(inst, ty_op.operand, 0, operand)) { - break :result operand; + const opt_mcv = try self.allocRegOrMem(inst, true); + try self.setRegOrMem(pl_ty, opt_mcv, pl_mcv); + + if (!same_repr) { + const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*)); + switch (opt_mcv) { + else => unreachable, + + .register => |opt_reg| try self.asmRegisterImmediate( + .bts, + opt_reg, + Immediate.u(@intCast(u6, pl_abi_size * 8)), + ), + + .stack_offset => |off| try self.asmMemoryImmediate( + .mov, + Memory.sib(.byte, .{ .base = .rsp, .disp = pl_abi_size - off }), + Immediate.u(0), + ), } - break :result try self.copyToRegisterWithInstTracking(inst, payload_ty, operand); } - - const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*)); - const optional_abi_align = optional_ty.abiAlignment(self.target.*); - const payload_abi_size = @intCast(u32, payload_ty.abiSize(self.target.*)); - const offset = optional_abi_size - payload_abi_size; - - const stack_offset = @intCast(i32, try self.allocMem(inst, optional_abi_size, optional_abi_align)); - try self.genSetStack(Type.bool, stack_offset, .{ .immediate = 1 }, .{}); - try self.genSetStack(payload_ty, stack_offset - @intCast(i32, offset), operand, .{}); - break :result MCValue{ .stack_offset = stack_offset }; + break :result opt_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -2619,7 +2642,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { }, .register => { const shift: u6 = if (layout.tag_align < layout.payload_align) - @intCast(u6, layout.payload_size * @sizeOf(usize)) + @intCast(u6, layout.payload_size * 8) else 0; const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); @@ -3271,7 +3294,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); // Shift by struct_field_offset. - const shift = @intCast(u8, struct_field_offset * @sizeOf(usize)); + const shift = @intCast(u8, struct_field_offset * 8); try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv.register, .{ .immediate = shift }); // Mask with reg.bitSize() - struct_field_size @@ -4928,25 +4951,107 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, .unreach, .{ .none, .none, .none }); } -fn isNull(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { +fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { try self.spillEflagsIfOccupied(); self.eflags_inst = inst; - const cmp_ty: Type = if (!ty.isPtrLikeOptional()) blk: { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); - break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime()) Type.bool else ty; - } else ty; + var pl_buf: Type.Payload.ElemType = undefined; + const pl_ty = opt_ty.optionalChild(&pl_buf); - try self.genBinOpMir(.cmp, cmp_ty, operand, MCValue{ .immediate = 0 }); + var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; + const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload()) + .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty } + else + .{ .off = @intCast(i32, pl_ty.abiSize(self.target.*)), .ty = Type.bool }; - return MCValue{ .eflags = .e }; + switch (opt_mcv) { + .none, + .unreach, + .dead, + .undef, + .immediate, + .register_overflow, + .ptr_stack_offset, + .eflags, + => unreachable, + + .register => |opt_reg| { + if (some_info.off == 0) { + const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); + const alias_reg = registerAlias(opt_reg, some_abi_size); + assert(some_abi_size * 8 == alias_reg.bitSize()); + try self.asmRegisterRegister(.@"test", alias_reg, alias_reg); + return .{ .eflags = .z }; + } + assert(some_info.ty.tag() == .bool); + const opt_abi_size = @intCast(u32, opt_ty.abiSize(self.target.*)); + try self.asmRegisterImmediate( + .bt, + registerAlias(opt_reg, opt_abi_size), + Immediate.u(@intCast(u6, some_info.off * 8)), + ); + return .{ .eflags = .nc }; + }, + + .memory, .linker_load => { + const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); + const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); + defer self.register_manager.unlockReg(addr_reg_lock); + + try self.loadMemPtrIntoRegister(addr_reg, Type.usize, opt_mcv); + + // To get the actual address of the value we want to modify we have to go through the GOT + try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ + .base = addr_reg, + .disp = 0, + })); + + const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); + try self.asmMemoryImmediate(.cmp, Memory.sib( + Memory.PtrSize.fromSize(some_abi_size), + .{ .base = addr_reg, .disp = some_info.off }, + ), Immediate.u(0)); + return .{ .eflags = .e }; + }, + + .stack_offset => |off| { + const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); + try self.asmMemoryImmediate(.cmp, Memory.sib( + Memory.PtrSize.fromSize(some_abi_size), + .{ .base = .rbp, .disp = some_info.off - off }, + ), Immediate.u(0)); + return .{ .eflags = .e }; + }, + } } -fn isNonNull(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { - const is_null_res = try self.isNull(inst, ty, operand); - assert(is_null_res.eflags == .e); - return MCValue{ .eflags = is_null_res.eflags.negate() }; +fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { + try self.spillEflagsIfOccupied(); + self.eflags_inst = inst; + + const opt_ty = ptr_ty.childType(); + var pl_buf: Type.Payload.ElemType = undefined; + const pl_ty = opt_ty.optionalChild(&pl_buf); + + var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; + const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload()) + .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty } + else + .{ .off = @intCast(i32, pl_ty.abiSize(self.target.*)), .ty = Type.bool }; + + const ptr_reg = switch (ptr_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(ptr_ty, ptr_mcv), + }; + const ptr_lock = self.register_manager.lockReg(ptr_reg); + defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); + + const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); + try self.asmMemoryImmediate(.cmp, Memory.sib( + Memory.PtrSize.fromSize(some_abi_size), + .{ .base = ptr_reg, .disp = some_info.off }, + ), Immediate.u(0)); + return .{ .eflags = .e }; } fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { @@ -5012,29 +5117,11 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; - - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ un_op, .none, .none }); - } - - const operand_ptr = try self.resolveInst(un_op); - const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const operand = try self.resolveInst(un_op); + const ty = self.air.typeOf(un_op); + break :result try self.isNullPtr(inst, ty, operand); }; - defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock); - - const ptr_ty = self.air.typeOf(un_op); - const elem_ty = ptr_ty.childType(); - const operand = if (elem_ty.isPtrLikeOptional() and self.reuseOperand(inst, un_op, 0, operand_ptr)) - // The MCValue that holds the pointer can be re-used as the value. - operand_ptr - else - try self.allocTempRegOrMem(elem_ty, true); - try self.load(operand, operand_ptr, ptr_ty); - - const result = try self.isNull(inst, elem_ty, operand); - return self.finishAir(inst, result, .{ un_op, .none, .none }); } @@ -5043,36 +5130,24 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand = try self.resolveInst(un_op); const ty = self.air.typeOf(un_op); - break :result try self.isNonNull(inst, ty, operand); + break :result switch (try self.isNull(inst, ty, operand)) { + .eflags => |cc| .{ .eflags = cc.negate() }, + else => unreachable, + }; }; return self.finishAir(inst, result, .{ un_op, .none, .none }); } fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; - - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ un_op, .none, .none }); - } - - const operand_ptr = try self.resolveInst(un_op); - const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const operand = try self.resolveInst(un_op); + const ty = self.air.typeOf(un_op); + break :result switch (try self.isNullPtr(inst, ty, operand)) { + .eflags => |cc| .{ .eflags = cc.negate() }, + else => unreachable, + }; }; - defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock); - - const ptr_ty = self.air.typeOf(un_op); - const elem_ty = ptr_ty.childType(); - const operand = if (elem_ty.isPtrLikeOptional() and self.reuseOperand(inst, un_op, 0, operand_ptr)) - // The MCValue that holds the pointer can be re-used as the value. - operand_ptr - else - try self.allocTempRegOrMem(elem_ty, true); - try self.load(operand, operand_ptr, ptr_ty); - - const result = try self.isNonNull(inst, ptr_ty.elemType(), operand); - return self.finishAir(inst, result, .{ un_op, .none, .none }); } @@ -6967,7 +7042,10 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { /// Truncates the value in the register in place. /// Clobbers any remaining bits. fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { - const int_info = ty.intInfo(self.target.*); + const int_info = if (ty.isAbiInt()) ty.intInfo(self.target.*) else std.builtin.Type.Int{ + .signedness = .unsigned, + .bits = @intCast(u16, ty.bitSize(self.target.*)), + }; const max_reg_bit_width = Register.rax.bitSize(); switch (int_info.signedness) { .signed => { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index b2a13a192a..4c63385e6b 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -75,6 +75,10 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .@"and", .bsf, .bsr, + .bt, + .btc, + .btr, + .bts, .call, .cbw, .cwde, diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index c813f2bece..436202ca3e 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -307,7 +307,7 @@ pub const Mnemonic = enum { // zig fmt: off // General-purpose adc, add, @"and", - bsf, bsr, + bsf, bsr, bt, btc, btr, bts, call, cbw, cdq, cdqe, cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna, cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 9f9122dd5e..e7d75e7446 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -42,6 +42,14 @@ pub const Inst = struct { bsf, /// Bit scan reverse bsr, + /// Bit test + bt, + /// Bit test and complement + btc, + /// Bit test and reset + btr, + /// Bit test and set + bts, /// Call call, /// Convert byte to word diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 7ade1be11b..ea21af2067 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -89,6 +89,34 @@ pub const table = &[_]Entry{ .{ .bsr, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbd }, 0, .none }, .{ .bsr, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbd }, 0, .long }, + .{ .bt, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none }, + .{ .bt, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none }, + .{ .bt, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xa3 }, 0, .long }, + .{ .bt, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .none }, + .{ .bt, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .none }, + .{ .bt, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .long }, + + .{ .btc, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xbb }, 0, .none }, + .{ .btc, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xbb }, 0, .none }, + .{ .btc, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xbb }, 0, .long }, + .{ .btc, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .none }, + .{ .btc, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .none }, + .{ .btc, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .long }, + + .{ .btr, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb3 }, 0, .none }, + .{ .btr, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb3 }, 0, .none }, + .{ .btr, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb3 }, 0, .long }, + .{ .btr, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .none }, + .{ .btr, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .none }, + .{ .btr, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .long }, + + .{ .bts, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xab }, 0, .none }, + .{ .bts, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xab }, 0, .none }, + .{ .bts, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xab }, 0, .long }, + .{ .bts, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .none }, + .{ .bts, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .none }, + .{ .bts, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .long }, + // This is M encoding according to Intel, but D makes more sense here. .{ .call, .d, .rel32, .none, .none, .none, &.{ 0xe8 }, 0, .none }, .{ .call, .m, .rm64, .none, .none, .none, &.{ 0xff }, 2, .none }, diff --git a/src/codegen.zig b/src/codegen.zig index a91795841c..c48200e845 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -608,7 +608,6 @@ pub fn generateSymbol( const payload_type = typed_value.ty.optionalChild(&opt_buf); const is_pl = !typed_value.val.isNull(); const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow; - const offset = abi_size - (math.cast(usize, payload_type.abiSize(target)) orelse return error.Overflow); if (!payload_type.hasRuntimeBits()) { try code.writer().writeByteNTimes(@boolToInt(is_pl), abi_size); @@ -639,8 +638,8 @@ pub fn generateSymbol( return Result.ok; } + const padding = abi_size - (math.cast(usize, payload_type.abiSize(target)) orelse return error.Overflow) - 1; const value = if (typed_value.val.castTag(.opt_payload)) |payload| payload.data else Value.initTag(.undef); - try code.writer().writeByteNTimes(@boolToInt(is_pl), offset); switch (try generateSymbol(bin_file, src_loc, .{ .ty = payload_type, .val = value, @@ -648,6 +647,8 @@ pub fn generateSymbol( .ok => {}, .fail => |em| return Result{ .fail = em }, } + try code.writer().writeByte(@boolToInt(is_pl)); + try code.writer().writeByteNTimes(0, padding); return Result.ok; }, diff --git a/test/behavior/bugs/12984.zig b/test/behavior/bugs/12984.zig index fec32947c9..75f2747eda 100644 --- a/test/behavior/bugs/12984.zig +++ b/test/behavior/bugs/12984.zig @@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void); test "simple test" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var c: CustomDraw = undefined; _ = c; diff --git a/test/behavior/bugs/13785.zig b/test/behavior/bugs/13785.zig index d0cced6a79..463cdbec68 100644 --- a/test/behavior/bugs/13785.zig +++ b/test/behavior/bugs/13785.zig @@ -3,7 +3,6 @@ const std = @import("std"); const S = packed struct { a: u0 = 0 }; test { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/call.zig b/test/behavior/call.zig index b51a459932..ab947f69dd 100644 --- a/test/behavior/call.zig +++ b/test/behavior/call.zig @@ -329,7 +329,6 @@ test "inline call preserves tail call" { test "inline call doesn't re-evaluate non generic struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn foo(f: struct { a: u8, b: u8 }) !void { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 275533d6ec..e601385bca 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1206,7 +1206,6 @@ fn cast128Float(x: u128) f128 { test "implicit cast from *[N]T to ?[*]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var x: ?[*]u16 = null; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 294b4ac2eb..8119a10028 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -451,7 +451,6 @@ test "optional error set is the same size as error set" { } test "nested catch" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 6632cdd5c2..948629038b 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -130,7 +130,6 @@ test "if peer expressions inferred optional type" { } test "if-else expression with runtime condition result location is inferred optional" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/null.zig b/test/behavior/null.zig index c78a995833..6ef51cf3bd 100644 --- a/test/behavior/null.zig +++ b/test/behavior/null.zig @@ -29,7 +29,6 @@ test "optional type" { } test "test maybe object and get a pointer to the inner value" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -138,7 +137,6 @@ test "optional pointer to 0 bit type null value at runtime" { } test "if var maybe pointer" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index bbcc5b3ce6..95b39f2170 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -91,7 +91,6 @@ test "address of unwrap optional" { test "nested optional field in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S2 = struct { @@ -109,7 +108,6 @@ test "nested optional field in struct" { test "equality compare optional with non-optional" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO try test_cmp_optional_non_optional(); @@ -227,7 +225,6 @@ test "assigning to an unwrapped optional field in an inline loop" { } test "coerce an anon struct literal to optional struct" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -247,7 +244,6 @@ test "coerce an anon struct literal to optional struct" { } test "0-bit child type coerced to optional return ptr result location" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -299,7 +295,6 @@ test "0-bit child type coerced to optional" { } test "array of optional unaligned types" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -336,7 +331,6 @@ test "array of optional unaligned types" { } test "optional pointer to zero bit optional payload" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -450,7 +444,6 @@ test "Optional slice size is optimized" { test "peer type resolution in nested if expressions" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const Thing = struct { n: i32 }; var a = false; diff --git a/test/behavior/ptrcast.zig b/test/behavior/ptrcast.zig index 845ea3751e..becdee6b05 100644 --- a/test/behavior/ptrcast.zig +++ b/test/behavior/ptrcast.zig @@ -18,7 +18,6 @@ fn testReinterpretBytesAsInteger() !void { } test "reinterpret an array over multiple elements, with no well-defined layout" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 2a1acebc0f..b250b5b087 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1149,7 +1149,6 @@ test "anon init through error unions and optionals" { } test "anon init through optional" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -1456,7 +1455,6 @@ test "struct has only one reference" { test "no dependency loop on pointer to optional struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { const A = struct { b: B }; @@ -1509,7 +1507,6 @@ test "no dependency loop on optional field wrapped in generic function" { } test "optional field init with tuple" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index 79db21424e..3f557bc40e 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -263,7 +263,6 @@ test "initializing anon struct with mixed comptime-runtime fields" { test "tuple in tuple passed to generic function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { @@ -283,7 +282,6 @@ test "tuple in tuple passed to generic function" { test "coerce tuple to tuple" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const T = std.meta.Tuple(&.{u8}); @@ -298,7 +296,6 @@ test "coerce tuple to tuple" { test "tuple type with void field" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const T = std.meta.Tuple(&[_]type{void}); const x = T{{}}; @@ -335,7 +332,6 @@ test "zero sized struct in tuple handled correctly" { test "tuple type with void field and a runtime field" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const T = std.meta.Tuple(&[_]type{ usize, void }); var t: T = .{ 5, {} }; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 9b49f8bf47..3b040fcba9 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1227,7 +1227,6 @@ test "union tag is set when initiated as a temporary value at runtime" { } test "extern union most-aligned field is smaller" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 956aa30f7b..fc3c6e85d8 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -341,7 +341,6 @@ test "else continue outer while" { } test "try terminating an infinite loop" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO From 958c8e1ce97671bcd7dc5b2dd9ddc1b87d0d1196 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 08:26:05 -0400 Subject: [PATCH 057/216] x86_64: implement @popCount for older processors This fixes the behavior tests when compiled for baseline. --- src/arch/x86_64/CodeGen.zig | 105 ++++++++++++++++++++++++++++++++---- src/arch/x86_64/bits.zig | 1 + 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f788dbd531..cbc645eb9d 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2771,29 +2771,112 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result = result: { + const result: MCValue = result: { if (self.liveness.isUnused(inst)) break :result .dead; - const op_ty = self.air.typeOf(ty_op.operand); + const src_ty = self.air.typeOf(ty_op.operand); + const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); + const src_mcv = try self.resolveInst(ty_op.operand); if (Target.x86.featureSetHas(self.target.cpu.features, .popcnt)) { - const op_mcv = try self.resolveInst(ty_op.operand); - const mat_op_mcv = switch (op_mcv) { - .immediate => MCValue{ .register = try self.copyToTmpRegister(op_ty, op_mcv) }, - else => op_mcv, + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, + else => src_mcv, }; - const mat_op_lock = switch (mat_op_mcv) { + const mat_src_lock = switch (mat_src_mcv) { .register => |reg| self.register_manager.lockReg(reg), else => null, }; - defer if (mat_op_lock) |lock| self.register_manager.unlockReg(lock); + defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); - const dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, gp) }; - try self.genBinOpMir(.popcnt, op_ty, dst_mcv, mat_op_mcv); + const dst_mcv: MCValue = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + .{ .register = try self.register_manager.allocReg(inst, gp) }; + + const popcnt_ty = if (src_abi_size > 1) src_ty else Type.u16; + try self.genBinOpMir(.popcnt, popcnt_ty, dst_mcv, mat_src_mcv); break :result dst_mcv; } - return self.fail("TODO implement airPopcount for {}", .{op_ty.fmt(self.bin_file.options.module.?)}); + const mask = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - src_abi_size * 8); + const imm_0_1 = Immediate.u(mask / 0b1_1); + const imm_00_11 = Immediate.u(mask / 0b01_01); + const imm_0000_1111 = Immediate.u(mask / 0b0001_0001); + const imm_0000_0001 = Immediate.u(mask / 0b1111_1111); + + const tmp_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv.register + else + try self.copyToTmpRegister(src_ty, src_mcv); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); + + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + { + const dst = registerAlias(dst_reg, src_abi_size); + const tmp = registerAlias(tmp_reg, src_abi_size); + const imm = if (src_abi_size > 4) + try self.register_manager.allocReg(null, gp) + else + undefined; + + // tmp = operand + try self.asmRegisterRegister(.mov, dst, tmp); + // dst = operand + try self.asmRegisterImmediate(.shr, tmp, Immediate.u(1)); + // tmp = operand >> 1 + if (src_abi_size > 4) { + try self.asmRegisterImmediate(.mov, imm, imm_0_1); + try self.asmRegisterRegister(.@"and", tmp, imm); + } else try self.asmRegisterImmediate(.@"and", tmp, imm_0_1); + // tmp = (operand >> 1) & 0x55...55 + try self.asmRegisterRegister(.sub, dst, tmp); + // dst = temp1 = operand - ((operand >> 1) & 0x55...55) + try self.asmRegisterRegister(.mov, tmp, dst); + // tmp = temp1 + try self.asmRegisterImmediate(.shr, dst, Immediate.u(2)); + // dst = temp1 >> 2 + if (src_abi_size > 4) { + try self.asmRegisterImmediate(.mov, imm, imm_00_11); + try self.asmRegisterRegister(.@"and", tmp, imm); + try self.asmRegisterRegister(.@"and", dst, imm); + } else { + try self.asmRegisterImmediate(.@"and", tmp, imm_00_11); + try self.asmRegisterImmediate(.@"and", dst, imm_00_11); + } + // tmp = temp1 & 0x33...33 + // dst = (temp1 >> 2) & 0x33...33 + try self.asmRegisterRegister(.add, tmp, dst); + // tmp = temp2 = (temp1 & 0x33...33) + ((temp1 >> 2) & 0x33...33) + try self.asmRegisterRegister(.mov, dst, tmp); + // dst = temp2 + try self.asmRegisterImmediate(.shr, tmp, Immediate.u(4)); + // tmp = temp2 >> 4 + try self.asmRegisterRegister(.add, dst, tmp); + // dst = temp2 + (temp2 >> 4) + if (src_abi_size > 4) { + try self.asmRegisterImmediate(.mov, imm, imm_0000_1111); + try self.asmRegisterImmediate(.mov, tmp, imm_0000_0001); + try self.asmRegisterRegister(.@"and", dst, imm); + try self.asmRegisterRegister(.imul, dst, tmp); + } else { + try self.asmRegisterImmediate(.@"and", dst, imm_0000_1111); + if (src_abi_size > 1) { + try self.asmRegisterRegisterImmediate(.imul, dst, dst, imm_0000_0001); + } + } + // dst = temp3 = (temp2 + (temp2 >> 4)) & 0x0f...0f + // dst = temp3 * 0x01...01 + if (src_abi_size > 1) { + try self.asmRegisterImmediate(.shr, dst, Immediate.u((src_abi_size - 1) * 8)); + } + // dst = (temp3 * 0x01...01) >> (bits - 8) + } + break :result .{ .register = dst_reg }; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index 48a3c64093..250eedeafc 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -476,6 +476,7 @@ pub const Memory = union(enum) { base: ?Register = null, scale_index: ?ScaleIndex = null, }) Memory { + if (args.scale_index) |si| assert(std.math.isPowerOfTwo(si.scale)); return .{ .sib = .{ .base = args.base, .disp = args.disp, From 6c453dd806d9a0207b1f1e64adfc38eca0c38f16 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 09:43:07 -0400 Subject: [PATCH 058/216] x86_64: implement some slice ops --- src/arch/x86_64/CodeGen.zig | 68 +++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index cbc645eb9d..8e1beed798 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2089,9 +2089,12 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { defer self.register_manager.unlockReg(src_lock); const dst_ty = self.air.typeOfIndex(inst); - const dst_reg = try self.register_manager.allocReg(inst, gp); - const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); - defer self.register_manager.unlockReg(dst_lock); + const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_reg + else + try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); const eu_ty = src_ty.childType(); const pl_ty = eu_ty.errorUnionPayload(); @@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { if (self.liveness.isUnused(inst)) break :result .dead; const dst_ty = self.air.typeOfIndex(inst); - const dst_reg = try self.register_manager.allocReg(inst, gp); - const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); - defer self.register_manager.unlockReg(dst_lock); + const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_reg + else + try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); @@ -2309,19 +2315,53 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const src_ty = self.air.typeOf(ty_op.operand); + const src_mcv = try self.resolveInst(ty_op.operand); + const src_reg = switch (src_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(src_ty, src_mcv), + }; + const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); + defer self.register_manager.unlockReg(src_lock); + + const dst_ty = self.air.typeOfIndex(inst); + const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_reg + else + try self.register_manager.allocReg(inst, gp); + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); + try self.asmRegisterMemory( + .lea, + registerAlias(dst_reg, dst_abi_size), + Memory.sib(.qword, .{ + .base = src_reg, + .disp = @divExact(self.target.cpu.arch.ptrBitWidth(), 8), + }), + ); + break :result .{ .register = dst_reg }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const dst_ty = self.air.typeOfIndex(inst); + const opt_mcv = try self.resolveInst(ty_op.operand); + + break :result if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) + opt_mcv + else + try self.copyToRegisterWithInstTracking(inst, dst_ty, opt_mcv); + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } From 3f4569bf187bfe296323aee6fbb59ab374041243 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 19 Mar 2023 22:43:59 -0400 Subject: [PATCH 059/216] codegen: fix backend breakage due to optional layout change --- src/arch/aarch64/CodeGen.zig | 82 ++++++++++++++++++++---------------- src/arch/wasm/CodeGen.zig | 49 ++++++++------------- test/behavior/error.zig | 1 + 3 files changed, 65 insertions(+), 67 deletions(-) diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index e20cf900af..e2e2ce9ead 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -3011,41 +3011,16 @@ fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: return MCValue{ .register = reg }; } - const offset = @intCast(u32, optional_ty.abiSize(self.target.*) - payload_ty.abiSize(self.target.*)); switch (mcv) { - .register => |source_reg| { + .register => { // TODO should we reuse the operand here? const raw_reg = try self.register_manager.allocReg(inst, gp); const dest_reg = raw_reg.toX(); - const shift = @intCast(u6, offset * 8); - if (shift == 0) { - try self.genSetReg(payload_ty, dest_reg, mcv); - } else { - _ = try self.addInst(.{ - .tag = if (payload_ty.isSignedInt()) - Mir.Inst.Tag.asr_immediate - else - Mir.Inst.Tag.lsr_immediate, - .data = .{ .rr_shift = .{ - .rd = dest_reg, - .rn = source_reg.toX(), - .shift = shift, - } }, - }); - } - + try self.genSetReg(payload_ty, dest_reg, mcv); return MCValue{ .register = self.registerAlias(dest_reg, payload_ty) }; }, - .stack_argument_offset => |off| { - return MCValue{ .stack_argument_offset = off + offset }; - }, - .stack_offset => |off| { - return MCValue{ .stack_offset = off - offset }; - }, - .memory => |addr| { - return MCValue{ .memory = addr + offset }; - }, + .stack_argument_offset, .stack_offset, .memory => return mcv, else => unreachable, // invalid MCValue for an error union } } @@ -3289,12 +3264,11 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*)); const optional_abi_align = optional_ty.abiAlignment(self.target.*); - const payload_abi_size = @intCast(u32, payload_ty.abiSize(self.target.*)); - const offset = optional_abi_size - payload_abi_size; + const offset = @intCast(u32, payload_ty.abiSize(self.target.*)); const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst); - try self.genSetStack(Type.bool, stack_offset, .{ .immediate = 1 }); - try self.genSetStack(payload_ty, stack_offset - @intCast(u32, offset), operand); + try self.genSetStack(payload_ty, stack_offset, operand); + try self.genSetStack(Type.bool, stack_offset - offset, .{ .immediate = 1 }); break :result MCValue{ .stack_offset = stack_offset }; }; @@ -4834,13 +4808,49 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { } fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { - const sentinel_ty: Type = if (!operand_ty.isPtrLikeOptional()) blk: { + const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional()) blk: { var buf: Type.Payload.ElemType = undefined; const payload_ty = operand_ty.optionalChild(&buf); - break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime()) Type.bool else operand_ty; - } else operand_ty; + if (!payload_ty.hasRuntimeBitsIgnoreComptime()) + break :blk .{ .ty = operand_ty, .bind = operand_bind }; + + const offset = @intCast(u32, payload_ty.abiSize(self.target.*)); + const operand_mcv = try operand_bind.resolveToMcv(self); + const new_mcv: MCValue = switch (operand_mcv) { + .register => |source_reg| new: { + // TODO should we reuse the operand here? + const raw_reg = try self.register_manager.allocReg(null, gp); + const dest_reg = raw_reg.toX(); + + const shift = @intCast(u6, offset * 8); + if (shift == 0) { + try self.genSetReg(payload_ty, dest_reg, operand_mcv); + } else { + _ = try self.addInst(.{ + .tag = if (payload_ty.isSignedInt()) + Mir.Inst.Tag.asr_immediate + else + Mir.Inst.Tag.lsr_immediate, + .data = .{ .rr_shift = .{ + .rd = dest_reg, + .rn = source_reg.toX(), + .shift = shift, + } }, + }); + } + + break :new .{ .register = self.registerAlias(dest_reg, payload_ty) }; + }, + .stack_argument_offset => |off| .{ .stack_argument_offset = off + offset }, + .stack_offset => |off| .{ .stack_offset = off - offset }, + .memory => |addr| .{ .memory = addr + offset }, + else => unreachable, // invalid MCValue for an optional + }; + + break :blk .{ .ty = Type.bool, .bind = .{ .mcv = new_mcv } }; + } else .{ .ty = operand_ty, .bind = operand_bind }; const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; - return self.cmp(operand_bind, imm_bind, sentinel_ty, .eq); + return self.cmp(sentinel.bind, imm_bind, sentinel.ty, .eq); } fn isNonNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index c05f07a602..9af66eb40c 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -2715,20 +2715,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, ptr_child_ty: Type) InnerError }, .opt_payload_ptr => { const payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; - const parent_ptr = try func.lowerParentPtr(payload_ptr.container_ptr, payload_ptr.container_ty); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = payload_ptr.container_ty.optionalChild(&buf); - if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.optionalReprIsPayload()) { - return parent_ptr; - } - - const abi_size = payload_ptr.container_ty.abiSize(func.target); - const offset = abi_size - payload_ty.abiSize(func.target); - - return WValue{ .memory_offset = .{ - .pointer = parent_ptr.memory, - .offset = @intCast(u32, offset), - } }; + return func.lowerParentPtr(payload_ptr.container_ptr, payload_ptr.container_ty); }, else => |tag| return func.fail("TODO: Implement lowerParentPtr for tag: {}", .{tag}), } @@ -2889,7 +2876,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { } } else { const is_pl = val.tag() == .opt_payload; - return WValue{ .imm32 = if (is_pl) @as(u32, 1) else 0 }; + return WValue{ .imm32 = @boolToInt(is_pl) }; }, .Struct => { const struct_obj = ty.castTag(.@"struct").?.data; @@ -3882,7 +3869,11 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod // When payload is zero-bits, we can treat operand as a value, rather than // a pointer to the stack value if (payload_ty.hasRuntimeBitsIgnoreComptime()) { - try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset(), .alignment = 1 }); + const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse { + const module = func.bin_file.base.options.module.?; + return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(module)}); + }; + try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 }); } } else if (payload_ty.isSlice()) { switch (func.arch()) { @@ -3911,13 +3902,11 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const operand = try func.resolveInst(ty_op.operand); if (opt_ty.optionalReprIsPayload()) break :result func.reuseOperand(ty_op.operand, operand); - const offset = opt_ty.abiSize(func.target) - payload_ty.abiSize(func.target); - if (isByRef(payload_ty, func.target)) { - break :result try func.buildPointerOffset(operand, offset, .new); + break :result try func.buildPointerOffset(operand, 0, .new); } - const payload = try func.load(operand, payload_ty, @intCast(u32, offset)); + const payload = try func.load(operand, payload_ty, 0); break :result try payload.toLocal(func, payload_ty); }; func.finishAir(inst, result, &.{ty_op.operand}); @@ -3936,8 +3925,7 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { break :result func.reuseOperand(ty_op.operand, operand); } - const offset = opt_ty.abiSize(func.target) - payload_ty.abiSize(func.target); - break :result try func.buildPointerOffset(operand, offset, .new); + break :result try func.buildPointerOffset(operand, 0, .new); }; func.finishAir(inst, result, &.{ty_op.operand}); } @@ -3956,16 +3944,16 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi return func.finishAir(inst, operand, &.{ty_op.operand}); } - const offset = std.math.cast(u32, opt_ty.abiSize(func.target) - payload_ty.abiSize(func.target)) orelse { + const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse { const module = func.bin_file.base.options.module.?; return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(module)}); }; try func.emitWValue(operand); try func.addImm32(1); - try func.addMemArg(.i32_store8, .{ .offset = operand.offset(), .alignment = 1 }); + try func.addMemArg(.i32_store8, .{ .offset = operand.offset() + offset, .alignment = 1 }); - const result = try func.buildPointerOffset(operand, offset, .new); + const result = try func.buildPointerOffset(operand, 0, .new); return func.finishAir(inst, result, &.{ty_op.operand}); } @@ -3988,7 +3976,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { if (op_ty.optionalReprIsPayload()) { break :result func.reuseOperand(ty_op.operand, operand); } - const offset = std.math.cast(u32, op_ty.abiSize(func.target) - payload_ty.abiSize(func.target)) orelse { + const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse { const module = func.bin_file.base.options.module.?; return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(module)}); }; @@ -3997,9 +3985,9 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const result_ptr = try func.allocStack(op_ty); try func.emitWValue(result_ptr); try func.addImm32(1); - try func.addMemArg(.i32_store8, .{ .offset = result_ptr.offset(), .alignment = 1 }); + try func.addMemArg(.i32_store8, .{ .offset = result_ptr.offset() + offset, .alignment = 1 }); - const payload_ptr = try func.buildPointerOffset(result_ptr, offset, .new); + const payload_ptr = try func.buildPointerOffset(result_ptr, 0, .new); try func.store(payload_ptr, operand, payload_ty, 0); break :result result_ptr; }; @@ -4719,7 +4707,6 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: assert(op == .eq or op == .neq); var buf: Type.Payload.ElemType = undefined; const payload_ty = operand_ty.optionalChild(&buf); - const offset = @intCast(u32, operand_ty.abiSize(func.target) - payload_ty.abiSize(func.target)); // We store the final result in here that will be validated // if the optional is truly equal. @@ -4732,8 +4719,8 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: try func.addTag(.i32_ne); // inverse so we can exit early try func.addLabel(.br_if, 0); - _ = try func.load(lhs, payload_ty, offset); - _ = try func.load(rhs, payload_ty, offset); + _ = try func.load(lhs, payload_ty, 0); + _ = try func.load(rhs, payload_ty, 0); const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, func.target) }); try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); try func.addLabel(.br_if, 0); diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 8119a10028..a708971a49 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -874,6 +874,7 @@ test "field access of anyerror results in smaller error set" { } test "optional error union return type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { From f316cb29cc094c37be191f1eb72ee70eb0dc99ee Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 20 Mar 2023 06:22:38 -0400 Subject: [PATCH 060/216] x86_64: implement atomic and fence ops --- src/arch/x86_64/CodeGen.zig | 337 +++++++++++++++++++++-------- src/arch/x86_64/Emit.zig | 105 +++++++-- src/arch/x86_64/Encoding.zig | 15 +- src/arch/x86_64/Mir.zig | 42 +++- src/arch/x86_64/encoder.zig | 3 +- src/arch/x86_64/encodings.zig | 38 ++++ src/register_manager.zig | 40 ++-- test/behavior/atomics.zig | 7 - test/behavior/bugs/13068.zig | 1 - test/behavior/cast.zig | 1 - test/behavior/merge_error_sets.zig | 1 - test/behavior/switch.zig | 1 - 12 files changed, 436 insertions(+), 155 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 8e1beed798..f32eb84afc 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -410,6 +410,25 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { }); } +fn asmSetccMemory(self: *Self, m: Memory, cc: bits.Condition) !void { + _ = try self.addInst(.{ + .tag = .setcc, + .ops = switch (m) { + .sib => .m_sib_cc, + .rip => .m_rip_cc, + else => unreachable, + }, + .data = .{ .x_cc = .{ + .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + }, + .cc = cc, + } }, + }); +} + fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bits.Condition) !void { _ = try self.addInst(.{ .tag = .cmovcc, @@ -890,7 +909,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .breakpoint => try self.airBreakpoint(), .ret_addr => try self.airRetAddr(inst), .frame_addr => try self.airFrameAddress(inst), - .fence => try self.airFence(), + .fence => try self.airFence(inst), .cond_br => try self.airCondBr(inst), .dbg_stmt => try self.airDbgStmt(inst), .fptrunc => try self.airFptrunc(inst), @@ -1880,13 +1899,17 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { switch (opt_mcv) { .register => |reg| try self.truncateRegister(pl_ty, reg), + .register_overflow => |ro| try self.truncateRegister(pl_ty, ro.reg), else => {}, } break :result opt_mcv; } const pl_mcv = try self.allocRegOrMem(inst, true); - try self.setRegOrMem(pl_ty, pl_mcv, opt_mcv); + try self.setRegOrMem(pl_ty, pl_mcv, switch (opt_mcv) { + else => opt_mcv, + .register_overflow => |ro| .{ .register = ro.reg }, + }); break :result pl_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -1969,8 +1992,14 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { }, .register => |reg| { // TODO reuse operand - const lock = self.register_manager.lockRegAssumeUnused(reg); - defer self.register_manager.unlockReg(lock); + self.register_manager.getRegAssumeFree(.rcx, null); + const rcx_lock = + if (err_off > 0) self.register_manager.lockRegAssumeUnused(.rcx) else null; + defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); + + const eu_lock = self.register_manager.lockReg(reg); + defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); + const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand); if (err_off > 0) { const shift = @intCast(u6, err_off * 8); @@ -2018,8 +2047,14 @@ fn genUnwrapErrorUnionPayloadMir( }, .register => |reg| { // TODO reuse operand - const lock = self.register_manager.lockRegAssumeUnused(reg); - defer self.register_manager.unlockReg(lock); + self.register_manager.getRegAssumeFree(.rcx, null); + const rcx_lock = + if (payload_off > 0) self.register_manager.lockRegAssumeUnused(.rcx) else null; + defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); + + const eu_lock = self.register_manager.lockReg(reg); + defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); + const result_reg: Register = if (maybe_inst) |inst| (try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union)).register else @@ -3129,7 +3164,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .none => unreachable, .dead => unreachable, .unreach => unreachable, - .eflags => unreachable, + .eflags => |cc| { + try self.asmSetccMemory(Memory.sib( + Memory.PtrSize.fromSize(abi_size), + .{ .base = reg.to64(), .disp = 0 }, + ), cc); + }, .undef => { if (!self.wantSafety()) return; // The already existing value will do just fine. switch (abi_size) { @@ -3598,8 +3638,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi }, else => {}, } - assert(self.register_manager.isRegFree(.rcx)); - try self.register_manager.getReg(.rcx, null); + self.register_manager.getRegAssumeFree(.rcx, null); try self.genSetReg(Type.u8, .rcx, shift); } @@ -3639,8 +3678,7 @@ fn genShiftBinOp( }; defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); - assert(self.register_manager.isRegFree(.rcx)); - try self.register_manager.getReg(.rcx, null); + self.register_manager.getRegAssumeFree(.rcx, null); const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx); defer self.register_manager.unlockReg(rcx_lock); @@ -4230,7 +4268,10 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu .base = .rbp, .disp = -off, }), - Immediate.u(@intCast(u32, imm)), + if (math.cast(i32, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u32, imm)), ); }, 64 => { @@ -4506,9 +4547,14 @@ fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ .none, .none, .none }); } -fn airFence(self: *Self) !void { - return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch}); - //return self.finishAirBookkeeping(); +fn airFence(self: *Self, inst: Air.Inst.Index) !void { + const order = self.air.instructions.items(.data)[inst].fence; + switch (order) { + .Unordered, .Monotonic => unreachable, + .Acquire, .Release, .AcqRel => {}, + .SeqCst => try self.asmOpOnly(.mfence), + } + return self.finishAirBookkeeping(); } fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void { @@ -5075,6 +5121,11 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { } fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { + switch (opt_mcv) { + .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() }, + else => {}, + } + try self.spillEflagsIfOccupied(); self.eflags_inst = inst; @@ -5196,8 +5247,13 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! try self.genBinOpMir(.cmp, Type.anyerror, .{ .stack_offset = offset }, .{ .immediate = 0 }); }, .register => |reg| { - const maybe_lock = self.register_manager.lockReg(reg); - defer if (maybe_lock) |lock| self.register_manager.unlockReg(lock); + self.register_manager.getRegAssumeFree(.rcx, null); + const rcx_lock = if (err_off > 0) self.register_manager.lockRegAssumeUnused(.rcx) else null; + defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); + + const eu_lock = self.register_manager.lockReg(reg); + defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); + const tmp_reg = try self.copyToTmpRegister(ty, operand); if (err_off > 0) { const shift = @intCast(u6, err_off * 8); @@ -5389,69 +5445,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ .none, .none, .none }); } -fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u32 { - const abi_size = @intCast(u32, ty.abiSize(self.target.*)); - switch (condition) { - .none => unreachable, - .undef => unreachable, - .dead, .unreach => unreachable, - .eflags => unreachable, - .register => |cond_reg| { - try self.spillEflagsIfOccupied(); - - const cond_reg_lock = self.register_manager.lockReg(cond_reg); - defer if (cond_reg_lock) |lock| self.register_manager.unlockReg(lock); - - switch (case) { - .none => unreachable, - .undef => unreachable, - .dead, .unreach => unreachable, - .immediate => |imm| try self.asmRegisterImmediate( - .xor, - registerAlias(cond_reg, abi_size), - Immediate.u(imm), - ), - .register => |reg| try self.asmRegisterRegister( - .xor, - registerAlias(cond_reg, abi_size), - registerAlias(reg, abi_size), - ), - .stack_offset => { - if (abi_size <= 8) { - const reg = try self.copyToTmpRegister(ty, case); - return self.genCondSwitchMir(ty, condition, .{ .register = reg }); - } - - return self.fail("TODO implement switch mir when case is stack offset with abi larger than 8 bytes", .{}); - }, - else => { - return self.fail("TODO implement switch mir when case is {}", .{case}); - }, - } - - const aliased_reg = registerAlias(cond_reg, abi_size); - try self.asmRegisterRegister(.@"test", aliased_reg, aliased_reg); - return self.asmJccReloc(undefined, .ne); - }, - .stack_offset => { - try self.spillEflagsIfOccupied(); - - if (abi_size <= 8) { - const reg = try self.copyToTmpRegister(ty, condition); - const reg_lock = self.register_manager.lockRegAssumeUnused(reg); - defer self.register_manager.unlockReg(reg_lock); - return self.genCondSwitchMir(ty, .{ .register = reg }, case); - } - - return self.fail("TODO implement switch mir when condition is stack offset with abi larger than 8 bytes", .{}); - }, - else => { - return self.fail("TODO implemenent switch mir when condition is {}", .{condition}); - }, - } - return 0; // TODO -} - fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { const pl_op = self.air.instructions.items(.data)[inst].pl_op; const condition = try self.resolveInst(pl_op.operand); @@ -5496,8 +5489,10 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { defer self.gpa.free(relocs); for (items, relocs) |item, *reloc| { + try self.spillEflagsIfOccupied(); const item_mcv = try self.resolveInst(item); - reloc.* = try self.genCondSwitchMir(condition_ty, condition, item_mcv); + try self.genBinOpMir(.cmp, condition_ty, condition, item_mcv); + reloc.* = try self.asmJccReloc(undefined, .ne); } // Capture the state of register and stack allocation state so that we can revert to it. @@ -6624,26 +6619,184 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; - const extra = self.air.extraData(Air.Block, ty_pl.payload); - _ = extra; - return self.fail("TODO implement x86 airCmpxchg", .{}); - // return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); + const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; + + const ptr_ty = self.air.typeOf(extra.ptr); + const ptr_mcv = try self.resolveInst(extra.ptr); + const val_ty = self.air.typeOf(extra.expected_value); + + const exp_mcv = try self.resolveInst(extra.expected_value); + try self.genSetReg(val_ty, .rax, exp_mcv); + const rax_lock = self.register_manager.lockRegAssumeUnused(.rax); + defer self.register_manager.unlockReg(rax_lock); + + const new_mcv = try self.resolveInst(extra.new_value); + const new_reg = try self.copyToTmpRegister(val_ty, new_mcv); + const new_lock = self.register_manager.lockRegAssumeUnused(new_reg); + defer self.register_manager.unlockReg(new_lock); + + const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); + const ptr_size = Memory.PtrSize.fromSize(val_abi_size); + const ptr_mem: Memory = switch (ptr_mcv) { + .register => |reg| Memory.sib(ptr_size, .{ .base = reg, .disp = 0 }), + .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }), + else => Memory.sib(ptr_size, .{ + .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv), + .disp = 0, + }), + }; + const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null; + defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); + + try self.spillEflagsIfOccupied(); + _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{ + .r1 = new_reg, + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } } }); + + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + self.eflags_inst = inst; + break :result .{ .register_overflow = .{ .reg = .rax, .eflags = .ne } }; + }; + return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); +} + +fn atomicOp( + self: *Self, + dst_reg: Register, + ptr_mcv: MCValue, + val_mcv: MCValue, + ptr_ty: Type, + val_ty: Type, + unused: bool, + op: ?std.builtin.AtomicRmwOp, + order: std.builtin.AtomicOrder, +) InnerError!void { + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + + const ptr_lock = switch (ptr_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); + + const val_lock = switch (val_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (val_lock) |lock| self.register_manager.unlockReg(lock); + + const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); + const ptr_size = Memory.PtrSize.fromSize(val_abi_size); + const ptr_mem: Memory = switch (ptr_mcv) { + .register => |reg| Memory.sib(ptr_size, .{ .base = reg, .disp = 0 }), + .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }), + else => Memory.sib(ptr_size, .{ + .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv), + .disp = 0, + }), + }; + const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null; + defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); + + try self.genSetReg(val_ty, dst_reg, val_mcv); + + const need_loop = val_ty.isRuntimeFloat() or if (op) |rmw| switch (rmw) { + .Xchg, .Add, .Sub => false, + .And, .Or, .Xor => !unused, + .Nand, .Max, .Min => true, + } else false; + if (!need_loop) { + const tag: Mir.Inst.Tag = if (op) |rmw| switch (rmw) { + .Xchg => if (unused) .mov else .xchg, + .Add => if (unused) .add else .xadd, + .Sub => if (unused) .sub else .xadd, + .And => .@"and", + .Or => .@"or", + .Xor => .xor, + else => unreachable, + } else switch (order) { + .Unordered, .Monotonic, .Release, .AcqRel => .mov, + .Acquire => unreachable, + .SeqCst => .xchg, + }; + if (op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) { + try self.genUnOpMir(.neg, val_ty, .{ .register = dst_reg }); + } + _ = try self.addInst(.{ .tag = tag, .ops = switch (tag) { + .mov, .xchg => .mr_sib, + .xadd, .add, .sub, .@"and", .@"or", .xor => .lock_mr_sib, + else => unreachable, + }, .data = .{ .rx = .{ + .r1 = registerAlias(dst_reg, val_abi_size), + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } } }); + return; + } + + return self.fail("TODO implement x86 atomic loop", .{}); } fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void { - _ = inst; - return self.fail("TODO implement x86 airAtomicRmw", .{}); + const pl_op = self.air.instructions.items(.data)[inst].pl_op; + const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; + + const dst_reg = try self.register_manager.allocReg(inst, gp); + + const ptr_ty = self.air.typeOf(pl_op.operand); + const ptr_mcv = try self.resolveInst(pl_op.operand); + + const val_ty = self.air.typeOf(extra.operand); + const val_mcv = try self.resolveInst(extra.operand); + + const unused = self.liveness.isUnused(inst); + try self.atomicOp(dst_reg, ptr_mcv, val_mcv, ptr_ty, val_ty, unused, extra.op(), extra.ordering()); + const result: MCValue = if (unused) .dead else .{ .register = dst_reg }; + return self.finishAir(inst, result, .{ pl_op.operand, extra.operand, .none }); } fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void { - _ = inst; - return self.fail("TODO implement airAtomicLoad for {}", .{self.target.cpu.arch}); + const atomic_load = self.air.instructions.items(.data)[inst].atomic_load; + + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const ptr_ty = self.air.typeOf(atomic_load.ptr); + const ptr_mcv = try self.resolveInst(atomic_load.ptr); + const ptr_lock = switch (ptr_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv = + if (self.reuseOperand(inst, atomic_load.ptr, 0, ptr_mcv)) + ptr_mcv + else + try self.allocRegOrMem(inst, true); + + try self.load(dst_mcv, ptr_mcv, ptr_ty); + break :result dst_mcv; + }; + return self.finishAir(inst, result, .{ atomic_load.ptr, .none, .none }); } fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOrder) !void { - _ = inst; - _ = order; - return self.fail("TODO implement airAtomicStore for {}", .{self.target.cpu.arch}); + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + + const dst_reg = try self.register_manager.allocReg(null, gp); + + const ptr_ty = self.air.typeOf(bin_op.lhs); + const ptr_mcv = try self.resolveInst(bin_op.lhs); + + const val_ty = self.air.typeOf(bin_op.rhs); + const val_mcv = try self.resolveInst(bin_op.rhs); + + try self.atomicOp(dst_reg, ptr_mcv, val_mcv, ptr_ty, val_ty, true, null, order); + return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airMemset(self: *Self, inst: Air.Inst.Index) !void { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 4c63385e6b..9718548736 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -87,6 +87,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .cdq, .cqo, .cmp, + .cmpxchg, .div, .fisttp, .fld, @@ -95,7 +96,9 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .int3, .jmp, .lea, + .lfence, .lzcnt, + .mfence, .mov, .movzx, .mul, @@ -110,6 +113,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .sal, .sar, .sbb, + .sfence, .shl, .shr, .sub, @@ -117,6 +121,8 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .@"test", .tzcnt, .ud2, + .xadd, + .xchg, .xor, .addss, @@ -148,6 +154,8 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .stos, => try emit.mirString(tag, inst), + .cmpxchgb => try emit.mirCmpxchgBytes(inst), + .jmp_reloc => try emit.mirJmpReloc(inst), .call_extern => try emit.mirCallExtern(inst), @@ -214,6 +222,20 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE const ops = emit.mir.instructions.items(.ops)[inst]; const data = emit.mir.instructions.items(.data)[inst]; + const prefix: Instruction.Prefix = switch (ops) { + .lock_m_sib, + .lock_m_rip, + .lock_mi_u_sib, + .lock_mi_u_rip, + .lock_mi_s_sib, + .lock_mi_s_rip, + .lock_mr_sib, + .lock_mr_rip, + .lock_moffs_rax, + => .lock, + else => .none, + }; + var op1: Instruction.Operand = .none; var op2: Instruction.Operand = .none; var op3: Instruction.Operand = .none; @@ -252,35 +274,35 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE op2 = .{ .reg = data.rri.r2 }; op3 = .{ .imm = imm }; }, - .m_sib => { + .m_sib, .lock_m_sib => { const msib = emit.mir.extraData(Mir.MemorySib, data.payload).data; op1 = .{ .mem = Mir.MemorySib.decode(msib) }; }, - .m_rip => { + .m_rip, .lock_m_rip => { const mrip = emit.mir.extraData(Mir.MemoryRip, data.payload).data; op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; }, - .mi_s_sib, .mi_u_sib => { + .mi_s_sib, .mi_u_sib, .lock_mi_s_sib, .lock_mi_u_sib => { const msib = emit.mir.extraData(Mir.MemorySib, data.xi.payload).data; const imm = switch (ops) { - .mi_s_sib => Immediate.s(@bitCast(i32, data.xi.imm)), - .mi_u_sib => Immediate.u(data.xi.imm), + .mi_s_sib, .lock_mi_s_sib => Immediate.s(@bitCast(i32, data.xi.imm)), + .mi_u_sib, .lock_mi_u_sib => Immediate.u(data.xi.imm), else => unreachable, }; op1 = .{ .mem = Mir.MemorySib.decode(msib) }; op2 = .{ .imm = imm }; }, - .mi_u_rip, .mi_s_rip => { + .mi_u_rip, .mi_s_rip, .lock_mi_u_rip, .lock_mi_s_rip => { const mrip = emit.mir.extraData(Mir.MemoryRip, data.xi.payload).data; const imm = switch (ops) { - .mi_s_rip => Immediate.s(@bitCast(i32, data.xi.imm)), - .mi_u_rip => Immediate.u(data.xi.imm), + .mi_s_rip, .lock_mi_s_rip => Immediate.s(@bitCast(i32, data.xi.imm)), + .mi_u_rip, .lock_mi_u_rip => Immediate.u(data.xi.imm), else => unreachable, }; op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; op2 = .{ .imm = imm }; }, - .rm_sib, .mr_sib => { + .rm_sib, .mr_sib, .lock_mr_sib => { const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data; const op_r = .{ .reg = data.rx.r1 }; const op_m = .{ .mem = Mir.MemorySib.decode(msib) }; @@ -289,23 +311,23 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE op1 = op_r; op2 = op_m; }, - .mr_sib => { + .mr_sib, .lock_mr_sib => { op1 = op_m; op2 = op_r; }, else => unreachable, } }, - .rm_rip, .mr_rip => { + .rm_rip, .mr_rip, .lock_mr_rip => { const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data; const op_r = .{ .reg = data.rx.r1 }; const op_m = .{ .mem = Mir.MemoryRip.decode(mrip) }; switch (ops) { - .rm_sib => { + .rm_rip => { op1 = op_r; op2 = op_m; }, - .mr_sib => { + .mr_rip, .lock_mr_rip => { op1 = op_m; op2 = op_r; }, @@ -319,6 +341,7 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE } return emit.encode(mnemonic, .{ + .prefix = prefix, .op1 = op1, .op2 = op2, .op3 = op3, @@ -348,6 +371,39 @@ fn mirString(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!vo } } +fn mirCmpxchgBytes(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { + const ops = emit.mir.instructions.items(.ops)[inst]; + const data = emit.mir.instructions.items(.data)[inst]; + + var op1: Instruction.Operand = .none; + switch (ops) { + .m_sib, .lock_m_sib => { + const sib = emit.mir.extraData(Mir.MemorySib, data.payload).data; + op1 = .{ .mem = Mir.MemorySib.decode(sib) }; + }, + .m_rip, .lock_m_rip => { + const rip = emit.mir.extraData(Mir.MemoryRip, data.payload).data; + op1 = .{ .mem = Mir.MemoryRip.decode(rip) }; + }, + else => unreachable, + } + + const mnemonic: Instruction.Mnemonic = switch (op1.mem.bitSize()) { + 64 => .cmpxchg8b, + 128 => .cmpxchg16b, + else => unreachable, + }; + + return emit.encode(mnemonic, .{ + .prefix = switch (ops) { + .m_sib, .m_rip => .none, + .lock_m_sib, .lock_m_rip => .lock, + else => unreachable, + }, + .op1 = op1, + }); +} + fn mirMovMoffs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const ops = emit.mir.instructions.items(.ops)[inst]; const payload = emit.mir.instructions.items(.data)[inst].payload; @@ -361,8 +417,13 @@ fn mirMovMoffs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { .op2 = .{ .mem = Memory.moffs(seg, offset) }, }); }, - .moffs_rax => { + .moffs_rax, .lock_moffs_rax => { try emit.encode(.mov, .{ + .prefix = switch (ops) { + .moffs_rax => .none, + .lock_moffs_rax => .lock, + else => unreachable, + }, .op1 = .{ .mem = Memory.moffs(seg, offset) }, .op2 = .{ .reg = .rax }, }); @@ -455,6 +516,22 @@ fn mirSetcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { .op1 = .{ .reg = data.r1 }, }); }, + .m_sib_cc => { + const data = emit.mir.instructions.items(.data)[inst].x_cc; + const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data; + const mnemonic = mnemonicFromConditionCode("set", data.cc); + return emit.encode(mnemonic, .{ + .op1 = .{ .mem = Mir.MemorySib.decode(extra) }, + }); + }, + .m_rip_cc => { + const data = emit.mir.instructions.items(.data)[inst].x_cc; + const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data; + const mnemonic = mnemonicFromConditionCode("set", data.cc); + return emit.encode(mnemonic, .{ + .op1 = .{ .mem = Mir.MemoryRip.decode(extra) }, + }); + }, else => unreachable, // TODO } } diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 436202ca3e..03b8abf983 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -314,6 +314,7 @@ pub const Mnemonic = enum { cmovnp, cmovns, cmovnz, cmovo, cmovp, cmovpe, cmovpo, cmovs, cmovz, cmp, cmps, cmpsb, cmpsd, cmpsq, cmpsw, + cmpxchg, cmpxchg8b, cmpxchg16b, cqo, cwd, cwde, div, fisttp, fld, @@ -321,10 +322,10 @@ pub const Mnemonic = enum { ja, jae, jb, jbe, jc, jrcxz, je, jg, jge, jl, jle, jna, jnae, jnb, jnbe, jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz, jmp, - lea, + lea, lfence, lods, lodsb, lodsd, lodsq, lodsw, lzcnt, - mov, + mfence, mov, movs, movsb, movsd, movsq, movsw, movsx, movsxd, movzx, mul, neg, nop, not, @@ -337,10 +338,11 @@ pub const Mnemonic = enum { seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae, setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns, setnz, seto, setp, setpe, setpo, sets, setz, + sfence, stos, stosb, stosd, stosq, stosw, @"test", tzcnt, ud2, - xor, + xadd, xchg, xor, // SSE addss, cmpss, @@ -387,7 +389,7 @@ pub const Op = enum { cl, r8, r16, r32, r64, rm8, rm16, rm32, rm64, - m8, m16, m32, m64, m80, + m8, m16, m32, m64, m80, m128, rel8, rel16, rel32, m, moffs, @@ -436,6 +438,7 @@ pub const Op = enum { 32 => .m32, 64 => .m64, 80 => .m80, + 128 => .m128, else => unreachable, }; }, @@ -473,7 +476,7 @@ pub const Op = enum { .imm32, .imm32s, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32, .imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64, .m80 => 80, - .xmm => 128, + .m128, .xmm => 128, }; } @@ -520,7 +523,7 @@ pub const Op = enum { // zig fmt: off return switch (op) { .rm8, .rm16, .rm32, .rm64, - .m8, .m16, .m32, .m64, .m80, + .m8, .m16, .m32, .m64, .m80, .m128, .m, .xmm_m32, .xmm_m64, => true, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index e7d75e7446..d086b617f5 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -66,6 +66,10 @@ pub const Inst = struct { cqo, /// Logical compare cmp, + /// Compare and exchange + cmpxchg, + /// Compare and exchange bytes + cmpxchgb, /// Unsigned division div, /// Store integer with truncation @@ -82,8 +86,12 @@ pub const Inst = struct { jmp, /// Load effective address lea, + /// Load fence + lfence, /// Count the number of leading zero bits lzcnt, + /// Memory fence + mfence, /// Move mov, /// Move with sign extension @@ -114,6 +122,8 @@ pub const Inst = struct { sar, /// Integer subtraction with borrow sbb, + /// Store fence + sfence, /// Logical shift left shl, /// Logical shift right @@ -128,6 +138,10 @@ pub const Inst = struct { tzcnt, /// Undefined instruction ud2, + /// Exchange and add + xadd, + /// Exchange register/memory with register + xchg, /// Logical exclusive-or xor, @@ -242,10 +256,10 @@ pub const Inst = struct { /// Uses `rri` payload. rri_u, /// Register with condition code (CC). - /// Uses `r_c` payload. + /// Uses `r_cc` payload. r_cc, /// Register, register with condition code (CC). - /// Uses `rr_c` payload. + /// Uses `rr_cc` payload. rr_cc, /// Register, immediate (sign-extended) operands. /// Uses `ri` payload. @@ -283,6 +297,12 @@ pub const Inst = struct { /// Single memory (RIP) operand. /// Uses `payload` with extra data of type `MemoryRip`. m_rip, + /// Single memory (SIB) operand with condition code (CC). + /// Uses `x_cc` with extra data of type `MemorySib`. + m_sib_cc, + /// Single memory (RIP) operand with condition code (CC). + /// Uses `x_cc` with extra data of type `MemoryRip`. + m_rip_cc, /// Memory (SIB), immediate (unsigned) operands. /// Uses `xi` payload with extra data of type `MemorySib`. mi_u_sib, @@ -301,6 +321,12 @@ pub const Inst = struct { /// Memory (RIP), register operands. /// Uses `rx` payload with extra data of type `MemoryRip`. mr_rip, + /// Rax, Memory moffs. + /// Uses `payload` with extra data of type `MemoryMoffs`. + rax_moffs, + /// Memory moffs, rax. + /// Uses `payload` with extra data of type `MemoryMoffs`. + moffs_rax, /// Single memory (SIB) operand with lock prefix. /// Uses `payload` with extra data of type `MemorySib`. lock_m_sib, @@ -325,12 +351,9 @@ pub const Inst = struct { /// Memory (RIP), register operands with lock prefix. /// Uses `rx` payload with extra data of type `MemoryRip`. lock_mr_rip, - /// Rax, Memory moffs. + /// Memory moffs, rax with lock prefix. /// Uses `payload` with extra data of type `MemoryMoffs`. - rax_moffs, - /// Memory moffs, rax. - /// Uses `payload` with extra data of type `MemoryMoffs`. - moffs_rax, + lock_moffs_rax, /// References another Mir instruction directly. /// Uses `inst` payload. inst, @@ -381,6 +404,11 @@ pub const Inst = struct { r2: Register, imm: u32, }, + /// Condition code (CC), followed by custom payload found in extra. + x_cc: struct { + payload: u32, + cc: bits.Condition, + }, /// Register with condition code (CC). r_cc: struct { r1: Register, diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 2a2d6ea031..519158d012 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -117,7 +117,8 @@ pub const Instruction = struct { pub fn new(mnemonic: Mnemonic, args: Init) !Instruction { const encoding = (try Encoding.findByMnemonic(mnemonic, args)) orelse { - log.debug("no encoding found for: {s} {s} {s} {s} {s}", .{ + log.debug("no encoding found for: {s} {s} {s} {s} {s} {s}", .{ + @tagName(args.prefix), @tagName(mnemonic), @tagName(Encoding.Op.fromOperand(args.op1)), @tagName(Encoding.Op.fromOperand(args.op2)), diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index ea21af2067..602718073d 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -252,6 +252,15 @@ pub const table = &[_]Entry{ .{ .cmpsd, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .none }, .{ .cmpsq, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .long }, + .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .none }, + .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .rex }, + .{ .cmpxchg, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb1 }, 0, .rex }, + .{ .cmpxchg, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb1 }, 0, .rex }, + .{ .cmpxchg, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb1 }, 0, .long }, + + .{ .cmpxchg8b , .m, .m64, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .none }, + .{ .cmpxchg16b, .m, .m128, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .long }, + .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .none }, .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .rex }, .{ .div, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 6, .none }, @@ -328,6 +337,8 @@ pub const table = &[_]Entry{ .{ .lea, .rm, .r32, .m, .none, .none, &.{ 0x8d }, 0, .none }, .{ .lea, .rm, .r64, .m, .none, .none, &.{ 0x8d }, 0, .long }, + .{ .lfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xe8 }, 0, .none }, + .{ .lods, .np, .m8, .none, .none, .none, &.{ 0xac }, 0, .none }, .{ .lods, .np, .m16, .none, .none, .none, &.{ 0xad }, 0, .none }, .{ .lods, .np, .m32, .none, .none, .none, &.{ 0xad }, 0, .none }, @@ -341,6 +352,8 @@ pub const table = &[_]Entry{ .{ .lzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, .{ .lzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .long }, + .{ .mfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xf0 }, 0, .none }, + .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .none }, .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .rex }, .{ .mov, .mr, .rm16, .r16, .none, .none, &.{ 0x89 }, 0, .none }, @@ -588,6 +601,8 @@ pub const table = &[_]Entry{ .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none }, .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex }, + .{ .sfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xf8 }, 0, .none }, + .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none }, .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex }, .{ .shl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, @@ -675,6 +690,29 @@ pub const table = &[_]Entry{ .{ .ud2, .np, .none, .none, .none, .none, &.{ 0x0f, 0x0b }, 0, .none }, + .{ .xadd, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xc0 }, 0, .none }, + .{ .xadd, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xc0 }, 0, .rex }, + .{ .xadd, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xc1 }, 0, .none }, + .{ .xadd, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xc1 }, 0, .none }, + .{ .xadd, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xc1 }, 0, .long }, + + .{ .xchg, .o, .ax, .r16, .none, .none, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, .r16, .ax, .none, .none, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, .eax, .r32, .none, .none, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, .rax, .r64, .none, .none, &.{ 0x90 }, 0, .long }, + .{ .xchg, .o, .r32, .eax, .none, .none, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, .r64, .rax, .none, .none, &.{ 0x90 }, 0, .long }, + .{ .xchg, .mr, .rm8, .r8, .none, .none, &.{ 0x86 }, 0, .none }, + .{ .xchg, .mr, .rm8, .r8, .none, .none, &.{ 0x86 }, 0, .rex }, + .{ .xchg, .rm, .r8, .rm8, .none, .none, &.{ 0x86 }, 0, .none }, + .{ .xchg, .rm, .r8, .rm8, .none, .none, &.{ 0x86 }, 0, .rex }, + .{ .xchg, .mr, .rm16, .r16, .none, .none, &.{ 0x87 }, 0, .none }, + .{ .xchg, .rm, .r16, .rm16, .none, .none, &.{ 0x87 }, 0, .none }, + .{ .xchg, .mr, .rm32, .r32, .none, .none, &.{ 0x87 }, 0, .none }, + .{ .xchg, .mr, .rm64, .r64, .none, .none, &.{ 0x87 }, 0, .long }, + .{ .xchg, .rm, .r32, .rm32, .none, .none, &.{ 0x87 }, 0, .none }, + .{ .xchg, .rm, .r64, .rm64, .none, .none, &.{ 0x87 }, 0, .long }, + .{ .xor, .zi, .al, .imm8, .none, .none, &.{ 0x34 }, 0, .none }, .{ .xor, .zi, .ax, .imm16, .none, .none, &.{ 0x35 }, 0, .none }, .{ .xor, .zi, .eax, .imm32, .none, .none, &.{ 0x35 }, 0, .none }, diff --git a/src/register_manager.zig b/src/register_manager.zig index 4d16348c27..713b669b06 100644 --- a/src/register_manager.zig +++ b/src/register_manager.zig @@ -305,40 +305,32 @@ pub fn RegisterManager( pub fn getReg(self: *Self, reg: Register, inst: ?Air.Inst.Index) AllocateRegistersError!void { const index = indexOfRegIntoTracked(reg) orelse return; log.debug("getReg {} for inst {?}", .{ reg, inst }); - self.markRegAllocated(reg); - if (inst) |tracked_inst| - if (!self.isRegFree(reg)) { - // Move the instruction that was previously there to a - // stack allocation. - const spilled_inst = self.registers[index]; - self.registers[index] = tracked_inst; - try self.getFunction().spillInstruction(reg, spilled_inst); - } else { - self.getRegAssumeFree(reg, tracked_inst); - } - else { - if (!self.isRegFree(reg)) { - // Move the instruction that was previously there to a - // stack allocation. - const spilled_inst = self.registers[index]; - try self.getFunction().spillInstruction(reg, spilled_inst); - self.freeReg(reg); - } - } + if (!self.isRegFree(reg)) { + self.markRegAllocated(reg); + + // Move the instruction that was previously there to a + // stack allocation. + const spilled_inst = self.registers[index]; + if (inst) |tracked_inst| self.registers[index] = tracked_inst; + try self.getFunction().spillInstruction(reg, spilled_inst); + if (inst == null) self.freeReg(reg); + } else self.getRegAssumeFree(reg, inst); } /// Allocates the specified register with the specified /// instruction. Asserts that the register is free and no /// spilling is necessary. - pub fn getRegAssumeFree(self: *Self, reg: Register, inst: Air.Inst.Index) void { + pub fn getRegAssumeFree(self: *Self, reg: Register, inst: ?Air.Inst.Index) void { const index = indexOfRegIntoTracked(reg) orelse return; - log.debug("getRegAssumeFree {} for inst {}", .{ reg, inst }); + log.debug("getRegAssumeFree {} for inst {?}", .{ reg, inst }); self.markRegAllocated(reg); assert(self.isRegFree(reg)); - self.registers[index] = inst; - self.markRegUsed(reg); + if (inst) |tracked_inst| { + self.registers[index] = tracked_inst; + self.markRegUsed(reg); + } } /// Marks the specified register as free diff --git a/test/behavior/atomics.zig b/test/behavior/atomics.zig index cf7c3b1503..a1e3af6e9a 100644 --- a/test/behavior/atomics.zig +++ b/test/behavior/atomics.zig @@ -33,7 +33,6 @@ fn testCmpxchg() !void { test "fence" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -44,7 +43,6 @@ test "fence" { test "atomicrmw and atomicload" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -73,7 +71,6 @@ fn testAtomicLoad(ptr: *u8) !void { test "cmpxchg with ptr" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -162,7 +159,6 @@ test "cmpxchg on a global variable" { test "atomic load and rmw with enum" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -180,7 +176,6 @@ test "atomic load and rmw with enum" { test "atomic store" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -194,7 +189,6 @@ test "atomic store" { test "atomic store comptime" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -424,7 +418,6 @@ fn testAtomicsWithType(comptime T: type, a: T, b: T) !void { test "return @atomicStore, using it as a void value" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/13068.zig b/test/behavior/bugs/13068.zig index e28a410807..bfe6164e27 100644 --- a/test/behavior/bugs/13068.zig +++ b/test/behavior/bugs/13068.zig @@ -8,7 +8,6 @@ test { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO list.items.len = 0; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index e601385bca..7d27138ded 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -655,7 +655,6 @@ test "@floatCast cast down" { } test "peer type resolution: unreachable, error set, unreachable" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/merge_error_sets.zig b/test/behavior/merge_error_sets.zig index 4e6d9e4c45..492cb27699 100644 --- a/test/behavior/merge_error_sets.zig +++ b/test/behavior/merge_error_sets.zig @@ -12,7 +12,6 @@ fn foo() C!void { } test "merge error sets" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (foo()) { diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 9129b73f16..1643a2f697 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -228,7 +228,6 @@ const SwitchProngWithVarEnum = union(enum) { }; test "switch prong with variable" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From c58b5732f381fe4f145537501e29347be01e2a44 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 20 Mar 2023 23:02:31 -0400 Subject: [PATCH 061/216] x86_64: implement @byteSwap and @bitReverse --- src/arch/x86_64/CodeGen.zig | 317 ++++++++++++++++++++++++++-------- src/arch/x86_64/Emit.zig | 6 + src/arch/x86_64/Encoding.zig | 6 +- src/arch/x86_64/Mir.zig | 12 ++ src/arch/x86_64/bits.zig | 2 +- src/arch/x86_64/encoder.zig | 121 ++++++------- src/arch/x86_64/encodings.zig | 74 ++++++++ 7 files changed, 388 insertions(+), 150 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f32eb84afc..f30be0e378 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2595,10 +2595,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { try self.asmRegisterMemory( .mov, registerAlias(dst_mcv.register, elem_abi_size), - Memory.sib(Memory.PtrSize.fromSize(elem_abi_size), .{ - .base = dst_mcv.register, - .disp = 0, - }), + Memory.sib(Memory.PtrSize.fromSize(elem_abi_size), .{ .base = dst_mcv.register }), ); break :result .{ .register = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)) }; } @@ -2956,21 +2953,197 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } +fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, mem_ok: bool) !MCValue { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + + const src_bits = self.regBitSize(src_ty); + const src_lock = switch (src_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + + switch (src_bits) { + else => unreachable, + 8 => return if ((mem_ok or src_mcv.isRegister()) and + self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking(inst, src_ty, src_mcv), + 16 => if ((mem_ok or src_mcv.isRegister()) and + self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + { + try self.genBinOpMir(.rol, src_ty, src_mcv, .{ .immediate = 8 }); + return src_mcv; + }, + 32, 64 => if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) { + try self.genUnOpMir(.bswap, src_ty, src_mcv); + return src_mcv; + }, + } + + if (src_mcv.isRegister()) { + const dst_mcv: MCValue = if (mem_ok) + try self.allocRegOrMem(inst, true) + else + .{ .register = try self.register_manager.allocReg(inst, gp) }; + if (dst_mcv.isRegister()) { + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register); + defer self.register_manager.unlockReg(dst_lock); + + try self.genSetReg(src_ty, dst_mcv.register, src_mcv); + switch (src_bits) { + else => unreachable, + 16 => try self.genBinOpMir(.rol, src_ty, dst_mcv, .{ .immediate = 8 }), + 32, 64 => try self.genUnOpMir(.bswap, src_ty, dst_mcv), + } + } else try self.genBinOpMir(.movbe, src_ty, dst_mcv, src_mcv); + return dst_mcv; + } + + const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_mcv = MCValue{ .register = dst_reg }; + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + try self.genBinOpMir(.movbe, src_ty, dst_mcv, src_mcv); + return dst_mcv; +} + fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airByteSwap for {}", .{self.target.cpu.arch}); + const result = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const src_ty = self.air.typeOf(ty_op.operand); + const src_mcv = try self.resolveInst(ty_op.operand); + + const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, true); + switch (self.regExtraBits(src_ty)) { + 0 => {}, + else => |extra| try self.genBinOpMir( + if (src_ty.isSignedInt()) .sar else .shr, + src_ty, + dst_mcv, + .{ .immediate = extra }, + ), + } + break :result dst_mcv; + }; + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airBitReverse for {}", .{self.target.cpu.arch}); + const result = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const src_ty = self.air.typeOf(ty_op.operand); + const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); + const src_mcv = try self.resolveInst(ty_op.operand); + + const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, false); + const dst_reg = dst_mcv.register; + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const tmp_reg = try self.register_manager.allocReg(null, gp); + const tmp_lock = self.register_manager.lockReg(tmp_reg); + defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock); + + { + const dst = registerAlias(dst_reg, src_abi_size); + const tmp = registerAlias(tmp_reg, src_abi_size); + const imm = if (src_abi_size > 4) + try self.register_manager.allocReg(null, gp) + else + undefined; + + const mask = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - src_abi_size * 8); + const imm_0000_1111 = Immediate.u(mask / 0b0001_0001); + const imm_00_11 = Immediate.u(mask / 0b01_01); + const imm_0_1 = Immediate.u(mask / 0b1_1); + + // dst = temp1 = bswap(operand) + try self.asmRegisterRegister(.mov, tmp, dst); + // tmp = temp1 + try self.asmRegisterImmediate(.shr, dst, Immediate.u(4)); + // dst = temp1 >> 4 + if (src_abi_size > 4) { + try self.asmRegisterImmediate(.mov, imm, imm_0000_1111); + try self.asmRegisterRegister(.@"and", tmp, imm); + try self.asmRegisterRegister(.@"and", dst, imm); + } else { + try self.asmRegisterImmediate(.@"and", tmp, imm_0000_1111); + try self.asmRegisterImmediate(.@"and", dst, imm_0000_1111); + } + // tmp = temp1 & 0x0F...0F + // dst = (temp1 >> 4) & 0x0F...0F + try self.asmRegisterImmediate(.shl, tmp, Immediate.u(4)); + // tmp = (temp1 & 0x0F...0F) << 4 + try self.asmRegisterRegister(.@"or", dst, tmp); + // dst = temp2 = ((temp1 >> 4) & 0x0F...0F) | ((temp1 & 0x0F...0F) << 4) + try self.asmRegisterRegister(.mov, tmp, dst); + // tmp = temp2 + try self.asmRegisterImmediate(.shr, dst, Immediate.u(2)); + // dst = temp2 >> 2 + if (src_abi_size > 4) { + try self.asmRegisterImmediate(.mov, imm, imm_00_11); + try self.asmRegisterRegister(.@"and", tmp, imm); + try self.asmRegisterRegister(.@"and", dst, imm); + } else { + try self.asmRegisterImmediate(.@"and", tmp, imm_00_11); + try self.asmRegisterImmediate(.@"and", dst, imm_00_11); + } + // tmp = temp2 & 0x33...33 + // dst = (temp2 >> 2) & 0x33...33 + try self.asmRegisterMemory( + .lea, + if (src_abi_size > 4) tmp.to64() else tmp.to32(), + Memory.sib(.qword, .{ + .base = dst.to64(), + .scale_index = .{ .index = tmp.to64(), .scale = 1 << 2 }, + }), + ); + // tmp = temp3 = ((temp2 >> 2) & 0x33...33) + ((temp2 & 0x33...33) << 2) + try self.asmRegisterRegister(.mov, dst, tmp); + // dst = temp3 + try self.asmRegisterImmediate(.shr, tmp, Immediate.u(1)); + // tmp = temp3 >> 1 + if (src_abi_size > 4) { + try self.asmRegisterImmediate(.mov, imm, imm_0_1); + try self.asmRegisterRegister(.@"and", dst, imm); + try self.asmRegisterRegister(.@"and", tmp, imm); + } else { + try self.asmRegisterImmediate(.@"and", dst, imm_0_1); + try self.asmRegisterImmediate(.@"and", tmp, imm_0_1); + } + // dst = temp3 & 0x55...55 + // tmp = (temp3 >> 1) & 0x55...55 + try self.asmRegisterMemory( + .lea, + if (src_abi_size > 4) dst.to64() else dst.to32(), + Memory.sib(.qword, .{ + .base = tmp.to64(), + .scale_index = .{ .index = dst.to64(), .scale = 1 << 1 }, + }), + ); + // dst = ((temp3 >> 1) & 0x55...55) + ((temp3 & 0x55...55) << 1) + } + + switch (self.regExtraBits(src_ty)) { + 0 => {}, + else => |extra| try self.genBinOpMir( + if (src_ty.isSignedInt()) .sar else .shr, + src_ty, + dst_mcv, + .{ .immediate = extra }, + ), + } + break :result dst_mcv; + }; + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -3052,7 +3225,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo try self.asmRegisterMemory( .mov, registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg, .disp = 0 }), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg }), ); }, .stack_offset => |off| { @@ -3167,7 +3340,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .eflags => |cc| { try self.asmSetccMemory(Memory.sib( Memory.PtrSize.fromSize(abi_size), - .{ .base = reg.to64(), .disp = 0 }, + .{ .base = reg.to64() }, ), cc); }, .undef => { @@ -3187,10 +3360,10 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type Immediate.s(@intCast(i32, @bitCast(i64, imm))) else Immediate.u(@truncate(u32, imm)); - try self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = reg.to64(), - .disp = 0, - }), immediate); + try self.asmMemoryImmediate(.mov, Memory.sib( + Memory.PtrSize.fromSize(abi_size), + .{ .base = reg.to64() }, + ), immediate); }, 8 => { // TODO: optimization: if the imm is only using the lower @@ -3262,10 +3435,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); // To get the actual address of the value we want to modify we have to go through the GOT - try self.asmRegisterMemory(.mov, addr_reg.to64(), Memory.sib(.qword, .{ - .base = addr_reg.to64(), - .disp = 0, - })); + try self.asmRegisterMemory( + .mov, + addr_reg.to64(), + Memory.sib(.qword, .{ .base = addr_reg.to64() }), + ); const new_ptr = MCValue{ .register = addr_reg.to64() }; @@ -3287,10 +3461,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type return self.fail("TODO imm64 would get incorrectly sign extended", .{}); } } - try self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = addr_reg.to64(), - .disp = 0, - }), Immediate.u(@intCast(u32, imm))); + try self.asmMemoryImmediate( + .mov, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg.to64() }), + Immediate.u(@intCast(u32, imm)), + ); }, .register => { return self.store(new_ptr, value, ptr_ty, value_ty); @@ -3302,10 +3477,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type defer self.register_manager.unlockReg(tmp_reg_lock); try self.loadMemPtrIntoRegister(tmp_reg, value_ty, value); - try self.asmRegisterMemory(.mov, tmp_reg, Memory.sib(.qword, .{ - .base = tmp_reg, - .disp = 0, - })); + try self.asmRegisterMemory( + .mov, + tmp_reg, + Memory.sib(.qword, .{ .base = tmp_reg }), + ); return self.store(new_ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); } @@ -3604,15 +3780,16 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv); // To get the actual address of the value we want to modify we have to go through the GOT - try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ - .base = addr_reg, - .disp = 0, - })); + try self.asmRegisterMemory( + .mov, + addr_reg, + Memory.sib(.qword, .{ .base = addr_reg }), + ); - try self.asmMemory(mir_tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = addr_reg, - .disp = 0, - })); + try self.asmMemory( + mir_tag, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), + ); }, } } @@ -4117,17 +4294,15 @@ fn genBinOp( // To get the actual address of the value we want to modify we // we have to go through the GOT - try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ - .base = addr_reg, - .disp = 0, - })); + try self.asmRegisterMemory( + .mov, + addr_reg, + Memory.sib(.qword, .{ .base = addr_reg }), + ); try self.asmCmovccRegisterMemory( registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = addr_reg, - .disp = 0, - }), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), cc, ); }, @@ -5175,10 +5350,11 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC try self.loadMemPtrIntoRegister(addr_reg, Type.usize, opt_mcv); // To get the actual address of the value we want to modify we have to go through the GOT - try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ - .base = addr_reg, - .disp = 0, - })); + try self.asmRegisterMemory( + .mov, + addr_reg, + Memory.sib(.qword, .{ .base = addr_reg }), + ); const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); try self.asmMemoryImmediate(.cmp, Memory.sib( @@ -6374,10 +6550,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .f64 => .qword, else => unreachable, }; - return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{ - .base = base_reg.to64(), - .disp = 0, - })); + return self.asmRegisterMemory( + tag, + reg.to128(), + Memory.sib(ptr_size, .{ .base = base_reg.to64() }), + ); } return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); @@ -6387,7 +6564,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void try self.asmRegisterMemory( .mov, registerAlias(reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64(), .disp = 0 }), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), ); }, } @@ -6408,10 +6585,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .f64 => .qword, else => unreachable, }; - return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{ - .base = base_reg.to64(), - .disp = 0, - })); + return self.asmRegisterMemory( + tag, + reg.to128(), + Memory.sib(ptr_size, .{ .base = base_reg.to64() }), + ); } return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); @@ -6447,7 +6625,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void try self.asmRegisterMemory( .mov, registerAlias(reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64(), .disp = 0 }), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), ); } } @@ -6638,12 +6816,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); const ptr_size = Memory.PtrSize.fromSize(val_abi_size); const ptr_mem: Memory = switch (ptr_mcv) { - .register => |reg| Memory.sib(ptr_size, .{ .base = reg, .disp = 0 }), + .register => |reg| Memory.sib(ptr_size, .{ .base = reg }), .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }), - else => Memory.sib(ptr_size, .{ - .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv), - .disp = 0, - }), + else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }), }; const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null; defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); @@ -6692,12 +6867,9 @@ fn atomicOp( const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); const ptr_size = Memory.PtrSize.fromSize(val_abi_size); const ptr_mem: Memory = switch (ptr_mcv) { - .register => |reg| Memory.sib(ptr_size, .{ .base = reg, .disp = 0 }), + .register => |reg| Memory.sib(ptr_size, .{ .base = reg }), .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }), - else => Memory.sib(ptr_size, .{ - .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv), - .disp = 0, - }), + else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }), }; const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null; defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); @@ -6861,10 +7033,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { .linker_load, .memory => { const reg = try self.register_manager.allocReg(null, gp); try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); - try self.asmRegisterMemory(.mov, reg, Memory.sib(.qword, .{ - .base = reg, - .disp = 0, - })); + try self.asmRegisterMemory(.mov, reg, Memory.sib(.qword, .{ .base = reg })); break :blk MCValue{ .register = reg }; }, else => break :blk src_ptr, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 9718548736..cd8389aa49 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -75,6 +75,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .@"and", .bsf, .bsr, + .bswap, .bt, .btc, .btr, @@ -100,6 +101,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .lzcnt, .mfence, .mov, + .movbe, .movzx, .mul, .neg, @@ -109,7 +111,11 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .pop, .popcnt, .push, + .rcl, + .rcr, .ret, + .rol, + .ror, .sal, .sar, .sbb, diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 03b8abf983..891fc4e9a1 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -307,7 +307,7 @@ pub const Mnemonic = enum { // zig fmt: off // General-purpose adc, add, @"and", - bsf, bsr, bt, btc, btr, bts, + bsf, bsr, bswap, bt, btc, btr, bts, call, cbw, cdq, cdqe, cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna, cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno, @@ -325,13 +325,13 @@ pub const Mnemonic = enum { lea, lfence, lods, lodsb, lodsd, lodsq, lodsw, lzcnt, - mfence, mov, + mfence, mov, movbe, movs, movsb, movsd, movsq, movsw, movsx, movsxd, movzx, mul, neg, nop, not, @"or", pop, popcnt, push, - ret, + rcl, rcr, ret, rol, ror, sal, sar, sbb, scas, scasb, scasd, scasq, scasw, shl, shr, sub, syscall, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index d086b617f5..59c292c500 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -42,6 +42,8 @@ pub const Inst = struct { bsf, /// Bit scan reverse bsr, + /// Byte swap + bswap, /// Bit test bt, /// Bit test and complement @@ -94,6 +96,8 @@ pub const Inst = struct { mfence, /// Move mov, + /// Move data after swapping bytes + movbe, /// Move with sign extension movsx, /// Move with zero extension @@ -114,8 +118,16 @@ pub const Inst = struct { popcnt, /// Push push, + /// Rotate left through carry + rcl, + /// Rotate right through carry + rcr, /// Return ret, + /// Rotate left + rol, + /// Rotate right + ror, /// Arithmetic shift left sal, /// Arithmetic shift right diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index 250eedeafc..c10bfe4039 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -472,7 +472,7 @@ pub const Memory = union(enum) { } pub fn sib(ptr_size: PtrSize, args: struct { - disp: i32, + disp: i32 = 0, base: ?Register = null, scale_index: ?ScaleIndex = null, }) Memory { diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 519158d012..b3de7ec1bd 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -211,14 +211,12 @@ pub const Instruction = struct { fn encodeOpcode(inst: Instruction, encoder: anytype) !void { const opcode = inst.encoding.opcode(); + const first = @boolToInt(inst.encoding.mandatoryPrefix() != null); + const final = opcode.len - 1; + for (opcode[first..final]) |byte| try encoder.opcode_1byte(byte); switch (inst.encoding.op_en) { - .o, .oi => try encoder.opcode_withReg(opcode[0], inst.op1.reg.lowEnc()), - else => { - const index: usize = if (inst.encoding.mandatoryPrefix()) |_| 1 else 0; - for (opcode[index..]) |byte| { - try encoder.opcode_1byte(byte); - } - }, + .o, .oi => try encoder.opcode_withReg(opcode[final], inst.op1.reg.lowEnc()), + else => try encoder.opcode_1byte(opcode[final]), } } @@ -896,10 +894,10 @@ test "lower MI encoding" { try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.byte, .{ - .base = .r12, - .disp = 0, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, .{ + .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) }, + .op2 = .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10"); try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } }); @@ -911,10 +909,10 @@ test "lower MI encoding" { try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } }); try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .r11, - .disp = 0, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, .{ + .op1 = .{ .mem = Memory.sib(.dword, .{ .base = .r11 }) }, + .op2 = .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10"); try enc.encode(.mov, .{ @@ -1030,10 +1028,10 @@ test "lower MI encoding" { test "lower RM encoding" { var enc = TestEncode{}; - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .r11, - .disp = 0, - }) } }); + try enc.encode(.mov, .{ + .op1 = .{ .reg = .rax }, + .op2 = .{ .mem = Memory.sib(.qword, .{ .base = .r11 }) }, + }); try expectEqualHexStrings("\x49\x8b\x03", enc.code(), "mov rax, QWORD PTR [r11]"); try enc.encode(.mov, .{ .op1 = .{ .reg = .rbx }, .op2 = .{ .mem = Memory.sib(.qword, .{ @@ -1116,20 +1114,16 @@ test "lower RM encoding" { try enc.encode(.movsx, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .reg = .bl } }); try expectEqualHexStrings("\x66\x0F\xBE\xC3", enc.code(), "movsx ax, bl"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.sib(.word, .{ - .base = .rbp, - .disp = 0, - }) } }); + try enc.encode(.movsx, .{ + .op1 = .{ .reg = .eax }, + .op2 = .{ .mem = Memory.sib(.word, .{ .base = .rbp }) }, + }); try expectEqualHexStrings("\x0F\xBF\x45\x00", enc.code(), "movsx eax, BYTE PTR [rbp]"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.sib(.byte, .{ - .base = null, - .scale_index = .{ - .index = .rax, - .scale = 2, - }, - .disp = 0, - }) } }); + try enc.encode(.movsx, .{ + .op1 = .{ .reg = .eax }, + .op2 = .{ .mem = Memory.sib(.byte, .{ .scale_index = .{ .index = .rax, .scale = 2 } }) }, + }); try expectEqualHexStrings("\x0F\xBE\x04\x45\x00\x00\x00\x00", enc.code(), "movsx eax, BYTE PTR [rax * 2]"); try enc.encode(.movsx, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.rip(.byte, 0x10) } }); @@ -1156,14 +1150,13 @@ test "lower RM encoding" { try enc.encode(.lea, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.rip(.byte, 0x10) } }); try expectEqualHexStrings("\x66\x8D\x05\x10\x00\x00\x00", enc.code(), "lea ax, BYTE PTR [rip + 0x10]"); - try enc.encode(.lea, .{ .op1 = .{ .reg = .rsi }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .scale_index = .{ - .scale = 1, - .index = .rcx, - }, - .disp = 0, - }) } }); + try enc.encode(.lea, .{ + .op1 = .{ .reg = .rsi }, + .op2 = .{ .mem = Memory.sib(.qword, .{ + .base = .rbp, + .scale_index = .{ .scale = 1, .index = .rcx }, + }) }, + }); try expectEqualHexStrings("\x48\x8D\x74\x0D\x00", enc.code(), "lea rsi, QWORD PTR [rbp + rcx*1 + 0]"); try enc.encode(.add, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{ @@ -1319,51 +1312,35 @@ test "lower M encoding" { try enc.encode(.call, .{ .op1 = .{ .reg = .r12 } }); try expectEqualHexStrings("\x41\xFF\xD4", enc.code(), "call r12"); - try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .r12, - .disp = 0, - }) } }); + try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .r12 }) } }); try expectEqualHexStrings("\x41\xFF\x14\x24", enc.code(), "call QWORD PTR [r12]"); - try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = null, - .scale_index = .{ - .index = .r11, - .scale = 2, - }, - .disp = 0, - }) } }); + try enc.encode(.call, .{ + .op1 = .{ .mem = Memory.sib(.qword, .{ + .base = null, + .scale_index = .{ .index = .r11, .scale = 2 }, + }) }, + }); try expectEqualHexStrings("\x42\xFF\x14\x5D\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r11 * 2]"); - try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = null, - .scale_index = .{ - .index = .r12, - .scale = 2, - }, - .disp = 0, - }) } }); + try enc.encode(.call, .{ + .op1 = .{ .mem = Memory.sib(.qword, .{ + .base = null, + .scale_index = .{ .index = .r12, .scale = 2 }, + }) }, + }); try expectEqualHexStrings("\x42\xFF\x14\x65\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r12 * 2]"); - try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .gs, - .disp = 0, - }) } }); + try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .gs }) } }); try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0"); try enc.encode(.call, .{ .op1 = .{ .imm = Immediate.s(0) } }); try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0"); - try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .disp = 0, - }) } }); + try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .rbp }) } }); try expectEqualHexStrings("\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]"); - try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.word, .{ - .base = .rbp, - .disp = 0, - }) } }); + try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.word, .{ .base = .rbp }) } }); try expectEqualHexStrings("\x66\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]"); try enc.encode(.pop, .{ .op1 = .{ .mem = Memory.rip(.qword, 0) } }); @@ -1491,7 +1468,7 @@ fn cannotEncode(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { test "cannot encode" { try cannotEncode(.@"test", .{ - .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12, .disp = 0 }) }, + .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) }, .op2 = .{ .reg = .ah }, }); try cannotEncode(.@"test", .{ diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 602718073d..23a125789b 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -89,6 +89,9 @@ pub const table = &[_]Entry{ .{ .bsr, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbd }, 0, .none }, .{ .bsr, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbd }, 0, .long }, + .{ .bswap, .o, .r32, .none, .none, .none, &.{ 0x0f, 0xc8 }, 0, .none }, + .{ .bswap, .o, .r64, .none, .none, .none, &.{ 0x0f, 0xc8 }, 0, .long }, + .{ .bt, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none }, .{ .bt, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none }, .{ .bt, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xa3 }, 0, .long }, @@ -387,6 +390,13 @@ pub const table = &[_]Entry{ .{ .mov, .mi, .rm32, .imm32, .none, .none, &.{ 0xc7 }, 0, .none }, .{ .mov, .mi, .rm64, .imm32s, .none, .none, &.{ 0xc7 }, 0, .long }, + .{ .movbe, .rm, .r16, .m16, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .none }, + .{ .movbe, .rm, .r32, .m32, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .none }, + .{ .movbe, .rm, .r64, .m64, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .long }, + .{ .movbe, .mr, .m16, .r16, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .none }, + .{ .movbe, .mr, .m32, .r32, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .none }, + .{ .movbe, .mr, .m64, .r64, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .long }, + .{ .movs, .np, .m8, .m8, .none, .none, &.{ 0xa4 }, 0, .none }, .{ .movs, .np, .m16, .m16, .none, .none, &.{ 0xa5 }, 0, .none }, .{ .movs, .np, .m32, .m32, .none, .none, &.{ 0xa5 }, 0, .none }, @@ -476,6 +486,70 @@ pub const table = &[_]Entry{ .{ .ret, .np, .none, .none, .none, .none, &.{ 0xc3 }, 0, .none }, + .{ .rcl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 2, .none }, + .{ .rcl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 2, .rex }, + .{ .rcl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 2, .none }, + .{ .rcl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 2, .rex }, + .{ .rcl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 2, .none }, + .{ .rcl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 2, .rex }, + .{ .rcl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 2, .none }, + .{ .rcl, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 2, .none }, + .{ .rcl, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 2, .none }, + .{ .rcl, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 2, .none }, + .{ .rcl, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 2, .long }, + .{ .rcl, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 2, .none }, + .{ .rcl, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 2, .long }, + .{ .rcl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 2, .none }, + .{ .rcl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 2, .long }, + + .{ .rcr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 3, .none }, + .{ .rcr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 3, .rex }, + .{ .rcr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 3, .none }, + .{ .rcr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 3, .rex }, + .{ .rcr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 3, .none }, + .{ .rcr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 3, .rex }, + .{ .rcr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 3, .none }, + .{ .rcr, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 3, .none }, + .{ .rcr, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 3, .none }, + .{ .rcr, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 3, .none }, + .{ .rcr, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 3, .long }, + .{ .rcr, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 3, .none }, + .{ .rcr, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 3, .long }, + .{ .rcr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 3, .none }, + .{ .rcr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 3, .long }, + + .{ .rol, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 0, .none }, + .{ .rol, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 0, .rex }, + .{ .rol, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 0, .none }, + .{ .rol, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 0, .rex }, + .{ .rol, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 0, .none }, + .{ .rol, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 0, .rex }, + .{ .rol, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 0, .none }, + .{ .rol, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 0, .none }, + .{ .rol, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 0, .none }, + .{ .rol, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 0, .none }, + .{ .rol, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 0, .long }, + .{ .rol, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 0, .none }, + .{ .rol, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 0, .long }, + .{ .rol, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 0, .none }, + .{ .rol, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 0, .long }, + + .{ .ror, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 1, .none }, + .{ .ror, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 1, .rex }, + .{ .ror, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 1, .none }, + .{ .ror, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 1, .rex }, + .{ .ror, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 1, .none }, + .{ .ror, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 1, .rex }, + .{ .ror, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 1, .none }, + .{ .ror, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 1, .none }, + .{ .ror, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 1, .none }, + .{ .ror, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 1, .none }, + .{ .ror, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 1, .long }, + .{ .ror, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 1, .none }, + .{ .ror, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 1, .long }, + .{ .ror, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 1, .none }, + .{ .ror, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 1, .long }, + .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none }, .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex }, .{ .sal, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, From a88ffa7fa91e568fe234ac9ea2b15f005876cca6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 11:38:19 +0100 Subject: [PATCH 062/216] macho+zld: save locals from section atoms to symtab too --- src/link/MachO/zld.zig | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 931352545e..17d122b30d 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -2456,6 +2456,17 @@ pub const Zld = struct { try self.writeStrtab(); } + fn addLocalToSymtab(self: *Zld, sym_loc: SymbolWithLoc, locals: *std.ArrayList(macho.nlist_64)) !void { + const sym = self.getSymbol(sym_loc); + if (sym.n_strx == 0) return; // no name, skip + if (sym.ext()) return; // an export lands in its own symtab section, skip + if (self.symbolIsTemp(sym_loc)) return; // local temp symbol, skip + + var out_sym = sym; + out_sym.n_strx = try self.strtab.insert(self.gpa, self.getSymbolName(sym_loc)); + try locals.append(out_sym); + } + fn writeSymtab(self: *Zld) !SymtabCtx { const gpa = self.gpa; @@ -2466,14 +2477,12 @@ pub const Zld = struct { for (object.atoms.items) |atom_index| { const atom = self.getAtom(atom_index); const sym_loc = atom.getSymbolWithLoc(); - const sym = self.getSymbol(sym_loc); - if (sym.n_strx == 0) continue; // no name, skip - if (sym.ext()) continue; // an export lands in its own symtab section, skip - if (self.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip + try self.addLocalToSymtab(sym_loc, &locals); - var out_sym = sym; - out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(sym_loc)); - try locals.append(out_sym); + var it = Atom.getInnerSymbolsIterator(self, atom_index); + while (it.next()) |inner_sym_loc| { + try self.addLocalToSymtab(inner_sym_loc, &locals); + } } } From 073f9a18a92fd233e07470e737e15e651618e47f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 11:38:49 +0100 Subject: [PATCH 063/216] macho+zld: return null rather than error on invalid AbbrevKind --- src/link/MachO/DwarfInfo.zig | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/link/MachO/DwarfInfo.zig b/src/link/MachO/DwarfInfo.zig index 1ec4a79871..3218435734 100644 --- a/src/link/MachO/DwarfInfo.zig +++ b/src/link/MachO/DwarfInfo.zig @@ -27,7 +27,7 @@ const CompileUnitIterator = struct { pub fn next(self: *CompileUnitIterator) !?CompileUnit { if (self.pos >= self.ctx.debug_info.len) return null; - var stream = std.io.fixedBufferStream(self.ctx.debug_info); + var stream = std.io.fixedBufferStream(self.ctx.debug_info[self.pos..]); var creader = std.io.countingReader(stream.reader()); const reader = creader.reader(); @@ -37,7 +37,7 @@ const CompileUnitIterator = struct { const cu = CompileUnit{ .cuh = cuh, - .debug_info_off = offset, + .debug_info_off = self.pos + offset, }; self.pos += (math.cast(usize, total_length) orelse return error.Overflow); @@ -188,7 +188,7 @@ const AbbrevEntryIterator = struct { return AbbrevEntry.null(); } - const abbrev_pos = lookup.get(kind) orelse return error.MalformedDwarf; + const abbrev_pos = lookup.get(kind) orelse return null; const len = try findAbbrevEntrySize( self.ctx, abbrev_pos.pos, @@ -290,21 +290,6 @@ pub const Attribute = struct { }; } - pub fn getReference(self: Attribute, ctx: DwarfInfo) !?u64 { - const debug_info = self.getDebugInfo(ctx); - var stream = std.io.fixedBufferStream(debug_info); - const reader = stream.reader(); - - return switch (self.form) { - dwarf.FORM.ref1 => debug_info[0], - dwarf.FORM.ref2 => mem.readIntLittle(u16, debug_info[0..2]), - dwarf.FORM.ref4 => mem.readIntLittle(u32, debug_info[0..4]), - dwarf.FORM.ref8 => mem.readIntLittle(u64, debug_info[0..8]), - dwarf.FORM.ref_udata => try leb.readULEB128(u64, reader), - else => null, - }; - } - pub fn getAddr(self: Attribute, ctx: DwarfInfo, cuh: CompileUnit.Header) ?u64 { if (self.form != dwarf.FORM.addr) return null; const debug_info = self.getDebugInfo(ctx); From b73159f4f57dcdffab526bb2c944b37942d65fc8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 12:47:43 +0100 Subject: [PATCH 064/216] macho: use TOOL=0x5 to mean ZIG as the build tool --- lib/std/macho.zig | 2 ++ src/link/MachO/load_commands.zig | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/std/macho.zig b/lib/std/macho.zig index 8f695b14b7..ff12e718f6 100644 --- a/lib/std/macho.zig +++ b/lib/std/macho.zig @@ -143,6 +143,8 @@ pub const TOOL = enum(u32) { CLANG = 0x1, SWIFT = 0x2, LD = 0x3, + LLD = 0x4, // LLVM's stock LLD linker + ZIG = 0x5, // Unofficially Zig _, }; diff --git a/src/link/MachO/load_commands.zig b/src/link/MachO/load_commands.zig index a452551a0a..43469ac435 100644 --- a/src/link/MachO/load_commands.zig +++ b/src/link/MachO/load_commands.zig @@ -294,7 +294,7 @@ pub fn writeBuildVersionLC(options: *const link.Options, lc_writer: anytype) !vo .ntools = 1, }); try lc_writer.writeAll(mem.asBytes(&macho.build_tool_version{ - .tool = .LD, + .tool = .ZIG, .version = 0x0, })); } From 898e4473e8acf664d67474716bb9728ed601c5a0 Mon Sep 17 00:00:00 2001 From: Xavier Bouchoux Date: Sun, 19 Mar 2023 12:56:37 +0000 Subject: [PATCH 065/216] CBE: implement aggregateInit() for array of array case. fixes `error(compilation): clang failed with stderr: error: array type 'uint32_t[10]' (aka 'unsigned int[10]') is not assignable` --- src/codegen/c.zig | 40 +++++++++++++++++++++++++++++----------- test/behavior/array.zig | 10 ++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 519b2b45d5..0c85f0f923 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -6852,17 +6852,35 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { switch (inst_ty.zigTypeTag()) { .Array, .Vector => { const elem_ty = inst_ty.childType(); - for (resolved_elements, 0..) |element, i| { - try f.writeCValue(writer, local, .Other); - try writer.print("[{d}] = ", .{i}); - try f.writeCValue(writer, element, .Other); - try writer.writeAll(";\n"); - } - if (inst_ty.sentinel()) |sentinel| { - try f.writeCValue(writer, local, .Other); - try writer.print("[{d}] = ", .{resolved_elements.len}); - try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); - try writer.writeAll(";\n"); + + const is_array = lowersToArray(elem_ty, target); + const need_memcpy = is_array; + if (need_memcpy) { + for (resolved_elements, 0..) |element, i| { + try writer.writeAll("memcpy("); + try f.writeCValue(writer, local, .Other); + try writer.print("[{d}]", .{i}); + try writer.writeAll(", "); + try f.writeCValue(writer, element, .Other); + try writer.writeAll(", sizeof("); + try f.renderType(writer, elem_ty); + try writer.writeAll("))"); + try writer.writeAll(";\n"); + } + assert(inst_ty.sentinel() == null); + } else { + for (resolved_elements, 0..) |element, i| { + try f.writeCValue(writer, local, .Other); + try writer.print("[{d}] = ", .{i}); + try f.writeCValue(writer, element, .Other); + try writer.writeAll(";\n"); + } + if (inst_ty.sentinel()) |sentinel| { + try f.writeCValue(writer, local, .Other); + try writer.print("[{d}] = ", .{resolved_elements.len}); + try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); + try writer.writeAll(";\n"); + } } }, .Struct => switch (inst_ty.containerLayout()) { diff --git a/test/behavior/array.zig b/test/behavior/array.zig index c78bf4ab85..484cab4722 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -669,3 +669,13 @@ test "runtime initialized sentinel-terminated array literal" { try std.testing.expect(g[2] == 0x99); try std.testing.expect(g[3] == 0x99); } + +test "array of array agregate init" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + var a = [1]u32{11} ** 10; + var b = [1][10]u32{a} ** 2; + try std.testing.expect(b[1][1] == 11); +} From 1e087d3a64e6b504524c32f72b22faffef78b41e Mon Sep 17 00:00:00 2001 From: Marcus Ramse Date: Wed, 8 Mar 2023 16:04:57 +0100 Subject: [PATCH 066/216] std.json: support tuples --- lib/std/json.zig | 48 +++++++++++++++++++++++++++++++++++------ lib/std/json/test.zig | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/lib/std/json.zig b/lib/std/json.zig index 590040efba..d2467fb2cd 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1511,6 +1511,34 @@ fn parseInternal( } }, .Struct => |structInfo| { + if (structInfo.is_tuple) { + switch (token) { + .ArrayBegin => {}, + else => return error.UnexpectedToken, + } + var r: T = undefined; + var child_options = options; + child_options.allow_trailing_data = true; + var fields_seen: usize = 0; + errdefer { + inline for (0..structInfo.fields.len) |i| { + if (i < fields_seen) { + parseFree(structInfo.fields[i].type, r[i], options); + } + } + } + inline for (0..structInfo.fields.len) |i| { + r[i] = try parse(structInfo.fields[i].type, tokens, child_options); + fields_seen = i + 1; + } + const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson; + switch (tok) { + .ArrayEnd => {}, + else => return error.UnexpectedToken, + } + return r; + } + switch (token) { .ObjectBegin => {}, else => return error.UnexpectedToken, @@ -2290,7 +2318,7 @@ pub fn stringify( return value.jsonStringify(options, out_stream); } - try out_stream.writeByte('{'); + try out_stream.writeByte(if (S.is_tuple) '[' else '{'); var field_output = false; var child_options = options; if (child_options.whitespace) |*child_whitespace| { @@ -2320,11 +2348,13 @@ pub fn stringify( if (child_options.whitespace) |child_whitespace| { try child_whitespace.outputIndent(out_stream); } - try encodeJsonString(Field.name, options, out_stream); - try out_stream.writeByte(':'); - if (child_options.whitespace) |child_whitespace| { - if (child_whitespace.separator) { - try out_stream.writeByte(' '); + if (!S.is_tuple) { + try encodeJsonString(Field.name, options, out_stream); + try out_stream.writeByte(':'); + if (child_options.whitespace) |child_whitespace| { + if (child_whitespace.separator) { + try out_stream.writeByte(' '); + } } } try stringify(@field(value, Field.name), child_options, out_stream); @@ -2335,7 +2365,7 @@ pub fn stringify( try whitespace.outputIndent(out_stream); } } - try out_stream.writeByte('}'); + try out_stream.writeByte(if (S.is_tuple) ']' else '}'); return; }, .ErrorSet => return stringify(@as([]const u8, @errorName(value)), options, out_stream), @@ -2649,6 +2679,10 @@ test "stringify vector" { try teststringify("[1,1]", @splat(2, @as(u32, 1)), StringifyOptions{}); } +test "stringify tuple" { + try teststringify("[\"foo\",42]", std.meta.Tuple(&.{ []const u8, usize }){ "foo", 42 }, StringifyOptions{}); +} + fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions) !void { const ValidationWriter = struct { const Self = @This(); diff --git a/lib/std/json/test.zig b/lib/std/json/test.zig index 067bc2920b..ce4b4ea7e8 100644 --- a/lib/std/json/test.zig +++ b/lib/std/json/test.zig @@ -2459,6 +2459,56 @@ test "parse into struct ignoring unknown fields" { try testing.expectEqualSlices(u8, "zig", r.language); } +test "parse into tuple" { + const options = ParseOptions{ .allocator = testing.allocator }; + const Union = union(enum) { + char: u8, + float: f64, + string: []const u8, + }; + const T = std.meta.Tuple(&.{ + i64, + f64, + bool, + []const u8, + ?bool, + struct { + foo: i32, + bar: []const u8, + }, + std.meta.Tuple(&.{ u8, []const u8, u8 }), + Union, + }); + var ts = TokenStream.init( + \\[ + \\ 420, + \\ 3.14, + \\ true, + \\ "zig", + \\ null, + \\ { + \\ "foo": 1, + \\ "bar": "zero" + \\ }, + \\ [4, "två", 42], + \\ 12.34 + \\] + ); + const r = try parse(T, &ts, options); + defer parseFree(T, r, options); + try testing.expectEqual(@as(i64, 420), r[0]); + try testing.expectEqual(@as(f64, 3.14), r[1]); + try testing.expectEqual(true, r[2]); + try testing.expectEqualSlices(u8, "zig", r[3]); + try testing.expectEqual(@as(?bool, null), r[4]); + try testing.expectEqual(@as(i32, 1), r[5].foo); + try testing.expectEqualSlices(u8, "zero", r[5].bar); + try testing.expectEqual(@as(u8, 4), r[6][0]); + try testing.expectEqualSlices(u8, "två", r[6][1]); + try testing.expectEqual(@as(u8, 42), r[6][2]); + try testing.expectEqual(Union{ .float = 12.34 }, r[7]); +} + const ParseIntoRecursiveUnionDefinitionValue = union(enum) { integer: i64, array: []const ParseIntoRecursiveUnionDefinitionValue, From f9b5829508e4f9a7e2eee2f05f58a38c00318d91 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 4 Mar 2023 13:21:11 +0000 Subject: [PATCH 067/216] Sema: implement @export for arbitrary values --- src/Sema.zig | 18 +++++++++++++++++- test/behavior/export.zig | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 6d6a9a13e8..d01535cdaa 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5668,7 +5668,15 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError }; const decl_index = switch (operand.val.tag()) { .function => operand.val.castTag(.function).?.data.owner_decl, - else => return sema.fail(block, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it. + else => blk: { + var anon_decl = try block.startAnonDecl(); + defer anon_decl.deinit(); + break :blk try anon_decl.finish( + try operand.ty.copy(anon_decl.arena()), + try operand.val.copy(anon_decl.arena()), + 0, + ); + }, }; try sema.analyzeExport(block, src, options, decl_index); } @@ -5704,6 +5712,14 @@ pub fn analyzeExport( return sema.failWithOwnedErrorMsg(msg); } + // TODO: some backends might support re-exporting extern decls + if (exported_decl.isExtern()) { + return sema.fail(block, src, "export target cannot be extern", .{}); + } + + // This decl is alive no matter what, since it's being exported + mod.markDeclAlive(exported_decl); + const gpa = mod.gpa; try mod.decl_exports.ensureUnusedCapacity(gpa, 1); diff --git a/test/behavior/export.zig b/test/behavior/export.zig index fb35fc6fc6..6123aa593b 100644 --- a/test/behavior/export.zig +++ b/test/behavior/export.zig @@ -70,3 +70,22 @@ test "exporting using field access" { _ = S.Inner.x; } + +test "exporting comptime-known value" { + const x: u32 = 10; + @export(x, .{ .name = "exporting_comptime_known_value_foo" }); + const S = struct { + extern const exporting_comptime_known_value_foo: u32; + }; + try expect(S.exporting_comptime_known_value_foo == 10); +} + +test "exporting comptime var" { + comptime var x: u32 = 5; + @export(x, .{ .name = "exporting_comptime_var_foo" }); + x = 7; // modifying this now shouldn't change anything + const S = struct { + extern const exporting_comptime_var_foo: u32; + }; + try expect(S.exporting_comptime_var_foo == 5); +} From 8642770eff4f1770aa5de88907946c60fe5ff0d8 Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Fri, 3 Mar 2023 16:16:08 +0100 Subject: [PATCH 068/216] langref: add missing return types to builtin functions This should add all remaining missing return types to all builtin functions. For @clz, @ctz, and @popCount it uses anytype for the lack of a better alternative. We already use this return type for other builtin functions in the langref to indicate that the type is not always the same. It is not possible to use anytype as the return type for regular functions but builtin functions are special. --- doc/langref.html.in | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 991fd0c3e6..be055c3179 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -7814,7 +7814,7 @@ comptime { {#header_close#} {#header_open|@breakpoint#} -
{#syntax#}@breakpoint(){#endsyntax#}
+
{#syntax#}@breakpoint() void{#endsyntax#}

This function inserts a platform-specific debug trap instruction which causes debuggers to break there. @@ -7933,7 +7933,7 @@ pub const CallModifier = enum { {#header_close#} {#header_open|@cDefine#} -

{#syntax#}@cDefine(comptime name: []u8, value){#endsyntax#}
+
{#syntax#}@cDefine(comptime name: []u8, value) void{#endsyntax#}

This function can only occur inside {#syntax#}@cImport{#endsyntax#}.

@@ -7977,7 +7977,7 @@ pub const CallModifier = enum { {#see_also|Import from C Header File|@cInclude|@cDefine|@cUndef#} {#header_close#} {#header_open|@cInclude#} -
{#syntax#}@cInclude(comptime path: []u8){#endsyntax#}
+
{#syntax#}@cInclude(comptime path: []u8) void{#endsyntax#}

This function can only occur inside {#syntax#}@cImport{#endsyntax#}.

@@ -7989,7 +7989,7 @@ pub const CallModifier = enum { {#header_close#} {#header_open|@clz#} -
{#syntax#}@clz(operand: anytype){#endsyntax#}
+
{#syntax#}@clz(operand: anytype) anytype{#endsyntax#}

{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.

{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.

@@ -8068,7 +8068,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#header_close#} {#header_open|@compileError#} -

{#syntax#}@compileError(comptime msg: []u8){#endsyntax#}
+
{#syntax#}@compileError(comptime msg: []u8) noreturn{#endsyntax#}

This function, when semantically analyzed, causes a compile error with the message {#syntax#}msg{#endsyntax#}. @@ -8081,7 +8081,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#header_close#} {#header_open|@compileLog#} -

{#syntax#}@compileLog(args: ...){#endsyntax#}
+
{#syntax#}@compileLog(args: ...) void{#endsyntax#}

This function prints the arguments passed to it at compile-time.

@@ -8139,7 +8139,7 @@ test "main" { {#header_close#} {#header_open|@ctz#} -
{#syntax#}@ctz(operand: anytype){#endsyntax#}
+
{#syntax#}@ctz(operand: anytype) anytype{#endsyntax#}

{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.

{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.

@@ -8159,7 +8159,7 @@ test "main" { {#header_close#} {#header_open|@cUndef#} -

{#syntax#}@cUndef(comptime name: []u8){#endsyntax#}
+
{#syntax#}@cUndef(comptime name: []u8) void{#endsyntax#}

This function can only occur inside {#syntax#}@cImport{#endsyntax#}.

@@ -8370,7 +8370,7 @@ export fn @"A function name that is a complete sentence."() void {} {#header_close#} {#header_open|@fence#} -
{#syntax#}@fence(order: AtomicOrder){#endsyntax#}
+
{#syntax#}@fence(order: AtomicOrder) void{#endsyntax#}

The {#syntax#}fence{#endsyntax#} function is used to introduce happens-before edges between operations.

@@ -8622,7 +8622,7 @@ test "integer cast panic" { {#header_close#} {#header_open|@memcpy#} -
{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize){#endsyntax#}
+
{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize) void{#endsyntax#}

This function copies bytes from one region of memory to another. {#syntax#}dest{#endsyntax#} and {#syntax#}source{#endsyntax#} are both pointers and must not overlap. @@ -8641,7 +8641,7 @@ mem.copy(u8, dest[0..byte_count], source[0..byte_count]);{#endsyntax#} {#header_close#} {#header_open|@memset#} -

{#syntax#}@memset(dest: [*]u8, c: u8, byte_count: usize){#endsyntax#}
+
{#syntax#}@memset(dest: [*]u8, c: u8, byte_count: usize) void{#endsyntax#}

This function sets a region of memory to {#syntax#}c{#endsyntax#}. {#syntax#}dest{#endsyntax#} is a pointer.

@@ -8753,7 +8753,7 @@ test "@wasmMemoryGrow" { {#header_close#} {#header_open|@popCount#} -
{#syntax#}@popCount(operand: anytype){#endsyntax#}
+
{#syntax#}@popCount(operand: anytype) anytype{#endsyntax#}

{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type.

{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.

Counts the number of bits set in an integer.

@@ -8767,7 +8767,7 @@ test "@wasmMemoryGrow" { {#header_close#} {#header_open|@prefetch#} -
{#syntax#}@prefetch(ptr: anytype, comptime options: std.builtin.PrefetchOptions){#endsyntax#}
+
{#syntax#}@prefetch(ptr: anytype, comptime options: std.builtin.PrefetchOptions) void{#endsyntax#}

This builtin tells the compiler to emit a prefetch instruction if supported by the target CPU. If the target CPU does not support the requested prefetch instruction, @@ -8881,21 +8881,21 @@ pub const PrefetchOptions = struct { {#header_close#} {#header_open|@setAlignStack#} -

{#syntax#}@setAlignStack(comptime alignment: u29){#endsyntax#}
+
{#syntax#}@setAlignStack(comptime alignment: u29) void{#endsyntax#}

Ensures that a function will have a stack alignment of at least {#syntax#}alignment{#endsyntax#} bytes.

{#header_close#} {#header_open|@setCold#} -
{#syntax#}@setCold(comptime is_cold: bool){#endsyntax#}
+
{#syntax#}@setCold(comptime is_cold: bool) void{#endsyntax#}

Tells the optimizer that a function is rarely called.

{#header_close#} {#header_open|@setEvalBranchQuota#} -
{#syntax#}@setEvalBranchQuota(comptime new_quota: u32){#endsyntax#}
+
{#syntax#}@setEvalBranchQuota(comptime new_quota: u32) void{#endsyntax#}

Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error. @@ -8930,7 +8930,7 @@ test "foo" { {#header_close#} {#header_open|@setFloatMode#} -

{#syntax#}@setFloatMode(comptime mode: @import("std").builtin.FloatMode){#endsyntax#}
+
{#syntax#}@setFloatMode(comptime mode: @import("std").builtin.FloatMode) void{#endsyntax#}

Sets the floating point mode of the current scope. Possible values are:

From ec445fb6b8bb3f3d423cafa4f3a7860da65ca233 Mon Sep 17 00:00:00 2001 From: John Schmidt Date: Sat, 25 Feb 2023 20:44:53 +0100 Subject: [PATCH 069/216] Improve error messages for break type coercion --- src/AstGen.zig | 169 ++++++++++++++---- src/Module.zig | 2 +- src/Sema.zig | 75 +++++--- src/Zir.zig | 9 +- src/print_zir.zig | 3 +- .../incompatible sub-byte fields.zig | 2 + .../compile_errors/missing_else_clause.zig | 2 + .../missing_result_type_for_phi_node.zig | 2 + .../unused_value_in_switch_in_loop.zig | 2 + 9 files changed, 199 insertions(+), 67 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index 182a28084f..c91303cdb1 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1280,7 +1280,7 @@ fn fnProtoExpr( defer param_gz.unstack(); const param_type = try expr(¶m_gz, scope, coerced_type_ri, param_type_node); const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); - _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); + _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); const main_tokens = tree.nodes.items(.main_token); const name_token = param.name_token orelse main_tokens[param_type_node]; const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; @@ -1991,7 +1991,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn switch (block_gz.break_result_info.rl) { .block_ptr => { - const br = try parent_gz.addBreak(break_tag, block_inst, operand); + const br = try parent_gz.addBreakWithSrcNode(break_tag, block_inst, operand, rhs); try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index }); }, .ptr => { @@ -2003,7 +2003,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); }, else => { - _ = try parent_gz.addBreak(break_tag, block_inst, operand); + _ = try parent_gz.addBreakWithSrcNode(break_tag, block_inst, operand, rhs); }, } return Zir.Inst.Ref.unreachable_value; @@ -3754,7 +3754,7 @@ fn fnDecl( defer param_gz.unstack(); const param_type = try expr(¶m_gz, params_scope, coerced_type_ri, param_type_node); const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); - _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); + _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); const main_tokens = tree.nodes.items(.main_token); const name_token = param.name_token orelse main_tokens[param_type_node]; @@ -4114,7 +4114,7 @@ fn globalVarDecl( }; // We do this at the end so that the instruction index marks the end // range of a top level declaration. - _ = try block_scope.addBreak(.break_inline, block_inst, var_inst); + _ = try block_scope.addBreakWithSrcNode(.break_inline, block_inst, var_inst, node); try block_scope.setBlockBody(block_inst); { @@ -5456,7 +5456,9 @@ fn orelseCatchExpr( condbr, cond, then_result, + node, else_result, + rhs, block, block, break_tag, @@ -5475,7 +5477,9 @@ fn finishThenElseBlock( condbr: Zir.Inst.Index, cond: Zir.Inst.Ref, then_result: Zir.Inst.Ref, + then_src_node: Ast.Node.Index, else_result: Zir.Inst.Ref, + else_src_node: Ast.Node.Index, main_block: Zir.Inst.Index, then_break_block: Zir.Inst.Index, break_tag: Zir.Inst.Tag, @@ -5498,11 +5502,11 @@ fn finishThenElseBlock( return indexToRef(main_block); }, .break_operand => { - const then_break = if (!then_no_return) try then_scope.makeBreak(break_tag, then_break_block, then_result) else 0; + const then_break = if (!then_no_return) try then_scope.makeBreakWithSrcNode(break_tag, then_break_block, then_result, then_src_node) else 0; const else_break = if (else_result == .none) try else_scope.makeBreak(break_tag, main_block, .void_value) else if (!else_no_return) - try else_scope.makeBreak(break_tag, main_block, else_result) + try else_scope.makeBreakWithSrcNode(break_tag, main_block, else_result, else_src_node) else 0; @@ -5683,7 +5687,7 @@ fn boolBinOp( defer rhs_scope.unstack(); const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs); if (!gz.refIsNoReturn(rhs)) { - _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs); + _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs); } try rhs_scope.setBoolBrBody(bool_br); @@ -5758,6 +5762,7 @@ fn ifExpr( var payload_val_scope: Scope.LocalVal = undefined; try then_scope.addDbgBlockBegin(); + const then_node = if_full.ast.then_expr; const then_sub_scope = s: { if (if_full.error_token != null) { if (if_full.payload_token) |payload_token| { @@ -5765,7 +5770,7 @@ fn ifExpr( .err_union_payload_unsafe_ptr else .err_union_payload_unsafe; - const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr); + const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node); const token_name_index = payload_token + @boolToInt(payload_is_ref); const ident_name = try astgen.identAsString(token_name_index); const token_name_str = tree.tokenSlice(token_name_index); @@ -5795,7 +5800,7 @@ fn ifExpr( const ident_bytes = tree.tokenSlice(ident_token); if (mem.eql(u8, "_", ident_bytes)) break :s &then_scope.base; - const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr); + const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node); const ident_name = try astgen.identAsString(ident_token); try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture); payload_val_scope = .{ @@ -5813,7 +5818,7 @@ fn ifExpr( } }; - const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, if_full.ast.then_expr); + const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node); if (!then_scope.endsWithNoReturn()) { block_scope.break_count += 1; } @@ -5878,7 +5883,7 @@ fn ifExpr( .result = e, }; } else .{ - .src = if_full.ast.then_expr, + .src = then_node, .result = switch (ri.rl) { // Explicitly store void to ptr result loc if there is no else branch .ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node), @@ -5897,7 +5902,9 @@ fn ifExpr( condbr, cond.bool_bit, then_result, + then_node, else_info.result, + else_info.src, block, block, break_tag, @@ -6185,6 +6192,7 @@ fn whileExpr( then_scope.instructions_top = then_scope.instructions.items.len; try then_scope.addDbgBlockBegin(); + const then_node = while_full.ast.then_expr; if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst); if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst); try then_scope.instructions.append(astgen.gpa, continue_block); @@ -6198,7 +6206,7 @@ fn whileExpr( try then_scope.addDbgBlockEnd(); continue_scope.instructions_top = continue_scope.instructions.items.len; - _ = try unusedResultExpr(&continue_scope, &continue_scope.base, while_full.ast.then_expr); + _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node); try checkUsed(parent_gz, &then_scope.base, then_sub_scope); const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; if (!continue_scope.endsWithNoReturn()) { @@ -6261,7 +6269,7 @@ fn whileExpr( .result = else_result, }; } else .{ - .src = while_full.ast.then_expr, + .src = then_node, .result = .none, }; @@ -6280,7 +6288,9 @@ fn whileExpr( condbr, cond.bool_bit, .void_value, + then_node, else_info.result, + else_info.src, loop_block, cond_block, break_tag, @@ -6468,6 +6478,7 @@ fn forExpr( }); } + var then_node = for_full.ast.then_expr; var then_scope = parent_gz.makeSubBlock(&cond_scope.base); defer then_scope.unstack(); @@ -6535,8 +6546,8 @@ fn forExpr( break :blk capture_sub_scope; }; - const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, for_full.ast.then_expr); - _ = try addEnsureResult(&then_scope, then_result, for_full.ast.then_expr); + const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node); + _ = try addEnsureResult(&then_scope, then_result, then_node); try checkUsed(parent_gz, &then_scope.base, then_sub_scope); try then_scope.addDbgBlockEnd(); @@ -6567,7 +6578,7 @@ fn forExpr( .result = else_result, }; } else .{ - .src = for_full.ast.then_expr, + .src = then_node, .result = .none, }; @@ -6587,7 +6598,9 @@ fn forExpr( condbr, cond, then_result, + then_node, else_info.result, + else_info.src, loop_block, cond_block, break_tag, @@ -6949,12 +6962,13 @@ fn switchExpr( if (dbg_var_tag_name) |some| { try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst); } - const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, case.ast.target_expr); + const target_expr_node = case.ast.target_expr; + const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node); try checkUsed(parent_gz, &case_scope.base, sub_scope); try case_scope.addDbgBlockEnd(); if (!parent_gz.refIsNoReturn(case_result)) { block_scope.break_count += 1; - _ = try case_scope.addBreak(.@"break", switch_block, case_result); + _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node); } const case_slice = case_scope.instructionsSlice(); @@ -7057,10 +7071,12 @@ fn switchExpr( .break_void => { assert(!strat.elide_store_to_block_ptr_instructions); const last_inst = payloads.items[end_index - 1]; - if (zir_tags[last_inst] == .@"break" and - zir_datas[last_inst].@"break".block_inst == switch_block) - { - zir_datas[last_inst].@"break".operand = .void_value; + if (zir_tags[last_inst] == .@"break") { + const inst_data = zir_datas[last_inst].@"break"; + const block_inst = astgen.extra.items[inst_data.payload_index]; + if (block_inst == switch_block) { + zir_datas[last_inst].@"break".operand = .void_value; + } } }, } @@ -8856,7 +8872,7 @@ fn callExpr( // `call_inst` is reused to provide the param type. arg_block.rl_ty_inst = call_inst; const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node); - _ = try arg_block.addBreak(.break_inline, call_index, arg_ref); + _ = try arg_block.addBreakWithSrcNode(.break_inline, call_index, arg_ref, param_node); const body = arg_block.instructionsSlice(); try astgen.scratch.ensureUnusedCapacity(astgen.gpa, countBodyLenAfterFixups(astgen, body)); @@ -11262,35 +11278,40 @@ const GenZir = struct { if (align_body.len != 0) { astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body)); astgen.appendBodyWithFixups(align_body); - zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index; + const inst_data = zir_datas[align_body[align_body.len - 1]].@"break"; + astgen.extra.items[inst_data.payload_index] = new_index; } else if (args.align_ref != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref)); } if (addrspace_body.len != 0) { astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body)); astgen.appendBodyWithFixups(addrspace_body); - zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index; + const inst_data = zir_datas[addrspace_body[addrspace_body.len - 1]].@"break"; + astgen.extra.items[inst_data.payload_index] = new_index; } else if (args.addrspace_ref != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref)); } if (section_body.len != 0) { astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body)); astgen.appendBodyWithFixups(section_body); - zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index; + const inst_data = zir_datas[section_body[section_body.len - 1]].@"break"; + astgen.extra.items[inst_data.payload_index] = new_index; } else if (args.section_ref != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref)); } if (cc_body.len != 0) { astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body)); astgen.appendBodyWithFixups(cc_body); - zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index; + const inst_data = zir_datas[cc_body[cc_body.len - 1]].@"break"; + astgen.extra.items[inst_data.payload_index] = new_index; } else if (args.cc_ref != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref)); } if (ret_body.len != 0) { astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body)); astgen.appendBodyWithFixups(ret_body); - zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index; + const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break"; + astgen.extra.items[inst_data.payload_index] = new_index; } else if (ret_ref != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref)); } @@ -11344,7 +11365,9 @@ const GenZir = struct { const zir_datas = astgen.instructions.items(.data); if (ret_body.len != 0) { astgen.appendBodyWithFixups(ret_body); - zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index; + + const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break"; + astgen.extra.items[inst_data.payload_index] = new_index; } else if (ret_ref != .none) { astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref)); } @@ -11790,30 +11813,104 @@ const GenZir = struct { fn addBreak( gz: *GenZir, tag: Zir.Inst.Tag, - break_block: Zir.Inst.Index, + block_inst: Zir.Inst.Index, operand: Zir.Inst.Ref, ) !Zir.Inst.Index { - return gz.addAsIndex(.{ + const gpa = gz.astgen.gpa; + try gz.instructions.ensureUnusedCapacity(gpa, 1); + try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); + + const extra: Zir.Inst.Break = .{ + .block_inst = block_inst, + .operand_src_node = Zir.Inst.Break.no_src_node, + }; + const payload_index = try gz.astgen.addExtra(extra); + const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); + gz.astgen.instructions.appendAssumeCapacity(.{ .tag = tag, .data = .{ .@"break" = .{ - .block_inst = break_block, .operand = operand, + .payload_index = payload_index, } }, }); + gz.instructions.appendAssumeCapacity(new_index); + return new_index; } fn makeBreak( gz: *GenZir, tag: Zir.Inst.Tag, - break_block: Zir.Inst.Index, + block_inst: Zir.Inst.Index, operand: Zir.Inst.Ref, ) !Zir.Inst.Index { + const gpa = gz.astgen.gpa; + try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); + + const extra: Zir.Inst.Break = .{ + .block_inst = block_inst, + .operand_src_node = Zir.Inst.Break.no_src_node, + }; + const payload_index = try gz.astgen.addExtra(extra); const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); - try gz.astgen.instructions.append(gz.astgen.gpa, .{ + gz.astgen.instructions.appendAssumeCapacity(.{ .tag = tag, .data = .{ .@"break" = .{ - .block_inst = break_block, .operand = operand, + .payload_index = payload_index, + } }, + }); + return new_index; + } + + fn addBreakWithSrcNode( + gz: *GenZir, + tag: Zir.Inst.Tag, + block_inst: Zir.Inst.Index, + operand: Zir.Inst.Ref, + operand_src_node: Ast.Node.Index, + ) !Zir.Inst.Index { + const gpa = gz.astgen.gpa; + try gz.instructions.ensureUnusedCapacity(gpa, 1); + try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); + + const extra: Zir.Inst.Break = .{ + .block_inst = block_inst, + .operand_src_node = gz.nodeIndexToRelative(operand_src_node), + }; + const payload_index = try gz.astgen.addExtra(extra); + const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); + gz.astgen.instructions.appendAssumeCapacity(.{ + .tag = tag, + .data = .{ .@"break" = .{ + .operand = operand, + .payload_index = payload_index, + } }, + }); + gz.instructions.appendAssumeCapacity(new_index); + return new_index; + } + + fn makeBreakWithSrcNode( + gz: *GenZir, + tag: Zir.Inst.Tag, + block_inst: Zir.Inst.Index, + operand: Zir.Inst.Ref, + operand_src_node: Ast.Node.Index, + ) !Zir.Inst.Index { + const gpa = gz.astgen.gpa; + try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); + + const extra: Zir.Inst.Break = .{ + .block_inst = block_inst, + .operand_src_node = gz.nodeIndexToRelative(operand_src_node), + }; + const payload_index = try gz.astgen.addExtra(extra); + const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); + gz.astgen.instructions.appendAssumeCapacity(.{ + .tag = tag, + .data = .{ .@"break" = .{ + .operand = operand, + .payload_index = payload_index, } }, }); return new_index; diff --git a/src/Module.zig b/src/Module.zig index 17016865d1..906bde95c7 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5949,7 +5949,7 @@ pub const PeerTypeCandidateSrc = union(enum) { none: void, /// When we want to know the the src of candidate i, look up at /// index i in this slice - override: []LazySrcLoc, + override: []?LazySrcLoc, /// resolvePeerTypes originates from a @TypeOf(...) call typeof_builtin_call_node_offset: i32, diff --git a/src/Sema.zig b/src/Sema.zig index d01535cdaa..13327657a8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -349,6 +349,16 @@ pub const Block = struct { /// if we need to add type coercion at the end of block analysis. /// Same indexes, capacity, length as `results`. br_list: std.ArrayListUnmanaged(Air.Inst.Index), + /// Keeps the source location of the rhs operand of the break instruction, + /// to enable more precise compile errors. + /// Same indexes, capacity, length as `results`. + src_locs: std.ArrayListUnmanaged(?LazySrcLoc), + + pub fn deinit(merges: *@This(), allocator: mem.Allocator) void { + merges.results.deinit(allocator); + merges.br_list.deinit(allocator); + merges.src_locs.deinit(allocator); + } }; /// For debugging purposes. @@ -722,8 +732,7 @@ const LabeledBlock = struct { fn destroy(lb: *LabeledBlock, gpa: Allocator) void { lb.block.instructions.deinit(gpa); - lb.label.merges.results.deinit(gpa); - lb.label.merges.br_list.deinit(gpa); + lb.label.merges.deinit(gpa); gpa.destroy(lb); } }; @@ -777,8 +786,9 @@ fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.In error.ComptimeBreak => { const zir_datas = sema.code.instructions.items(.data); const break_data = zir_datas[sema.comptime_break_inst].@"break"; + const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; try sema.addRuntimeBreak(block, .{ - .block_inst = break_data.block_inst, + .block_inst = extra.block_inst, .operand = break_data.operand, .inst = sema.comptime_break_inst, }); @@ -817,8 +827,9 @@ pub fn analyzeBodyBreak( sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn()) return null; const break_data = sema.code.instructions.items(.data)[break_inst].@"break"; + const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; return BreakData{ - .block_inst = break_data.block_inst, + .block_inst = extra.block_inst, .operand = break_data.operand, .inst = break_inst, }; @@ -5238,6 +5249,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError var label: Block.Label = .{ .zir_block = inst, .merges = .{ + .src_locs = .{}, .results = .{}, .br_list = .{}, .block_inst = block_inst, @@ -5251,8 +5263,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError const merges = &child_block.label.?.merges; defer child_block.instructions.deinit(gpa); - defer merges.results.deinit(gpa); - defer merges.br_list.deinit(gpa); + defer merges.deinit(gpa); var loop_block = child_block.makeSubBlock(); defer loop_block.instructions.deinit(gpa); @@ -5422,6 +5433,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro var label: Block.Label = .{ .zir_block = inst, .merges = .{ + .src_locs = .{}, .results = .{}, .br_list = .{}, .block_inst = block_inst, @@ -5450,8 +5462,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro }; defer child_block.instructions.deinit(gpa); - defer label.merges.results.deinit(gpa); - defer label.merges.br_list.deinit(gpa); + defer label.merges.deinit(gpa); return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges); } @@ -5480,7 +5491,8 @@ fn resolveBlockBody( const break_inst = sema.comptime_break_inst; const break_data = sema.code.instructions.items(.data)[break_inst].@"break"; - if (break_data.block_inst == body_inst) { + const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; + if (extra.block_inst == body_inst) { return try sema.resolveInst(break_data.operand); } else { return error.ComptimeBreak; @@ -5533,7 +5545,7 @@ fn analyzeBlockBody( // Need to set the type and emit the Block instruction. This allows machine code generation // to emit a jump instruction to after the block when it encounters the break. try parent_block.instructions.append(gpa, merges.block_inst); - const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none); + const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items }); // TODO add note "missing else causes void value" const type_src = src; // TODO: better source location @@ -5842,14 +5854,20 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[inst].@"break"; + const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data; const operand = try sema.resolveInst(inst_data.operand); - const zir_block = inst_data.block_inst; + const zir_block = extra.block_inst; var block = start_block; while (true) { if (block.label) |label| { if (label.zir_block == zir_block) { const br_ref = try start_block.addBr(label.merges.block_inst, operand); + const src_loc = if (extra.operand_src_node != Zir.Inst.Break.no_src_node) + LazySrcLoc.nodeOffset(extra.operand_src_node) + else + null; + try label.merges.src_locs.append(sema.gpa, src_loc); try label.merges.results.append(sema.gpa, operand); try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?); block.runtime_index.increment(); @@ -6643,6 +6661,7 @@ fn analyzeCall( .func = null, .comptime_result = undefined, .merges = .{ + .src_locs = .{}, .results = .{}, .br_list = .{}, .block_inst = block_inst, @@ -6692,8 +6711,7 @@ fn analyzeCall( const merges = &child_block.inlining.?.merges; defer child_block.instructions.deinit(gpa); - defer merges.results.deinit(gpa); - defer merges.br_list.deinit(gpa); + defer merges.deinit(gpa); // If it's a comptime function call, we need to memoize it as long as no external // comptime memory is mutated. @@ -10780,6 +10798,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError var label: Block.Label = .{ .zir_block = inst, .merges = .{ + .src_locs = .{}, .results = .{}, .br_list = .{}, .block_inst = block_inst, @@ -10807,8 +10826,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError }; const merges = &child_block.label.?.merges; defer child_block.instructions.deinit(gpa); - defer merges.results.deinit(gpa); - defer merges.br_list.deinit(gpa); + defer merges.deinit(gpa); if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| { var extra_index: usize = special.end; @@ -12298,7 +12316,7 @@ fn zirBitwise( try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; - const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); + const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); const scalar_type = resolved_type.scalarType(); const scalar_tag = scalar_type.zigTypeTag(); @@ -12502,7 +12520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai try trash_block.addBitCast(rhs_info.elem_type, .void_value), }; break :t try sema.resolvePeerTypes(block, src, &instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); }; @@ -13002,7 +13020,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const is_vector = resolved_type.zigTypeTag() == .Vector; @@ -13162,7 +13180,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const is_vector = resolved_type.zigTypeTag() == .Vector; @@ -13325,7 +13343,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const is_vector = resolved_type.zigTypeTag() == .Vector; @@ -13441,7 +13459,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const is_vector = resolved_type.zigTypeTag() == .Vector; @@ -13683,7 +13701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const is_vector = resolved_type.zigTypeTag() == .Vector; @@ -13866,7 +13884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); @@ -13968,7 +13986,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); @@ -14081,7 +14099,7 @@ fn zirOverflowArithmetic( lhs_ty else try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const rhs_dest_ty = if (zir_tag == .shl_with_overflow) @@ -14312,7 +14330,7 @@ fn analyzeArithmetic( const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const is_vector = resolved_type.zigTypeTag() == .Vector; @@ -15200,7 +15218,7 @@ fn analyzeCmp( return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src); } const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; - const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); + const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); if (!resolved_type.isSelfComparable(is_equality_cmp)) { return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{ compareOperatorName(op), resolved_type.fmt(sema.mod), @@ -17024,6 +17042,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi .label = .{ .zir_block = break_data.block_inst, .merges = .{ + .src_locs = .{}, .results = .{}, .br_list = .{}, .block_inst = new_block_inst, @@ -20605,7 +20624,7 @@ fn checkSimdBinOp( try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null; const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{ - .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src); const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src); diff --git a/src/Zir.zig b/src/Zir.zig index 001c4e8101..bc5202c8aa 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -2603,8 +2603,8 @@ pub const Inst = struct { } }, @"break": struct { - block_inst: Index, operand: Ref, + payload_index: u32, }, switch_capture: struct { switch_inst: Index, @@ -2690,6 +2690,13 @@ pub const Inst = struct { }; }; + pub const Break = struct { + pub const no_src_node = std.math.maxInt(i32); + + block_inst: Index, + operand_src_node: i32, + }; + /// Trailing: /// 0. Output for every outputs_len /// 1. Input for every inputs_len diff --git a/src/print_zir.zig b/src/print_zir.zig index 5e7d0d45de..755107cd1a 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -2321,8 +2321,9 @@ const Writer = struct { fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { const inst_data = self.code.instructions.items(.data)[inst].@"break"; + const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data; - try self.writeInstIndex(stream, inst_data.block_inst); + try self.writeInstIndex(stream, extra.block_inst); try stream.writeAll(", "); try self.writeInstRef(stream, inst_data.operand); try stream.writeAll(")"); diff --git a/test/cases/compile_errors/incompatible sub-byte fields.zig b/test/cases/compile_errors/incompatible sub-byte fields.zig index d765b7cf45..dc6f715c2f 100644 --- a/test/cases/compile_errors/incompatible sub-byte fields.zig +++ b/test/cases/compile_errors/incompatible sub-byte fields.zig @@ -25,3 +25,5 @@ export fn entry() void { // target=native // // :14:17: error: incompatible types: '*align(1:0:1) u2' and '*align(2:8:2) u2' +// :15:14: note: type '*align(1:0:1) u2' here +// :16:14: note: type '*align(2:8:2) u2' here diff --git a/test/cases/compile_errors/missing_else_clause.zig b/test/cases/compile_errors/missing_else_clause.zig index 2e5fe9318f..a27408cb4c 100644 --- a/test/cases/compile_errors/missing_else_clause.zig +++ b/test/cases/compile_errors/missing_else_clause.zig @@ -31,7 +31,9 @@ export fn entry() void { // target=native // // :2:21: error: incompatible types: 'i32' and 'void' +// :6:25: note: type 'i32' here // :6:15: error: incompatible types: 'i32' and 'void' +// :2:31: note: type 'i32' here // :12:16: error: expected type 'tmp.h.T', found 'void' // :11:15: note: struct declared here // :18:9: error: incompatible types: 'void' and 'tmp.k.T' diff --git a/test/cases/compile_errors/missing_result_type_for_phi_node.zig b/test/cases/compile_errors/missing_result_type_for_phi_node.zig index c4bd686b01..9e460ececb 100644 --- a/test/cases/compile_errors/missing_result_type_for_phi_node.zig +++ b/test/cases/compile_errors/missing_result_type_for_phi_node.zig @@ -10,3 +10,5 @@ export fn entry() void { // target=native // // :5:11: error: incompatible types: 'void' and 'comptime_int' +// :5:11: note: type 'void' here +// :5:17: note: type 'comptime_int' here diff --git a/test/cases/compile_errors/unused_value_in_switch_in_loop.zig b/test/cases/compile_errors/unused_value_in_switch_in_loop.zig index 830262db4d..b74e016474 100644 --- a/test/cases/compile_errors/unused_value_in_switch_in_loop.zig +++ b/test/cases/compile_errors/unused_value_in_switch_in_loop.zig @@ -12,3 +12,5 @@ export fn entry() void { // target=native // // :3:18: error: incompatible types: 'comptime_int' and 'void' +// :4:14: note: type 'comptime_int' here +// :5:16: note: type 'void' here From 0787b11f19917ab4ae994cd12bc8ac5c96311683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Fro=C5=82ow?= Date: Tue, 21 Mar 2023 14:12:13 +0100 Subject: [PATCH 070/216] naming: mid for index and mid_item for item --- lib/std/sort.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/std/sort.zig b/lib/std/sort.zig index 405ab658d1..d2b79db91b 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -9,7 +9,7 @@ pub fn binarySearch( key: anytype, items: []const T, context: anytype, - comptime compareFn: fn (context: @TypeOf(context), key: @TypeOf(key), mid: T) math.Order, + comptime compareFn: fn (context: @TypeOf(context), key: @TypeOf(key), mid_item: T) math.Order, ) ?usize { var left: usize = 0; var right: usize = items.len; @@ -79,14 +79,14 @@ test "binarySearch" { return @This(){ .b = b, .e = e }; } - fn order(context: void, key: i32, mid: @This()) math.Order { + fn order(context: void, key: i32, mid_item: @This()) math.Order { _ = context; - if (key < mid.b) { + if (key < mid_item.b) { return .lt; } - if (key > mid.e) { + if (key > mid_item.e) { return .gt; } @@ -1069,8 +1069,8 @@ fn binaryFirst( const offset = size % 2; size /= 2; - const mid = items[curr + size]; - if (lessThan(context, mid, value)) { + const mid_item = items[curr + size]; + if (lessThan(context, mid_item, value)) { curr += size + offset; } } @@ -1092,8 +1092,8 @@ fn binaryLast( const offset = size % 2; size /= 2; - const mid = items[curr + size]; - if (!lessThan(context, value, mid)) { + const mid_item = items[curr + size]; + if (!lessThan(context, value, mid_item)) { curr += size + offset; } } From 83352678d433c9ffbda23b88066f628ab9d1c76d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 14:30:30 +0100 Subject: [PATCH 071/216] macho+zld: put __TEXT bound sections in __TEXT segment --- src/link/MachO/zld.zig | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 17d122b30d..7a15782ae6 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -477,9 +477,9 @@ pub const Zld = struct { mem.eql(u8, sectname, "__gosymtab") or mem.eql(u8, sectname, "__gopclntab")) { - break :blk self.getSectionByName("__DATA_CONST", "__const") orelse try self.initSection( - "__DATA_CONST", - "__const", + break :blk self.getSectionByName("__TEXT", sectname) orelse try self.initSection( + "__TEXT", + sectname, .{}, ); } @@ -490,15 +490,13 @@ pub const Zld = struct { mem.eql(u8, sectname, "__objc_classlist") or mem.eql(u8, sectname, "__objc_imageinfo")) { - break :blk self.getSectionByName("__DATA_CONST", sectname) orelse - try self.initSection( + break :blk self.getSectionByName("__DATA_CONST", sectname) orelse try self.initSection( "__DATA_CONST", sectname, .{}, ); } else if (mem.eql(u8, sectname, "__data")) { - break :blk self.getSectionByName("__DATA", "__data") orelse - try self.initSection( + break :blk self.getSectionByName("__DATA", "__data") orelse try self.initSection( "__DATA", "__data", .{}, From cb34d6f4362c8f5d806c0d0b328ea29e877d5c5f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 14:43:02 +0100 Subject: [PATCH 072/216] macho+zld: put locals and globals in function-starts section --- src/link/MachO/zld.zig | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 7a15782ae6..845a12276f 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -2298,9 +2298,16 @@ pub const Zld = struct { const asc_u64 = std.sort.asc(u64); + fn addSymbolToFunctionStarts(self: *Zld, sym_loc: SymbolWithLoc, addresses: *std.ArrayList(u64)) !void { + const sym = self.getSymbol(sym_loc); + if (sym.n_strx == 0) return; + if (sym.n_desc == N_DEAD) return; + if (self.symbolIsTemp(sym_loc)) return; + try addresses.append(sym.n_value); + } + fn writeFunctionStarts(self: *Zld) !void { const text_seg_index = self.getSegmentByName("__TEXT") orelse return; - const text_sect_index = self.getSectionByName("__TEXT", "__text") orelse return; const text_seg = self.segments.items[text_seg_index]; const gpa = self.gpa; @@ -2308,17 +2315,18 @@ pub const Zld = struct { // We need to sort by address first var addresses = std.ArrayList(u64).init(gpa); defer addresses.deinit(); - try addresses.ensureTotalCapacityPrecise(self.globals.items.len); - for (self.globals.items) |global| { - const sym = self.getSymbol(global); - if (sym.undf()) continue; - if (sym.n_desc == N_DEAD) continue; + for (self.objects.items) |object| { + for (object.exec_atoms.items) |atom_index| { + const atom = self.getAtom(atom_index); + const sym_loc = atom.getSymbolWithLoc(); + try self.addSymbolToFunctionStarts(sym_loc, &addresses); - const sect_id = sym.n_sect - 1; - if (sect_id != text_sect_index) continue; - - addresses.appendAssumeCapacity(sym.n_value); + var it = Atom.getInnerSymbolsIterator(self, atom_index); + while (it.next()) |inner_sym_loc| { + try self.addSymbolToFunctionStarts(inner_sym_loc, &addresses); + } + } } std.sort.sort(u64, addresses.items, {}, asc_u64); @@ -2457,6 +2465,7 @@ pub const Zld = struct { fn addLocalToSymtab(self: *Zld, sym_loc: SymbolWithLoc, locals: *std.ArrayList(macho.nlist_64)) !void { const sym = self.getSymbol(sym_loc); if (sym.n_strx == 0) return; // no name, skip + if (sym.n_desc == N_DEAD) return; // garbage-collected, skip if (sym.ext()) return; // an export lands in its own symtab section, skip if (self.symbolIsTemp(sym_loc)) return; // local temp symbol, skip From dc98009e36a344f8d0330af6b9e9226a2ba6a474 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 16:12:25 +0100 Subject: [PATCH 073/216] macho+zld: save all defined globals in the export trie --- src/link/MachO/zld.zig | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 845a12276f..fe0ab16c92 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -2141,35 +2141,18 @@ pub const Zld = struct { const exec_segment = self.segments.items[segment_index]; const base_address = exec_segment.vmaddr; - if (self.options.output_mode == .Exe) { - for (&[_]SymbolWithLoc{ - self.getEntryPoint(), - self.globals.items[self.mh_execute_header_index.?], - }) |global| { - const sym = self.getSymbol(global); - const sym_name = self.getSymbolName(global); - log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); - try trie.put(gpa, .{ - .name = sym_name, - .vmaddr_offset = sym.n_value - base_address, - .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, - }); - } - } else { - assert(self.options.output_mode == .Lib); - for (self.globals.items) |global| { - const sym = self.getSymbol(global); - if (sym.undf()) continue; - if (sym.n_desc == N_DEAD) continue; + for (self.globals.items) |global| { + const sym = self.getSymbol(global); + if (sym.undf()) continue; + if (sym.n_desc == N_DEAD) continue; - const sym_name = self.getSymbolName(global); - log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); - try trie.put(gpa, .{ - .name = sym_name, - .vmaddr_offset = sym.n_value - base_address, - .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, - }); - } + const sym_name = self.getSymbolName(global); + log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); + try trie.put(gpa, .{ + .name = sym_name, + .vmaddr_offset = sym.n_value - base_address, + .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, + }); } try trie.finalize(gpa); From 87e07d8671b469431340c615dcdd5a5332d198ec Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 21 Mar 2023 20:57:14 +0200 Subject: [PATCH 074/216] fix broken test cases exposed by ec445fb6b8bb3f3d423cafa4f3a7860da65ca233 shoulda rebased --- test/cases/compile_errors/for_loop_break_value_ignored.zig | 1 + test/cases/compile_errors/missing_else_clause.zig | 4 ++-- test/cases/compile_errors/while_loop_break_value_ignored.zig | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/cases/compile_errors/for_loop_break_value_ignored.zig b/test/cases/compile_errors/for_loop_break_value_ignored.zig index a1119ec651..76a8c091f5 100644 --- a/test/cases/compile_errors/for_loop_break_value_ignored.zig +++ b/test/cases/compile_errors/for_loop_break_value_ignored.zig @@ -13,3 +13,4 @@ export fn f1() void { // target=native // // :6:5: error: incompatible types: 'usize' and 'void' +// :7:22: note: type 'usize' here diff --git a/test/cases/compile_errors/missing_else_clause.zig b/test/cases/compile_errors/missing_else_clause.zig index a27408cb4c..e96363b9cd 100644 --- a/test/cases/compile_errors/missing_else_clause.zig +++ b/test/cases/compile_errors/missing_else_clause.zig @@ -31,9 +31,9 @@ export fn entry() void { // target=native // // :2:21: error: incompatible types: 'i32' and 'void' -// :6:25: note: type 'i32' here -// :6:15: error: incompatible types: 'i32' and 'void' // :2:31: note: type 'i32' here +// :6:15: error: incompatible types: 'i32' and 'void' +// :6:25: note: type 'i32' here // :12:16: error: expected type 'tmp.h.T', found 'void' // :11:15: note: struct declared here // :18:9: error: incompatible types: 'void' and 'tmp.k.T' diff --git a/test/cases/compile_errors/while_loop_break_value_ignored.zig b/test/cases/compile_errors/while_loop_break_value_ignored.zig index 2d14693fe5..e2f81d2b5f 100644 --- a/test/cases/compile_errors/while_loop_break_value_ignored.zig +++ b/test/cases/compile_errors/while_loop_break_value_ignored.zig @@ -23,4 +23,6 @@ export fn f2() void { // target=native // // :7:5: error: incompatible types: 'usize' and 'void' +// :8:22: note: type 'usize' here // :14:12: error: incompatible types: 'usize' and 'void' +// :16:33: note: type 'usize' here From 1be86218153ae77109d785aafb29430f787adefd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 21:27:17 +0100 Subject: [PATCH 075/216] macho+zld: when finding by address, note the end of section symbols too Previously, if we were looking for the very last symbol by address in some section, and the next symbol happened to also have the same address value but would reside in a different section, we would keep going finding the wrong symbol in the wrong section. This mechanism turns out vital for correct linking of Go binaries where the runtime looks for specially crafted synthetic symbols which mark the beginning and end of each section. In this case, we had an unfortunate clash between the end of PC marked machine code section (`_runtime.etext`) and beginning of read-only data (`_runtime.rodata`). --- src/link/MachO/Object.zig | 66 +++++++++++++++++++++----------------- src/link/MachO/ZldAtom.zig | 3 +- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index fdcdb47224..a3e322179d 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -50,7 +50,7 @@ reverse_symtab_lookup: []u32 = undefined, /// Can be undefined as set together with in_symtab. source_address_lookup: []i64 = undefined, /// Can be undefined as set together with in_symtab. -source_section_index_lookup: []i64 = undefined, +source_section_index_lookup: []Entry = undefined, /// Can be undefined as set together with in_symtab. strtab_lookup: []u32 = undefined, /// Can be undefined as set together with in_symtab. @@ -58,7 +58,7 @@ atom_by_index_table: []AtomIndex = undefined, /// Can be undefined as set together with in_symtab. globals_lookup: []i64 = undefined, /// Can be undefined as set together with in_symtab. -relocs_lookup: []RelocEntry = undefined, +relocs_lookup: []Entry = undefined, /// All relocations sorted and flatened, sorted by address descending /// per section. @@ -81,11 +81,14 @@ unwind_info_sect_id: ?u8 = null, unwind_relocs_lookup: []Record = undefined, unwind_records_lookup: std.AutoHashMapUnmanaged(AtomIndex, u32) = .{}, -const RelocEntry = struct { start: u32, len: u32 }; +const Entry = struct { + start: u32 = 0, + len: u32 = 0, +}; const Record = struct { dead: bool, - reloc: RelocEntry, + reloc: Entry, }; pub fn deinit(self: *Object, gpa: Allocator) void { @@ -170,11 +173,11 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) self.strtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len); self.globals_lookup = try allocator.alloc(i64, self.in_symtab.?.len); self.atom_by_index_table = try allocator.alloc(AtomIndex, self.in_symtab.?.len + nsects); - self.relocs_lookup = try allocator.alloc(RelocEntry, self.in_symtab.?.len + nsects); + self.relocs_lookup = try allocator.alloc(Entry, self.in_symtab.?.len + nsects); // This is wasteful but we need to be able to lookup source symbol address after stripping and // allocating of sections. self.source_address_lookup = try allocator.alloc(i64, self.in_symtab.?.len); - self.source_section_index_lookup = try allocator.alloc(i64, nsects); + self.source_section_index_lookup = try allocator.alloc(Entry, nsects); for (self.symtab) |*sym| { sym.* = .{ @@ -188,11 +191,8 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) mem.set(i64, self.globals_lookup, -1); mem.set(AtomIndex, self.atom_by_index_table, 0); - mem.set(i64, self.source_section_index_lookup, -1); - mem.set(RelocEntry, self.relocs_lookup, .{ - .start = 0, - .len = 0, - }); + mem.set(Entry, self.source_section_index_lookup, .{}); + mem.set(Entry, self.relocs_lookup, .{}); // You would expect that the symbol table is at least pre-sorted based on symbol's type: // local < extern defined < undefined. Unfortunately, this is not guaranteed! For instance, @@ -211,12 +211,24 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) // is kind enough to specify the symbols in the correct order. sort.sort(SymbolAtIndex, sorted_all_syms.items, self, SymbolAtIndex.lessThan); + var prev_sect_id: u8 = 0; + var section_index_lookup: ?Entry = null; for (sorted_all_syms.items, 0..) |sym_id, i| { const sym = sym_id.getSymbol(self); - if (sym.sect() and self.source_section_index_lookup[sym.n_sect - 1] == -1) { - self.source_section_index_lookup[sym.n_sect - 1] = @intCast(i64, i); + if (section_index_lookup) |*lookup| { + if (sym.n_sect != prev_sect_id or sym.undf()) { + self.source_section_index_lookup[prev_sect_id - 1] = lookup.*; + section_index_lookup = null; + } else { + lookup.len += 1; + } } + if (sym.sect() and section_index_lookup == null) { + section_index_lookup = .{ .start = @intCast(u32, i), .len = 1 }; + } + + prev_sect_id = sym.n_sect; self.symtab[i] = sym; self.source_symtab_lookup[i] = sym_id.index; @@ -234,13 +246,7 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) self.unwind_info_sect_id = self.getSourceSectionIndexByName("__LD", "__compact_unwind"); if (self.hasUnwindRecords()) { self.unwind_relocs_lookup = try allocator.alloc(Record, self.getUnwindRecords().len); - mem.set(Record, self.unwind_relocs_lookup, .{ - .dead = true, - .reloc = .{ - .start = 0, - .len = 0, - }, - }); + mem.set(Record, self.unwind_relocs_lookup, .{ .dead = true, .reloc = .{} }); } } @@ -620,7 +626,7 @@ fn filterRelocs( relocs: []align(1) const macho.relocation_info, start_addr: u64, end_addr: u64, -) RelocEntry { +) Entry { const Predicate = struct { addr: u64, @@ -712,9 +718,9 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { while (try it.next()) |record| { const offset = it.pos - record.getSize(); - const rel_pos = switch (cpu_arch) { + const rel_pos: Entry = switch (cpu_arch) { .aarch64 => filterRelocs(relocs, offset, offset + record.getSize()), - .x86_64 => RelocEntry{ .start = 0, .len = 0 }, + .x86_64 => .{}, else => unreachable, }; self.eh_frame_relocs_lookup.putAssumeCapacityNoClobber(offset, .{ @@ -990,13 +996,15 @@ pub fn getSymbolByAddress(self: Object, addr: u64, sect_hint: ?u8) u32 { }; if (sect_hint) |sect_id| { - if (self.source_section_index_lookup[sect_id] > -1) { - const first_sym_index = @intCast(usize, self.source_section_index_lookup[sect_id]); - const target_sym_index = @import("zld.zig").lsearch(i64, self.source_address_lookup[first_sym_index..], Predicate{ - .addr = @intCast(i64, addr), - }); + if (self.source_section_index_lookup[sect_id].len > 0) { + const lookup = self.source_section_index_lookup[sect_id]; + const target_sym_index = @import("zld.zig").lsearch( + i64, + self.source_address_lookup[lookup.start..][0..lookup.len], + Predicate{ .addr = @intCast(i64, addr) }, + ); if (target_sym_index > 0) { - return @intCast(u32, first_sym_index + target_sym_index - 1); + return @intCast(u32, lookup.start + target_sym_index - 1); } } return self.getSectionAliasSymbolIndex(sect_id); diff --git a/src/link/MachO/ZldAtom.zig b/src/link/MachO/ZldAtom.zig index e3d5f62a12..eb5e1c6ded 100644 --- a/src/link/MachO/ZldAtom.zig +++ b/src/link/MachO/ZldAtom.zig @@ -790,10 +790,11 @@ fn resolveRelocsX86( const target = parseRelocTarget(zld, atom_index, rel); const rel_offset = @intCast(u32, rel.r_address - context.base_offset); - log.debug(" RELA({s}) @ {x} => %{d} in object({?})", .{ + log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{ @tagName(rel_type), rel.r_address, target.sym_index, + zld.getSymbolName(target), target.getFile(), }); From 8bffe87e9eeaf602d06eec60dffc955a86228fbd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 Mar 2023 21:31:24 +0100 Subject: [PATCH 076/216] macho: collect all exports into the export trie --- src/link/MachO.zig | 39 +++++++++++---------------------------- src/link/MachO/zld.zig | 4 +--- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 151b947141..2f594d1fda 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3340,36 +3340,19 @@ fn collectExportData(self: *MachO, trie: *Trie) !void { const exec_segment = self.segments.items[self.header_segment_cmd_index.?]; const base_address = exec_segment.vmaddr; - if (self.base.options.output_mode == .Exe) { - for (&[_]SymbolWithLoc{ - try self.getEntryPoint(), - self.getGlobal("__mh_execute_header").?, - }) |global| { - const sym = self.getSymbol(global); - const sym_name = self.getSymbolName(global); - log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); - try trie.put(gpa, .{ - .name = sym_name, - .vmaddr_offset = sym.n_value - base_address, - .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, - }); - } - } else { - assert(self.base.options.output_mode == .Lib); - for (self.globals.items) |global| { - const sym = self.getSymbol(global); + for (self.globals.items) |global| { + const sym = self.getSymbol(global); - if (sym.undf()) continue; - if (!sym.ext()) continue; + if (sym.undf()) continue; + if (!sym.ext()) continue; - const sym_name = self.getSymbolName(global); - log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); - try trie.put(gpa, .{ - .name = sym_name, - .vmaddr_offset = sym.n_value - base_address, - .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, - }); - } + const sym_name = self.getSymbolName(global); + log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); + try trie.put(gpa, .{ + .name = sym_name, + .vmaddr_offset = sym.n_value - base_address, + .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, + }); } try trie.finalize(gpa); diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index fe0ab16c92..27a0fa5579 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -2158,9 +2158,7 @@ pub const Zld = struct { try trie.finalize(gpa); } - fn writeDyldInfoData( - self: *Zld, - ) !void { + fn writeDyldInfoData(self: *Zld) !void { const gpa = self.gpa; var rebase = Rebase{}; From 84b89d7cfe452f91fa22f2646ef53a3a7e990456 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Wed, 22 Mar 2023 07:17:52 +0100 Subject: [PATCH 077/216] crypto.hmac: set the recommended key size to the block size (#15031) HMAC supports arbitrary key sizes, and there are no practical reasons to use more than 256 bit keys. It still makes sense to match the security level, though, especially since a distinction between the block size and the key size can be confusing. Using HMAC.key_size instead of HMAC.mac_size caused our TLS implementation to compute wrong shared secrets when SHA-384 was used. So, fix it directly in `crypto.hmac` in order to prevent other misuses. --- lib/std/crypto/hmac.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 457cc5ec18..f279132ee8 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -18,7 +18,7 @@ pub fn Hmac(comptime Hash: type) type { const Self = @This(); pub const mac_length = Hash.digest_length; pub const key_length_min = 0; - pub const key_length = 32; // recommended key length + pub const key_length = mac_length; // recommended key length o_key_pad: [Hash.block_length]u8, hash: Hash, From cc44183787adde8b83f9373dd53250f154058dc4 Mon Sep 17 00:00:00 2001 From: xEgoist Date: Tue, 21 Mar 2023 09:03:50 -0500 Subject: [PATCH 078/216] Implemented getMaxRss for Windows In Windows, the equivalent to maxrss is PeakWorkingSetSize which is found in PROCESS_MEMORY_COUNTERS in bytes. Currently, this is done by calling `GetProcessMemoryInfo` in kernel32. --- lib/std/child_process.zig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 3748ca6877..72d7be4451 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -99,12 +99,20 @@ pub const ChildProcess = struct { return null; } }, + .windows => { + if (rus.rusage) |ru| { + return ru.PeakWorkingSetSize; + } else { + return null; + } + }, else => return null, } } const rusage_init = switch (builtin.os.tag) { .linux => @as(?std.os.rusage, null), + .windows => @as(?windows.PROCESS_MEMORY_COUNTERS, null), else => {}, }; }; @@ -364,6 +372,13 @@ pub const ChildProcess = struct { } }); + if (self.request_resource_usage_statistics) { + var pmc: windows.PROCESS_MEMORY_COUNTERS = undefined; + if (windows.kernel32.K32GetProcessMemoryInfo(self.id, &pmc, @sizeOf(windows.PROCESS_MEMORY_COUNTERS)) != 0) { + self.resource_usage_statistics.rusage = pmc; + } + } + os.close(self.id); os.close(self.thread_handle); self.cleanupStreams(); From 70469d428dd94693295b320a975b1ddf904dda3b Mon Sep 17 00:00:00 2001 From: xEgoist Date: Wed, 22 Mar 2023 05:57:14 -0500 Subject: [PATCH 079/216] Implemented Zig wrapper for `GetProcessMemoryInfo` `GetProcessMemoryInfo` is implemented using `NtQueryInformationProcess` with `ProcessVmCounters` to obtain `VM_COUNTERS`. The structs, enum definitions are found in `winternl.h` or `ntddk.h` in the latest WDK. This should give the same results as using `K32GetProcessMemoryInfo` --- lib/std/child_process.zig | 6 ++-- lib/std/os/windows.zig | 45 ++++++++++++++++++++++++++ lib/std/os/windows/ntdll.zig | 63 ++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 72d7be4451..13fd40d982 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -137,6 +137,7 @@ pub const ChildProcess = struct { os.SetIdError || os.ChangeCurDirError || windows.CreateProcessError || + windows.GetProcessMemoryInfoError || windows.WaitForSingleObjectError; pub const Term = union(enum) { @@ -374,9 +375,8 @@ pub const ChildProcess = struct { if (self.request_resource_usage_statistics) { var pmc: windows.PROCESS_MEMORY_COUNTERS = undefined; - if (windows.kernel32.K32GetProcessMemoryInfo(self.id, &pmc, @sizeOf(windows.PROCESS_MEMORY_COUNTERS)) != 0) { - self.resource_usage_statistics.rusage = pmc; - } + try windows.GetProcessMemoryInfo(self.id, &pmc); + self.resource_usage_statistics.rusage = pmc; } os.close(self.id); diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index b385f68194..27f2ddb316 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -3947,6 +3947,20 @@ pub const PSAPI_WS_WATCH_INFORMATION = extern struct { FaultingVa: LPVOID, }; +pub const VM_COUNTERS = extern struct { + PeakVirtualSize: SIZE_T, + VirtualSize: SIZE_T, + PageFaultCount: ULONG, + PeakWorkingSetSize: SIZE_T, + WorkingSetSize: SIZE_T, + QuotaPeakPagedPoolUsage: SIZE_T, + QuotaPagedPoolUsage: SIZE_T, + QuotaPeakNonPagedPoolUsage: SIZE_T, + QuotaNonPagedPoolUsage: SIZE_T, + PagefileUsage: SIZE_T, + PeakPagefileUsage: SIZE_T, +}; + pub const PROCESS_MEMORY_COUNTERS = extern struct { cb: DWORD, PageFaultCount: DWORD, @@ -3974,6 +3988,37 @@ pub const PROCESS_MEMORY_COUNTERS_EX = extern struct { PrivateUsage: SIZE_T, }; +pub const GetProcessMemoryInfoError = error{ + AccessDenied, + InvalidHandle, + Unexpected, +}; + +pub fn GetProcessMemoryInfo(hProcess: HANDLE, out: *PROCESS_MEMORY_COUNTERS) GetProcessMemoryInfoError!void { + var vmc: VM_COUNTERS = undefined; + const rc = ntdll.NtQueryInformationProcess(hProcess, .ProcessVmCounters, &vmc, @sizeOf(VM_COUNTERS), null); + switch (rc) { + .SUCCESS => { + out.* = PROCESS_MEMORY_COUNTERS{ + .cb = @sizeOf(PROCESS_MEMORY_COUNTERS), + .PageFaultCount = vmc.PageFaultCount, + .PeakWorkingSetSize = vmc.PeakWorkingSetSize, + .WorkingSetSize = vmc.WorkingSetSize, + .QuotaPeakPagedPoolUsage = vmc.QuotaPeakPagedPoolUsage, + .QuotaPagedPoolUsage = vmc.QuotaPagedPoolUsage, + .QuotaPeakNonPagedPoolUsage = vmc.QuotaPeakNonPagedPoolUsage, + .QuotaNonPagedPoolUsage = vmc.QuotaNonPagedPoolUsage, + .PagefileUsage = vmc.PagefileUsage, + .PeakPagefileUsage = vmc.PeakPagefileUsage, + }; + }, + .ACCESS_DENIED => return error.AccessDenied, + .INVALID_HANDLE => return error.InvalidHandle, + .INVALID_PARAMETER => unreachable, + else => return unexpectedStatus(rc), + } +} + pub const PERFORMANCE_INFORMATION = extern struct { cb: DWORD, CommitTotal: SIZE_T, diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 58cba356a2..3916e7d178 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -32,6 +32,69 @@ const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION; const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS; const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE; +pub const PROCESSINFOCLASS = enum(c_int) { + ProcessBasicInformation, + ProcessQuotaLimits, + ProcessIoCounters, + ProcessVmCounters, + ProcessTimes, + ProcessBasePriority, + ProcessRaisePriority, + ProcessDebugPort, + ProcessExceptionPort, + ProcessAccessToken, + ProcessLdtInformation, + ProcessLdtSize, + ProcessDefaultHardErrorMode, + ProcessIoPortHandlers, + ProcessPooledUsageAndLimits, + ProcessWorkingSetWatch, + ProcessUserModeIOPL, + ProcessEnableAlignmentFaultFixup, + ProcessPriorityClass, + ProcessWx86Information, + ProcessHandleCount, + ProcessAffinityMask, + ProcessPriorityBoost, + ProcessDeviceMap, + ProcessSessionInformation, + ProcessForegroundInformation, + ProcessWow64Information, + ProcessImageFileName, + ProcessLUIDDeviceMapsEnabled, + ProcessBreakOnTermination, + ProcessDebugObjectHandle, + ProcessDebugFlags, + ProcessHandleTracing, + ProcessIoPriority, + ProcessExecuteFlags, + ProcessTlsInformation, + ProcessCookie, + ProcessImageInformation, + ProcessCycleTime, + ProcessPagePriority, + ProcessInstrumentationCallback, + ProcessThreadStackAllocation, + ProcessWorkingSetWatchEx, + ProcessImageFileNameWin32, + ProcessImageFileMapping, + ProcessAffinityUpdateMode, + ProcessMemoryAllocationMode, + ProcessGroupInformation, + ProcessTokenVirtualizationEnabled, + ProcessConsoleHostProcess, + ProcessWindowInformation, + MaxProcessInfoClass +}; + +pub extern "ntdll" fn NtQueryInformationProcess( + ProcessHandle: HANDLE, + ProcessInformationClass: PROCESSINFOCLASS, + ProcessInformation: *anyopaque, + ProcessInformationLength: ULONG, + ReturnLength: ?*ULONG, +) callconv(WINAPI) NTSTATUS; + pub const THREADINFOCLASS = enum(c_int) { ThreadBasicInformation, ThreadTimes, From c984201ddb10d2977290c6f1d6857e78573a2dff Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 22 Mar 2023 13:57:43 +0100 Subject: [PATCH 080/216] macho+zld: refactor parsing of relocation target --- src/link/MachO/Object.zig | 26 ++++----- src/link/MachO/UnwindInfo.zig | 74 ++++++----------------- src/link/MachO/ZldAtom.zig | 107 +++++++++++++++++++++++----------- src/link/MachO/dead_strip.zig | 77 ++++++++++++++++-------- src/link/MachO/eh_frame.zig | 26 ++++----- src/link/MachO/thunks.zig | 11 +++- src/link/MachO/zld.zig | 37 ++++++------ 7 files changed, 198 insertions(+), 160 deletions(-) diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index a3e322179d..c6b86cce63 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -735,13 +735,12 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed // Find function symbol that this record describes const rel = relocs[rel_pos.start..][rel_pos.len - 1]; - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - it.data[offset..], - @intCast(i32, offset), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = it.data[offset..], + .base_offset = @intCast(i32, offset), + }); break :blk target; }, .x86_64 => { @@ -825,13 +824,12 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { // Find function symbol that this record describes const rel = relocs[rel_pos.start..][rel_pos.len - 1]; - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - mem.asBytes(&record), - @intCast(i32, offset), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = mem.asBytes(&record), + .base_offset = @intCast(i32, offset), + }); log.debug("unwind record {d} tracks {s}", .{ record_id, zld.getSymbolName(target) }); if (target.getFile() != object_id) { self.unwind_relocs_lookup[record_id].dead = true; diff --git a/src/link/MachO/UnwindInfo.zig b/src/link/MachO/UnwindInfo.zig index c64e617a35..e59f5fe250 100644 --- a/src/link/MachO/UnwindInfo.zig +++ b/src/link/MachO/UnwindInfo.zig @@ -218,13 +218,12 @@ pub fn scanRelocs(zld: *Zld) !void { record_id, )) |rel| { // Personality function; add GOT pointer. - const target = parseRelocTarget( - zld, - @intCast(u32, object_id), - rel, - mem.asBytes(&record), - @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = @intCast(u32, object_id), + .rel = rel, + .code = mem.asBytes(&record), + .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), + }); try Atom.addGotEntry(zld, target); } } @@ -266,13 +265,12 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void { @intCast(u32, object_id), record_id, )) |rel| { - const target = parseRelocTarget( - zld, - @intCast(u32, object_id), - rel, - mem.asBytes(&record), - @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = @intCast(u32, object_id), + .rel = rel, + .code = mem.asBytes(&record), + .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), + }); const personality_index = info.getPersonalityFunction(target) orelse inner: { const personality_index = info.personalities_count; info.personalities[personality_index] = target; @@ -285,13 +283,12 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void { } if (getLsdaReloc(zld, @intCast(u32, object_id), record_id)) |rel| { - const target = parseRelocTarget( - zld, - @intCast(u32, object_id), - rel, - mem.asBytes(&record), - @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = @intCast(u32, object_id), + .rel = rel, + .code = mem.asBytes(&record), + .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), + }); record.lsda = @bitCast(u64, target); } } @@ -668,41 +665,6 @@ pub fn write(info: *UnwindInfo, zld: *Zld) !void { try zld.file.pwriteAll(buffer.items, sect.offset); } -pub fn parseRelocTarget( - zld: *Zld, - object_id: u32, - rel: macho.relocation_info, - code: []const u8, - base_offset: i32, -) SymbolWithLoc { - const tracy = trace(@src()); - defer tracy.end(); - - const object = &zld.objects.items[object_id]; - - const sym_index = if (rel.r_extern == 0) blk: { - const sect_id = @intCast(u8, rel.r_symbolnum - 1); - const rel_offset = @intCast(u32, rel.r_address - base_offset); - assert(rel.r_pcrel == 0 and rel.r_length == 3); - const address_in_section = mem.readIntLittle(u64, code[rel_offset..][0..8]); - const sym_index = object.getSymbolByAddress(address_in_section, sect_id); - break :blk sym_index; - } else object.reverse_symtab_lookup[rel.r_symbolnum]; - - const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 }; - const sym = zld.getSymbol(sym_loc); - - if (sym.sect() and !sym.ext()) { - // Make sure we are not dealing with a local alias. - const atom_index = object.getAtomIndexForSymbol(sym_index) orelse - return sym_loc; - const atom = zld.getAtom(atom_index); - return atom.getSymbolWithLoc(); - } else if (object.getGlobal(sym_index)) |global_index| { - return zld.globals.items[global_index]; - } else return sym_loc; -} - fn getRelocs(zld: *Zld, object_id: u32, record_id: usize) []const macho.relocation_info { const object = &zld.objects.items[object_id]; assert(object.hasUnwindRecords()); diff --git a/src/link/MachO/ZldAtom.zig b/src/link/MachO/ZldAtom.zig index eb5e1c6ded..c47bce7c17 100644 --- a/src/link/MachO/ZldAtom.zig +++ b/src/link/MachO/ZldAtom.zig @@ -15,6 +15,7 @@ const macho = std.macho; const math = std.math; const mem = std.mem; const meta = std.meta; +const trace = @import("../../tracy.zig").trace; const Allocator = mem.Allocator; const Arch = std.Target.Cpu.Arch; @@ -163,7 +164,7 @@ pub fn scanAtomRelocs(zld: *Zld, atom_index: AtomIndex, relocs: []align(1) const } const RelocContext = struct { - base_addr: u64 = 0, + base_addr: i64 = 0, base_offset: i32 = 0, }; @@ -175,7 +176,7 @@ pub fn getRelocContext(zld: *Zld, atom_index: AtomIndex) RelocContext { if (object.getSourceSymbol(atom.sym_index)) |source_sym| { const source_sect = object.getSourceSection(source_sym.n_sect - 1); return .{ - .base_addr = source_sect.addr, + .base_addr = @intCast(i64, source_sect.addr), .base_offset = @intCast(i32, source_sym.n_value - source_sect.addr), }; } @@ -183,55 +184,71 @@ pub fn getRelocContext(zld: *Zld, atom_index: AtomIndex) RelocContext { const sect_id = @intCast(u8, atom.sym_index - nbase); const source_sect = object.getSourceSection(sect_id); return .{ - .base_addr = source_sect.addr, + .base_addr = @intCast(i64, source_sect.addr), .base_offset = 0, }; } -pub fn parseRelocTarget(zld: *Zld, atom_index: AtomIndex, rel: macho.relocation_info) SymbolWithLoc { - const atom = zld.getAtom(atom_index); - const object = &zld.objects.items[atom.getFile().?]; +pub fn parseRelocTarget(zld: *Zld, ctx: struct { + object_id: u32, + rel: macho.relocation_info, + code: []const u8, + base_addr: i64 = 0, + base_offset: i32 = 0, +}) SymbolWithLoc { + const tracy = trace(@src()); + defer tracy.end(); - const sym_index = if (rel.r_extern == 0) sym_index: { - const sect_id = @intCast(u8, rel.r_symbolnum - 1); - const ctx = getRelocContext(zld, atom_index); - const atom_code = getAtomCode(zld, atom_index); - const rel_offset = @intCast(u32, rel.r_address - ctx.base_offset); + const object = &zld.objects.items[ctx.object_id]; + log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name }); - const address_in_section = if (rel.r_pcrel == 0) blk: { - break :blk if (rel.r_length == 3) - mem.readIntLittle(u64, atom_code[rel_offset..][0..8]) + const sym_index = if (ctx.rel.r_extern == 0) sym_index: { + const sect_id = @intCast(u8, ctx.rel.r_symbolnum - 1); + const rel_offset = @intCast(u32, ctx.rel.r_address - ctx.base_offset); + + const address_in_section = if (ctx.rel.r_pcrel == 0) blk: { + break :blk if (ctx.rel.r_length == 3) + mem.readIntLittle(u64, ctx.code[rel_offset..][0..8]) else - mem.readIntLittle(u32, atom_code[rel_offset..][0..4]); + mem.readIntLittle(u32, ctx.code[rel_offset..][0..4]); } else blk: { - const correction: u3 = switch (@intToEnum(macho.reloc_type_x86_64, rel.r_type)) { + assert(zld.options.target.cpu.arch == .x86_64); + const correction: u3 = switch (@intToEnum(macho.reloc_type_x86_64, ctx.rel.r_type)) { .X86_64_RELOC_SIGNED => 0, .X86_64_RELOC_SIGNED_1 => 1, .X86_64_RELOC_SIGNED_2 => 2, .X86_64_RELOC_SIGNED_4 => 4, else => unreachable, }; - const addend = mem.readIntLittle(i32, atom_code[rel_offset..][0..4]); - const target_address = @intCast(i64, ctx.base_addr) + rel.r_address + 4 + correction + addend; + const addend = mem.readIntLittle(i32, ctx.code[rel_offset..][0..4]); + const target_address = @intCast(i64, ctx.base_addr) + ctx.rel.r_address + 4 + correction + addend; break :blk @intCast(u64, target_address); }; // Find containing atom + log.debug(" | locating symbol by address @{x} in section {d}", .{ address_in_section, sect_id }); const sym_index = object.getSymbolByAddress(address_in_section, sect_id); break :sym_index sym_index; - } else object.reverse_symtab_lookup[rel.r_symbolnum]; + } else object.reverse_symtab_lookup[ctx.rel.r_symbolnum]; - const sym_loc = SymbolWithLoc{ - .sym_index = sym_index, - .file = atom.file, - }; + const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 }; const sym = zld.getSymbol(sym_loc); - - if (sym.sect() and !sym.ext()) { - return sym_loc; - } else if (object.getGlobal(sym_index)) |global_index| { - return zld.globals.items[global_index]; - } else return sym_loc; + const target = target: { + if (sym.sect() and !sym.ext()) { + // Make sure we are not dealing with a local alias. + const atom_index = object.getAtomIndexForSymbol(sym_index) orelse break :target sym_loc; + const atom = zld.getAtom(atom_index); + break :target atom.getSymbolWithLoc(); + } else if (object.getGlobal(sym_index)) |global_index| { + break :target zld.globals.items[global_index]; + } else break :target sym_loc; + }; + log.debug(" | target %{d} ('{s}') in object({?d})", .{ + target.sym_index, + zld.getSymbolName(target), + target.getFile(), + }); + return target; } pub fn getRelocTargetAtomIndex(zld: *Zld, target: SymbolWithLoc, is_via_got: bool) ?AtomIndex { @@ -499,13 +516,25 @@ fn resolveRelocsArm64( atom.getFile(), }); - subtractor = parseRelocTarget(zld, atom_index, rel); + subtractor = parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = atom_code, + .base_addr = context.base_addr, + .base_offset = context.base_offset, + }); continue; }, else => {}, } - const target = parseRelocTarget(zld, atom_index, rel); + const target = parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = atom_code, + .base_addr = context.base_addr, + .base_offset = context.base_offset, + }); const rel_offset = @intCast(u32, rel.r_address - context.base_offset); log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{ @@ -781,13 +810,25 @@ fn resolveRelocsX86( atom.getFile(), }); - subtractor = parseRelocTarget(zld, atom_index, rel); + subtractor = parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = atom_code, + .base_addr = context.base_addr, + .base_offset = context.base_offset, + }); continue; }, else => {}, } - const target = parseRelocTarget(zld, atom_index, rel); + const target = parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = atom_code, + .base_addr = context.base_addr, + .base_offset = context.base_offset, + }); const rel_offset = @intCast(u32, rel.r_address - context.base_offset); log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{ diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index a132ecb2de..cd64e72170 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -130,14 +130,29 @@ fn markLive(zld: *Zld, atom_index: AtomIndex, alive: *AtomTable) void { const header = zld.sections.items(.header)[sym.n_sect - 1]; if (header.isZerofill()) return; + const code = Atom.getAtomCode(zld, atom_index); const relocs = Atom.getAtomRelocs(zld, atom_index); + const ctx = Atom.getRelocContext(zld, atom_index); + for (relocs) |rel| { const target = switch (cpu_arch) { .aarch64 => switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) { .ARM64_RELOC_ADDEND => continue, - else => Atom.parseRelocTarget(zld, atom_index, rel), + else => Atom.parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }), }, - .x86_64 => Atom.parseRelocTarget(zld, atom_index, rel), + .x86_64 => Atom.parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }), else => unreachable, }; const target_sym = zld.getSymbol(target); @@ -175,14 +190,29 @@ fn refersLive(zld: *Zld, atom_index: AtomIndex, alive: AtomTable) bool { const header = zld.sections.items(.header)[sym.n_sect - 1]; assert(!header.isZerofill()); + const code = Atom.getAtomCode(zld, atom_index); const relocs = Atom.getAtomRelocs(zld, atom_index); + const ctx = Atom.getRelocContext(zld, atom_index); + for (relocs) |rel| { const target = switch (cpu_arch) { .aarch64 => switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) { .ARM64_RELOC_ADDEND => continue, - else => Atom.parseRelocTarget(zld, atom_index, rel), + else => Atom.parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }), }, - .x86_64 => Atom.parseRelocTarget(zld, atom_index, rel), + .x86_64 => Atom.parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }), else => unreachable, }; @@ -283,13 +313,12 @@ fn markUnwindRecords(zld: *Zld, object_id: u32, alive: *AtomTable) !void { try markEhFrameRecord(zld, object_id, atom_index, alive); } else { if (UnwindInfo.getPersonalityFunctionReloc(zld, object_id, record_id)) |rel| { - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - mem.asBytes(&record), - @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = mem.asBytes(&record), + .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), + }); const target_sym = zld.getSymbol(target); if (!target_sym.undf()) { const target_object = zld.objects.items[target.getFile().?]; @@ -299,13 +328,12 @@ fn markUnwindRecords(zld: *Zld, object_id: u32, alive: *AtomTable) !void { } if (UnwindInfo.getLsdaReloc(zld, object_id, record_id)) |rel| { - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - mem.asBytes(&record), - @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = mem.asBytes(&record), + .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)), + }); const target_object = zld.objects.items[target.getFile().?]; const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?; markLive(zld, target_atom_index, alive); @@ -333,13 +361,12 @@ fn markEhFrameRecord(zld: *Zld, object_id: u32, atom_index: AtomIndex, alive: *A // Mark FDE references which should include any referenced LSDA record const relocs = eh_frame.getRelocs(zld, object_id, fde_offset); for (relocs) |rel| { - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - fde.data, - @intCast(i32, fde_offset) + 4, - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = fde.data, + .base_offset = @intCast(i32, fde_offset) + 4, + }); const target_sym = zld.getSymbol(target); if (!target_sym.undf()) blk: { const target_object = zld.objects.items[target.getFile().?]; diff --git a/src/link/MachO/eh_frame.zig b/src/link/MachO/eh_frame.zig index 5420bf6c29..7c5c5b7c25 100644 --- a/src/link/MachO/eh_frame.zig +++ b/src/link/MachO/eh_frame.zig @@ -308,13 +308,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { }, else => unreachable, } - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - rec.data, - @intCast(i32, source_offset) + 4, - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = rec.data, + .base_offset = @intCast(i32, source_offset) + 4, + }); return target; } return null; @@ -331,13 +330,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { const relocs = getRelocs(zld, object_id, ctx.source_offset); for (relocs) |rel| { - const target = UnwindInfo.parseRelocTarget( - zld, - object_id, - rel, - rec.data, - @intCast(i32, ctx.source_offset) + 4, - ); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = object_id, + .rel = rel, + .code = rec.data, + .base_offset = @intCast(i32, ctx.source_offset) + 4, + }); const rel_offset = @intCast(u32, rel.r_address - @intCast(i32, ctx.source_offset) - 4); const source_addr = ctx.sect_addr + rel_offset + ctx.out_offset + 4; diff --git a/src/link/MachO/thunks.zig b/src/link/MachO/thunks.zig index ce3fda0b1f..afea08750c 100644 --- a/src/link/MachO/thunks.zig +++ b/src/link/MachO/thunks.zig @@ -225,11 +225,20 @@ fn scanRelocs( break :blk @intCast(i32, source_sym.n_value - source_sect.addr); } else 0; + const code = Atom.getAtomCode(zld, atom_index); const relocs = Atom.getAtomRelocs(zld, atom_index); + const ctx = Atom.getRelocContext(zld, atom_index); + for (relocs) |rel| { if (!relocNeedsThunk(rel)) continue; - const target = Atom.parseRelocTarget(zld, atom_index, rel); + const target = Atom.parseRelocTarget(zld, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }); if (isReachable(zld, atom_index, rel, base_offset, target, allocated)) continue; log.debug("{x}: source = {s}@{x}, target = {s}@{x} unreachable", .{ diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 27a0fa5579..07241b54cd 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -1884,13 +1884,9 @@ pub const Zld = struct { if (should_rebase) { log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) }); - const object = self.objects.items[atom.getFile().?]; - const base_rel_offset: i32 = blk: { - const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0; - const source_sect = object.getSourceSection(source_sym.n_sect - 1); - break :blk @intCast(i32, source_sym.n_value - source_sect.addr); - }; + const code = Atom.getAtomCode(self, atom_index); const relocs = Atom.getAtomRelocs(self, atom_index); + const ctx = Atom.getRelocContext(self, atom_index); for (relocs) |rel| { switch (cpu_arch) { @@ -1906,12 +1902,18 @@ pub const Zld = struct { }, else => unreachable, } - const target = Atom.parseRelocTarget(self, atom_index, rel); + const target = Atom.parseRelocTarget(self, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }); const target_sym = self.getSymbol(target); if (target_sym.undf()) continue; const base_offset = @intCast(i32, sym.n_value - segment.vmaddr); - const rel_offset = rel.r_address - base_rel_offset; + const rel_offset = rel.r_address - ctx.base_offset; const offset = @intCast(u64, base_offset + rel_offset); log.debug(" | rebase at {x}", .{offset}); @@ -2021,13 +2023,9 @@ pub const Zld = struct { }; if (should_bind) { - const object = self.objects.items[atom.getFile().?]; - const base_rel_offset: i32 = blk: { - const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0; - const source_sect = object.getSourceSection(source_sym.n_sect - 1); - break :blk @intCast(i32, source_sym.n_value - source_sect.addr); - }; + const code = Atom.getAtomCode(self, atom_index); const relocs = Atom.getAtomRelocs(self, atom_index); + const ctx = Atom.getRelocContext(self, atom_index); for (relocs) |rel| { switch (cpu_arch) { @@ -2044,15 +2042,20 @@ pub const Zld = struct { else => unreachable, } - const global = Atom.parseRelocTarget(self, atom_index, rel); + const global = Atom.parseRelocTarget(self, .{ + .object_id = atom.getFile().?, + .rel = rel, + .code = code, + .base_offset = ctx.base_offset, + .base_addr = ctx.base_addr, + }); const bind_sym_name = self.getSymbolName(global); const bind_sym = self.getSymbol(global); if (!bind_sym.undf()) continue; const base_offset = sym.n_value - segment.vmaddr; - const rel_offset = @intCast(u32, rel.r_address - base_rel_offset); + const rel_offset = @intCast(u32, rel.r_address - ctx.base_offset); const offset = @intCast(u64, base_offset + rel_offset); - const code = Atom.getAtomCode(self, atom_index); const addend = mem.readIntLittle(i64, code[rel_offset..][0..8]); const dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER); From 1eb4264b7aa9e9e2b8ec46a95b508dfa7a7ab0f7 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 22 Mar 2023 15:13:52 +0100 Subject: [PATCH 081/216] macho+zld: make sure we populate source section index lookup if no undefs --- src/link/MachO/Object.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index c6b86cce63..e407457e03 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -239,6 +239,12 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) self.strtab_lookup[i] = @intCast(u32, sym_name_len); } + // If there were no undefined symbols, make sure we populate the + // source section index lookup for the last scanned section. + if (section_index_lookup) |lookup| { + self.source_section_index_lookup[prev_sect_id - 1] = lookup; + } + // Parse __TEXT,__eh_frame header if one exists self.eh_frame_sect_id = self.getSourceSectionIndexByName("__TEXT", "__eh_frame"); From d61ac0db8c62f706ea65b70d2772cbb8c4efb416 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Wed, 22 Mar 2023 17:58:24 +0100 Subject: [PATCH 082/216] TLS: Favor ChaCha over AES-based ciphers on CPUs without AES support (#15034) On CPUs without AES support, ChaCha is always faster and safer than software AES. Add `crypto.core.aes.has_hardware_support` to represent whether AES acceleration is available or not, and in `tls.Client`, favor AES-based ciphers only if hardware support is available. This matches what BoringSSL is doing. --- lib/std/crypto/aes.zig | 6 ++++++ lib/std/crypto/tls/Client.zig | 23 ++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/std/crypto/aes.zig b/lib/std/crypto/aes.zig index e2efa5bb90..f5d96a5fe8 100644 --- a/lib/std/crypto/aes.zig +++ b/lib/std/crypto/aes.zig @@ -14,6 +14,12 @@ impl: { break :impl @import("aes/soft.zig"); }; +/// `true` if AES is backed by hardware (AES-NI on x86_64, ARM Crypto Extensions on AArch64). +/// Software implementations are much slower, and should be avoided if possible. +pub const has_hardware_support = + (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) or + (builtin.cpu.arch == .aarch64 and has_armaes); + pub const Block = impl.Block; pub const AesEncryptCtx = impl.AesEncryptCtx; pub const AesDecryptCtx = impl.AesDecryptCtx; diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index 2b62d592ba..7c97a2ead0 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/lib/std/crypto/tls/Client.zig @@ -1363,13 +1363,22 @@ fn limitVecs(iovecs: []std.os.iovec, len: usize) []std.os.iovec { /// aegis-256: 461 MiB/s /// aes128-gcm: 138 MiB/s /// aes256-gcm: 120 MiB/s -const cipher_suites = enum_array(tls.CipherSuite, &.{ - .AEGIS_128L_SHA256, - .AEGIS_256_SHA384, - .AES_128_GCM_SHA256, - .AES_256_GCM_SHA384, - .CHACHA20_POLY1305_SHA256, -}); +const cipher_suites = if (crypto.core.aes.has_hardware_support) + enum_array(tls.CipherSuite, &.{ + .AEGIS_128L_SHA256, + .AEGIS_256_SHA384, + .AES_128_GCM_SHA256, + .AES_256_GCM_SHA384, + .CHACHA20_POLY1305_SHA256, + }) +else + enum_array(tls.CipherSuite, &.{ + .CHACHA20_POLY1305_SHA256, + .AEGIS_128L_SHA256, + .AEGIS_256_SHA384, + .AES_128_GCM_SHA256, + .AES_256_GCM_SHA384, + }); test { _ = StreamInterface; From 9fedecf4ab6035dca596648cd31ce85798ad69d5 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:05:58 +0100 Subject: [PATCH 083/216] http.Client: don't prematurely check transfer_{encoding,compression} (#15040) Common headers in a response are: Content-Encoding: gzip Transfer-Encoding: chunked We used to return `HttpHeadersInvalid` if a `Transfer-Encoding` header was received while the compression was already set. However, Transfer-Encoding may not include compression. We should only return an error if we are setting a value that was already set. Fixes compatibility with a bunch of websites. --- lib/std/http/Client/Response.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/http/Client/Response.zig b/lib/std/http/Client/Response.zig index 8b2a9a4918..f1a3b07dd8 100644 --- a/lib/std/http/Client/Response.zig +++ b/lib/std/http/Client/Response.zig @@ -74,8 +74,6 @@ pub const Headers = struct { if (headers.content_length != null) return error.HttpHeadersInvalid; headers.content_length = try std.fmt.parseInt(u64, header_value, 10); } else if (std.ascii.eqlIgnoreCase(header_name, "transfer-encoding")) { - if (headers.transfer_encoding != null or headers.transfer_compression != null) return error.HttpHeadersInvalid; - // Transfer-Encoding: second, first // Transfer-Encoding: deflate, chunked var iter = std.mem.splitBackwards(u8, header_value, ","); @@ -84,8 +82,10 @@ pub const Headers = struct { const trimmed = std.mem.trim(u8, first, " "); if (std.meta.stringToEnum(http.TransferEncoding, trimmed)) |te| { + if (headers.transfer_encoding != null) return error.HttpHeadersInvalid; headers.transfer_encoding = te; } else if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| { + if (headers.transfer_compression != null) return error.HttpHeadersInvalid; headers.transfer_compression = ce; } else { return error.HttpTransferEncodingUnsupported; From 38ee46dda31101f349ea9eee762908f924fd384c Mon Sep 17 00:00:00 2001 From: Phil Eaton Date: Thu, 23 Mar 2023 05:06:46 -0400 Subject: [PATCH 084/216] Two more examples of possible syntax when dealing with errors (#15042) Add an example of if with try without else switch; add example of catch with block returning value --- doc/langref.html.in | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/langref.html.in b/doc/langref.html.in index be055c3179..907464867e 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5452,6 +5452,22 @@ fn doAThing(str: []u8) void { a default value of 13. The type of the right hand side of the binary {#syntax#}catch{#endsyntax#} operator must match the unwrapped error union type, or be of type {#syntax#}noreturn{#endsyntax#}.

+

+ If you want to provide a default value with + {#syntax#}catch{#endsyntax#} after performing some logic, you + can combine {#syntax#}catch{#endsyntax#} with named {#link|Blocks#}: +

+ {#code_begin|syntax|handle_error_with_catch_block.zig#} +const parseU64 = @import("error_union_parsing_u64.zig").parseU64; + +fn doAThing(str: []u8) void { + const number = parseU64(str, 10) catch blk: { + // do things + break :blk 13; + }; + _ = number; // number is now initialized +} + {#code_end#} {#header_close#} {#header_open|try#}

Let's say you wanted to return the error if you got one, otherwise continue with the @@ -5509,6 +5525,20 @@ fn doAThing(str: []u8) void { // we promise that InvalidChar won't happen (or crash in debug mode if it does) error.InvalidChar => unreachable, } +} + {#end_syntax_block#} +

+ You must use the variable capture syntax. If you don't need the + variable, you can capture with {#syntax#}_{#endsyntax#} and avoid the + {#syntax#}switch{#endsyntax#}. +

+ {#syntax_block|zig|handle_no_error_scenarios.zig#} +fn doADifferentThing(str: []u8) void { + if (parseU64(str, 10)) |number| { + doSomethingWithNumber(number); + } else |_| { + // do as you'd like + } } {#end_syntax_block#} {#header_open|errdefer#} From 2f5af6c9721a125f3308b55f5a8059d62e5d2ec7 Mon Sep 17 00:00:00 2001 From: xEgoist Date: Thu, 23 Mar 2023 06:13:26 -0500 Subject: [PATCH 085/216] Refactored GetProcessMemoryInfo to return `VM_COUNTERS` This change allows the function to return the process memory info directly instead of copying the result of the underlying Nt function. --- lib/std/child_process.zig | 6 ++---- lib/std/os/windows.zig | 17 ++--------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 13fd40d982..ca447b068d 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -112,7 +112,7 @@ pub const ChildProcess = struct { const rusage_init = switch (builtin.os.tag) { .linux => @as(?std.os.rusage, null), - .windows => @as(?windows.PROCESS_MEMORY_COUNTERS, null), + .windows => @as(?windows.VM_COUNTERS, null), else => {}, }; }; @@ -374,9 +374,7 @@ pub const ChildProcess = struct { }); if (self.request_resource_usage_statistics) { - var pmc: windows.PROCESS_MEMORY_COUNTERS = undefined; - try windows.GetProcessMemoryInfo(self.id, &pmc); - self.resource_usage_statistics.rusage = pmc; + self.resource_usage_statistics.rusage = try windows.GetProcessMemoryInfo(self.id); } os.close(self.id); diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 27f2ddb316..fe0a68a13a 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -3994,24 +3994,11 @@ pub const GetProcessMemoryInfoError = error{ Unexpected, }; -pub fn GetProcessMemoryInfo(hProcess: HANDLE, out: *PROCESS_MEMORY_COUNTERS) GetProcessMemoryInfoError!void { +pub fn GetProcessMemoryInfo(hProcess: HANDLE) GetProcessMemoryInfoError!VM_COUNTERS { var vmc: VM_COUNTERS = undefined; const rc = ntdll.NtQueryInformationProcess(hProcess, .ProcessVmCounters, &vmc, @sizeOf(VM_COUNTERS), null); switch (rc) { - .SUCCESS => { - out.* = PROCESS_MEMORY_COUNTERS{ - .cb = @sizeOf(PROCESS_MEMORY_COUNTERS), - .PageFaultCount = vmc.PageFaultCount, - .PeakWorkingSetSize = vmc.PeakWorkingSetSize, - .WorkingSetSize = vmc.WorkingSetSize, - .QuotaPeakPagedPoolUsage = vmc.QuotaPeakPagedPoolUsage, - .QuotaPagedPoolUsage = vmc.QuotaPagedPoolUsage, - .QuotaPeakNonPagedPoolUsage = vmc.QuotaPeakNonPagedPoolUsage, - .QuotaNonPagedPoolUsage = vmc.QuotaNonPagedPoolUsage, - .PagefileUsage = vmc.PagefileUsage, - .PeakPagefileUsage = vmc.PeakPagefileUsage, - }; - }, + .SUCCESS => return vmc, .ACCESS_DENIED => return error.AccessDenied, .INVALID_HANDLE => return error.InvalidHandle, .INVALID_PARAMETER => unreachable, From 8f4548dd69de3a1c1f5c14cdf6b2e7052ea5079f Mon Sep 17 00:00:00 2001 From: xEgoist Date: Thu, 23 Mar 2023 06:17:05 -0500 Subject: [PATCH 086/216] fmt: lib/std/os/windows/ntdll.zig --- lib/std/os/windows/ntdll.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 3916e7d178..429b36039e 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -84,7 +84,7 @@ pub const PROCESSINFOCLASS = enum(c_int) { ProcessTokenVirtualizationEnabled, ProcessConsoleHostProcess, ProcessWindowInformation, - MaxProcessInfoClass + MaxProcessInfoClass, }; pub extern "ntdll" fn NtQueryInformationProcess( From 4d31e3c917a05541394c544708f0047cfb53331a Mon Sep 17 00:00:00 2001 From: Mateusz Poliwczak Date: Thu, 23 Mar 2023 18:01:21 +0100 Subject: [PATCH 087/216] std.base64: don't overflow dest with padding --- lib/std/base64.zig | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/std/base64.zig b/lib/std/base64.zig index 83f07b9c18..d9bf7d4a07 100644 --- a/lib/std/base64.zig +++ b/lib/std/base64.zig @@ -117,7 +117,7 @@ pub const Base64Encoder = struct { out_idx += 1; } if (encoder.pad_char) |pad_char| { - for (dest[out_idx..]) |*pad| { + for (dest[out_idx..out_len]) |*pad| { pad.* = pad_char; } } @@ -305,6 +305,20 @@ test "base64" { comptime try testAllApis(standard, "comptime", "Y29tcHRpbWU="); } +test "base64 padding dest overflow" { + const input = "foo"; + + var expect: [128]u8 = undefined; + std.mem.set(u8, &expect, 0); + _ = url_safe.Encoder.encode(expect[0..url_safe.Encoder.calcSize(input.len)], input); + + var got: [128]u8 = undefined; + std.mem.set(u8, &got, 0); + _ = url_safe.Encoder.encode(&got, input); + + try std.testing.expectEqualSlices(u8, &expect, &got); +} + test "base64 url_safe_no_pad" { @setEvalBranchQuota(8000); try testBase64UrlSafeNoPad(); From dcdb878360045ec50fc0cc6fda0f970150567182 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 23 Mar 2023 19:10:30 +0100 Subject: [PATCH 088/216] macho+zld: only check for alias symbols for non-extern relocations --- src/link/MachO/ZldAtom.zig | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/link/MachO/ZldAtom.zig b/src/link/MachO/ZldAtom.zig index c47bce7c17..e701ee2a13 100644 --- a/src/link/MachO/ZldAtom.zig +++ b/src/link/MachO/ZldAtom.zig @@ -227,22 +227,21 @@ pub fn parseRelocTarget(zld: *Zld, ctx: struct { // Find containing atom log.debug(" | locating symbol by address @{x} in section {d}", .{ address_in_section, sect_id }); - const sym_index = object.getSymbolByAddress(address_in_section, sect_id); - break :sym_index sym_index; + const candidate = object.getSymbolByAddress(address_in_section, sect_id); + // Make sure we are not dealing with a local alias. + const atom_index = object.getAtomIndexForSymbol(candidate) orelse break :sym_index candidate; + const atom = zld.getAtom(atom_index); + break :sym_index atom.sym_index; } else object.reverse_symtab_lookup[ctx.rel.r_symbolnum]; const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 }; const sym = zld.getSymbol(sym_loc); - const target = target: { - if (sym.sect() and !sym.ext()) { - // Make sure we are not dealing with a local alias. - const atom_index = object.getAtomIndexForSymbol(sym_index) orelse break :target sym_loc; - const atom = zld.getAtom(atom_index); - break :target atom.getSymbolWithLoc(); - } else if (object.getGlobal(sym_index)) |global_index| { - break :target zld.globals.items[global_index]; - } else break :target sym_loc; - }; + const target = if (sym.sect() and !sym.ext()) + sym_loc + else if (object.getGlobal(sym_index)) |global_index| + zld.globals.items[global_index] + else + sym_loc; log.debug(" | target %{d} ('{s}') in object({?d})", .{ target.sym_index, zld.getSymbolName(target), @@ -752,7 +751,7 @@ fn resolveRelocsArm64( mem.readIntLittle(i32, atom_code[rel_offset..][0..4]); if (rel.r_extern == 0) { - const base_addr = if (target.sym_index > object.source_address_lookup.len) + const base_addr = if (target.sym_index >= object.source_address_lookup.len) @intCast(i64, object.getSourceSection(@intCast(u8, rel.r_symbolnum - 1)).addr) else object.source_address_lookup[target.sym_index]; @@ -902,7 +901,7 @@ fn resolveRelocsX86( var addend = mem.readIntLittle(i32, atom_code[rel_offset..][0..4]) + correction; if (rel.r_extern == 0) { - const base_addr = if (target.sym_index > object.source_address_lookup.len) + const base_addr = if (target.sym_index >= object.source_address_lookup.len) @intCast(i64, object.getSourceSection(@intCast(u8, rel.r_symbolnum - 1)).addr) else object.source_address_lookup[target.sym_index]; @@ -925,7 +924,7 @@ fn resolveRelocsX86( mem.readIntLittle(i32, atom_code[rel_offset..][0..4]); if (rel.r_extern == 0) { - const base_addr = if (target.sym_index > object.source_address_lookup.len) + const base_addr = if (target.sym_index >= object.source_address_lookup.len) @intCast(i64, object.getSourceSection(@intCast(u8, rel.r_symbolnum - 1)).addr) else object.source_address_lookup[target.sym_index]; From 5d2892740a842378fd03ced7af1c1ce6d1411539 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 23 Mar 2023 22:34:31 +0100 Subject: [PATCH 089/216] build: when parsing rpaths, do not expand special runtime paths on Darwin Special runtime paths on Darwin are: `@executable_path` and `@loader_path`. --- lib/std/Build/CompileStep.zig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/std/Build/CompileStep.zig b/lib/std/Build/CompileStep.zig index 72855f360e..2747f56af2 100644 --- a/lib/std/Build/CompileStep.zig +++ b/lib/std/Build/CompileStep.zig @@ -1725,6 +1725,22 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try zig_args.ensureUnusedCapacity(2 * self.rpaths.items.len); for (self.rpaths.items) |rpath| { zig_args.appendAssumeCapacity("-rpath"); + + if (self.target_info.target.isDarwin()) switch (rpath) { + .path => |path| { + // On Darwin, we should not try to expand special runtime paths such as + // * @executable_path + // * @loader_path + if (mem.startsWith(u8, path, "@executable_path") or + mem.startsWith(u8, path, "@loader_path")) + { + zig_args.appendAssumeCapacity(path); + continue; + } + }, + .generated => {}, + }; + zig_args.appendAssumeCapacity(rpath.getPath2(b, step)); } From 145f93ba961fb9eea66a39b60e93c2aa5e26ee40 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 23 Mar 2023 23:46:49 +0100 Subject: [PATCH 090/216] build: allow for deferred FileSource matching in CheckObjectStep Re-enable all of functionality of MachO dylib test. --- lib/std/Build/CheckObjectStep.zig | 83 ++++++++++++++++++++----------- test/link/macho/dylib/build.zig | 5 +- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/lib/std/Build/CheckObjectStep.zig b/lib/std/Build/CheckObjectStep.zig index 7cac2d04ec..fbeb87baee 100644 --- a/lib/std/Build/CheckObjectStep.zig +++ b/lib/std/Build/CheckObjectStep.zig @@ -58,6 +58,16 @@ pub fn runAndCompare(self: *CheckObjectStep) *std.Build.RunStep { return run; } +const SearchPhrase = struct { + string: []const u8, + file_source: ?std.Build.FileSource = null, + + fn resolve(phrase: SearchPhrase, b: *std.Build, step: *Step) []const u8 { + const file_source = phrase.file_source orelse return phrase.string; + return b.fmt("{s} {s}", .{ phrase.string, file_source.getPath2(b, step) }); + } +}; + /// There two types of actions currently suported: /// * `.match` - is the main building block of standard matchers with optional eat-all token `{*}` /// and extractors by name such as `{n_value}`. Please note this action is very simplistic in nature @@ -72,7 +82,7 @@ pub fn runAndCompare(self: *CheckObjectStep) *std.Build.RunStep { /// they could then be added with this simple program `vmaddr entryoff +`. const Action = struct { tag: enum { match, not_present, compute_cmp }, - phrase: []const u8, + phrase: SearchPhrase, expected: ?ComputeCompareExpected = null, /// Will return true if the `phrase` was found in the `haystack`. @@ -83,12 +93,18 @@ const Action = struct { /// and save under `vmaddr` global name (see `global_vars` param) /// name {*}libobjc{*}.dylib => will match `name` followed by a token which contains `libobjc` and `.dylib` /// in that order with other letters in between - fn match(act: Action, haystack: []const u8, global_vars: anytype) !bool { + fn match( + act: Action, + b: *std.Build, + step: *Step, + haystack: []const u8, + global_vars: anytype, + ) !bool { assert(act.tag == .match or act.tag == .not_present); - + const phrase = act.phrase.resolve(b, step); var candidate_var: ?struct { name: []const u8, value: u64 } = null; var hay_it = mem.tokenize(u8, mem.trim(u8, haystack, " "), " "); - var needle_it = mem.tokenize(u8, mem.trim(u8, act.phrase, " "), " "); + var needle_it = mem.tokenize(u8, mem.trim(u8, phrase, " "), " "); while (needle_it.next()) |needle_tok| { const hay_tok = hay_it.next() orelse return false; @@ -133,12 +149,13 @@ const Action = struct { /// Will return true if the `phrase` is correctly parsed into an RPN program and /// its reduced, computed value compares using `op` with the expected value, either /// a literal or another extracted variable. - fn computeCmp(act: Action, step: *Step, global_vars: anytype) !bool { + fn computeCmp(act: Action, b: *std.Build, step: *Step, global_vars: anytype) !bool { const gpa = step.owner.allocator; + const phrase = act.phrase.resolve(b, step); var op_stack = std.ArrayList(enum { add, sub, mod, mul }).init(gpa); var values = std.ArrayList(u64).init(gpa); - var it = mem.tokenize(u8, act.phrase, " "); + var it = mem.tokenize(u8, phrase, " "); while (it.next()) |next| { if (mem.eql(u8, next, "+")) { try op_stack.append(.add); @@ -225,34 +242,32 @@ const ComputeCompareExpected = struct { }; const Check = struct { - builder: *std.Build, actions: std.ArrayList(Action), - fn create(b: *std.Build) Check { + fn create(allocator: Allocator) Check { return .{ - .builder = b, - .actions = std.ArrayList(Action).init(b.allocator), + .actions = std.ArrayList(Action).init(allocator), }; } - fn match(self: *Check, phrase: []const u8) void { + fn match(self: *Check, phrase: SearchPhrase) void { self.actions.append(.{ .tag = .match, - .phrase = self.builder.dupe(phrase), + .phrase = phrase, }) catch @panic("OOM"); } - fn notPresent(self: *Check, phrase: []const u8) void { + fn notPresent(self: *Check, phrase: SearchPhrase) void { self.actions.append(.{ .tag = .not_present, - .phrase = self.builder.dupe(phrase), + .phrase = phrase, }) catch @panic("OOM"); } - fn computeCmp(self: *Check, phrase: []const u8, expected: ComputeCompareExpected) void { + fn computeCmp(self: *Check, phrase: SearchPhrase, expected: ComputeCompareExpected) void { self.actions.append(.{ .tag = .compute_cmp, - .phrase = self.builder.dupe(phrase), + .phrase = phrase, .expected = expected, }) catch @panic("OOM"); } @@ -260,8 +275,8 @@ const Check = struct { /// Creates a new sequence of actions with `phrase` as the first anchor searched phrase. pub fn checkStart(self: *CheckObjectStep, phrase: []const u8) void { - var new_check = Check.create(self.step.owner); - new_check.match(phrase); + var new_check = Check.create(self.step.owner.allocator); + new_check.match(.{ .string = self.step.owner.dupe(phrase) }); self.checks.append(new_check) catch @panic("OOM"); } @@ -270,7 +285,19 @@ pub fn checkStart(self: *CheckObjectStep, phrase: []const u8) void { pub fn checkNext(self: *CheckObjectStep, phrase: []const u8) void { assert(self.checks.items.len > 0); const last = &self.checks.items[self.checks.items.len - 1]; - last.match(phrase); + last.match(.{ .string = self.step.owner.dupe(phrase) }); +} + +/// Like `checkNext()` but takes an additional argument `FileSource` which will be +/// resolved to a full search query in `make()`. +pub fn checkNextFileSource( + self: *CheckObjectStep, + phrase: []const u8, + file_source: std.Build.FileSource, +) void { + assert(self.checks.items.len > 0); + const last = &self.checks.items[self.checks.items.len - 1]; + last.match(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source }); } /// Adds another searched phrase to the latest created Check with `CheckObjectStep.checkStart(...)` @@ -279,7 +306,7 @@ pub fn checkNext(self: *CheckObjectStep, phrase: []const u8) void { pub fn checkNotPresent(self: *CheckObjectStep, phrase: []const u8) void { assert(self.checks.items.len > 0); const last = &self.checks.items[self.checks.items.len - 1]; - last.notPresent(phrase); + last.notPresent(.{ .string = self.step.owner.dupe(phrase) }); } /// Creates a new check checking specifically symbol table parsed and dumped from the object @@ -302,8 +329,8 @@ pub fn checkComputeCompare( program: []const u8, expected: ComputeCompareExpected, ) void { - var new_check = Check.create(self.step.owner); - new_check.computeCmp(program, expected); + var new_check = Check.create(self.step.owner.allocator); + new_check.computeCmp(.{ .string = self.step.owner.dupe(program) }, expected); self.checks.append(new_check) catch @panic("OOM"); } @@ -343,7 +370,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { switch (act.tag) { .match => { while (it.next()) |line| { - if (try act.match(line, &vars)) break; + if (try act.match(b, step, line, &vars)) break; } else { return step.fail( \\ @@ -352,12 +379,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { \\========= but parsed file does not contain it: ======= \\{s} \\====================================================== - , .{ act.phrase, output }); + , .{ act.phrase.resolve(b, step), output }); } }, .not_present => { while (it.next()) |line| { - if (try act.match(line, &vars)) { + if (try act.match(b, step, line, &vars)) { return step.fail( \\ \\========= expected not to find: =================== @@ -365,12 +392,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { \\========= but parsed file does contain it: ======== \\{s} \\=================================================== - , .{ act.phrase, output }); + , .{ act.phrase.resolve(b, step), output }); } } }, .compute_cmp => { - const res = act.computeCmp(step, vars) catch |err| switch (err) { + const res = act.computeCmp(b, step, vars) catch |err| switch (err) { error.UnknownVariable => { return step.fail( \\========= from parsed file: ===================== @@ -388,7 +415,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { \\========= from parsed file: ======================= \\{s} \\=================================================== - , .{ act.phrase, act.expected.?, output }); + , .{ act.phrase.resolve(b, step), act.expected.?, output }); } }, } diff --git a/test/link/macho/dylib/build.zig b/test/link/macho/dylib/build.zig index 2d775aa23f..a4085b51e6 100644 --- a/test/link/macho/dylib/build.zig +++ b/test/link/macho/dylib/build.zig @@ -52,10 +52,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize check_exe.checkNext("compatibility version 10000"); check_exe.checkStart("cmd RPATH"); - // TODO check this (perhaps with `checkNextFileSource(dylib.getOutputDirectorySource())`) - //check_exe.checkNext(std.fmt.allocPrint(b.allocator, "path {s}", .{ - // b.pathFromRoot("zig-out/lib"), - //}) catch unreachable); + check_exe.checkNextFileSource("path", dylib.getOutputDirectorySource()); const run = check_exe.runAndCompare(); run.expectStdOutEqual("Hello world"); From dbe1b4a7e5731e4fb17d42b754faf1052aa78f32 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Thu, 23 Mar 2023 00:27:25 -0400 Subject: [PATCH 091/216] x86_64: fix value tracking bugs --- src/arch/x86_64/CodeGen.zig | 310 ++++++++++++++++++++--------------- src/arch/x86_64/abi.zig | 2 +- src/register_manager.zig | 8 +- test/behavior/array.zig | 1 + test/behavior/bugs/10970.zig | 1 - test/behavior/for.zig | 1 + test/behavior/if.zig | 1 - test/behavior/union.zig | 1 - 8 files changed, 182 insertions(+), 143 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f30be0e378..9dfa4f0502 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -265,12 +265,15 @@ pub fn generate( const fn_type = fn_owner_decl.ty; var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); + try branch_stack.ensureUnusedCapacity(2); + // The outermost branch is used for constants only. + branch_stack.appendAssumeCapacity(.{}); + branch_stack.appendAssumeCapacity(.{}); defer { - assert(branch_stack.items.len == 1); - branch_stack.items[0].deinit(bin_file.allocator); + assert(branch_stack.items.len == 2); + for (branch_stack.items) |*branch| branch.deinit(bin_file.allocator); branch_stack.deinit(); } - try branch_stack.append(.{}); var function = Self{ .gpa = bin_file.allocator, @@ -1070,20 +1073,29 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { if (self.air_bookkeeping < old_air_bookkeeping + 1) { std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[inst] }); } + + { // check consistency of tracked registers + var it = self.register_manager.free_registers.iterator(.{ .kind = .unset }); + while (it.next()) |index| { + const tracked_inst = self.register_manager.registers[index]; + switch (air_tags[tracked_inst]) { + .block => {}, + else => assert(RegisterManager.indexOfRegIntoTracked( + switch (self.getResolvedInstValue(tracked_inst).?) { + .register => |reg| reg, + .register_overflow => |ro| ro.reg, + else => unreachable, + }, + ).? == index), + } + } + } } } } -/// Asserts there is already capacity to insert into top branch inst_table. -fn processDeath(self: *Self, inst: Air.Inst.Index) void { - const air_tags = self.air.instructions.items(.tag); - if (air_tags[inst] == .constant) return; // Constants are immortal. - const prev_value = self.getResolvedInstValue(inst) orelse return; - log.debug("%{d} => {}", .{ inst, MCValue.dead }); - // When editing this function, note that the logic must synchronize with `reuseOperand`. - const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; - branch.inst_table.putAssumeCapacity(inst, .dead); - switch (prev_value) { +fn freeValue(self: *Self, value: MCValue) void { + switch (value) { .register => |reg| { self.register_manager.freeReg(reg); }, @@ -1098,6 +1110,18 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void { } } +/// Asserts there is already capacity to insert into top branch inst_table. +fn processDeath(self: *Self, inst: Air.Inst.Index) void { + const air_tags = self.air.instructions.items(.tag); + if (air_tags[inst] == .constant) return; // Constants are immortal. + const prev_value = self.getResolvedInstValue(inst) orelse return; + log.debug("%{d} => {}", .{ inst, MCValue.dead }); + // When editing this function, note that the logic must synchronize with `reuseOperand`. + const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; + branch.inst_table.putAssumeCapacity(inst, .dead); + self.freeValue(prev_value); +} + /// Called when there are no operands, and the instruction is always unreferenced. fn finishAirBookkeeping(self: *Self) void { if (std.debug.runtime_safety) { @@ -1140,13 +1164,17 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live }, else => {}, } + } else switch (result) { + .none, .dead, .unreach => {}, + else => unreachable, // Why didn't the result die? } self.finishAirBookkeeping(); } fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void { + // In addition to the caller's needs, we need enough space to spill every register and eflags. const table = &self.branch_stack.items[self.branch_stack.items.len - 1].inst_table; - try table.ensureUnusedCapacity(self.gpa, additional_count); + try table.ensureUnusedCapacity(self.gpa, additional_count + self.register_manager.registers.len + 1); } fn allocMem(self: *Self, inst: ?Air.Inst.Index, abi_size: u32, abi_align: u32) !u32 { @@ -1252,12 +1280,15 @@ fn captureState(self: *Self) !State { }; } -fn revertState(self: *Self, state: State) void { +fn revertState(self: *Self, state: State) !void { + var stack = try state.stack.clone(self.gpa); + errdefer stack.deinit(self.gpa); + self.register_manager.registers = state.registers; self.eflags_inst = state.eflags_inst; self.stack.deinit(self.gpa); - self.stack = state.stack; + self.stack = stack; self.next_stack_offset = state.next_stack_offset; self.register_manager.free_registers = state.free_registers; @@ -1277,7 +1308,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void else => {}, } const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; - try branch.inst_table.put(self.gpa, inst, stack_mcv); + branch.inst_table.putAssumeCapacity(inst, stack_mcv); try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv, .{}); } @@ -1294,7 +1325,7 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { log.debug("spilling %{d} to mcv {any}", .{ inst_to_save, new_mcv }); const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; - try branch.inst_table.put(self.gpa, inst_to_save, new_mcv); + branch.inst_table.putAssumeCapacity(inst_to_save, new_mcv); self.eflags_inst = null; @@ -1347,13 +1378,23 @@ fn copyToRegisterWithInstTracking(self: *Self, reg_owner: Air.Inst.Index, ty: Ty } fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { - const stack_offset = try self.allocMemPtr(inst); - return self.finishAir(inst, .{ .ptr_stack_offset = @intCast(i32, stack_offset) }, .{ .none, .none, .none }); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const stack_offset = try self.allocMemPtr(inst); + break :result .{ .ptr_stack_offset = @intCast(i32, stack_offset) }; + }; + return self.finishAir(inst, result, .{ .none, .none, .none }); } fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { - const stack_offset = try self.allocMemPtr(inst); - return self.finishAir(inst, .{ .ptr_stack_offset = @intCast(i32, stack_offset) }, .{ .none, .none, .none }); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + + const stack_offset = try self.allocMemPtr(inst); + break :result .{ .ptr_stack_offset = @intCast(i32, stack_offset) }; + }; + return self.finishAir(inst, result, .{ .none, .none, .none }); } fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { @@ -1992,11 +2033,6 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { }, .register => |reg| { // TODO reuse operand - self.register_manager.getRegAssumeFree(.rcx, null); - const rcx_lock = - if (err_off > 0) self.register_manager.lockRegAssumeUnused(.rcx) else null; - defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); - const eu_lock = self.register_manager.lockReg(reg); defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); @@ -2047,11 +2083,6 @@ fn genUnwrapErrorUnionPayloadMir( }, .register => |reg| { // TODO reuse operand - self.register_manager.getRegAssumeFree(.rcx, null); - const rcx_lock = - if (payload_off > 0) self.register_manager.lockRegAssumeUnused(.rcx) else null; - defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); - const eu_lock = self.register_manager.lockReg(reg); defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); @@ -2877,17 +2908,18 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { const imm_0000_1111 = Immediate.u(mask / 0b0001_0001); const imm_0000_0001 = Immediate.u(mask / 0b1111_1111); - const tmp_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) - src_mcv.register + const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv else - try self.copyToTmpRegister(src_ty, src_mcv); - const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); - defer self.register_manager.unlockReg(tmp_lock); - - const dst_reg = try self.register_manager.allocReg(inst, gp); + try self.copyToRegisterWithInstTracking(inst, src_ty, src_mcv); + const dst_reg = dst_mcv.register; const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); defer self.register_manager.unlockReg(dst_lock); + const tmp_reg = try self.register_manager.allocReg(null, gp); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); + { const dst = registerAlias(dst_reg, src_abi_size); const tmp = registerAlias(tmp_reg, src_abi_size); @@ -2896,9 +2928,9 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { else undefined; - // tmp = operand - try self.asmRegisterRegister(.mov, dst, tmp); // dst = operand + try self.asmRegisterRegister(.mov, tmp, dst); + // tmp = operand try self.asmRegisterImmediate(.shr, tmp, Immediate.u(1)); // tmp = operand >> 1 if (src_abi_size > 4) { @@ -2948,7 +2980,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { } // dst = (temp3 * 0x01...01) >> (bits - 8) } - break :result .{ .register = dst_reg }; + break :result dst_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -3796,8 +3828,6 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue /// Clobbers .rcx for non-immediate shift value. fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shift: MCValue) !void { - assert(reg.to64() != .rcx); - switch (tag) { .sal, .sar, .shl, .shr => {}, else => unreachable, @@ -4612,23 +4642,24 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { const src_index = self.air.instructions.items(.data)[inst].arg.src_index; const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index); - if (self.liveness.isUnused(inst)) - return self.finishAirBookkeeping(); + const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; - const dst_mcv: MCValue = switch (mcv) { - .register => |reg| blk: { - self.register_manager.getRegAssumeFree(reg.to64(), inst); - break :blk MCValue{ .register = reg }; - }, - .stack_offset => |off| blk: { - const offset = @intCast(i32, self.max_end_stack) - off + 16; - break :blk MCValue{ .stack_offset = -offset }; - }, - else => return self.fail("TODO implement arg for {}", .{mcv}), + const dst_mcv: MCValue = switch (mcv) { + .register => |reg| blk: { + self.register_manager.getRegAssumeFree(reg.to64(), inst); + break :blk MCValue{ .register = reg }; + }, + .stack_offset => |off| blk: { + const offset = @intCast(i32, self.max_end_stack) - off + 16; + break :blk MCValue{ .stack_offset = -offset }; + }, + else => return self.fail("TODO implement arg for {}", .{mcv}), + }; + try self.genArgDbgInfo(ty, name, dst_mcv); + break :result dst_mcv; }; - try self.genArgDbgInfo(ty, name, dst_mcv); - - return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); + return self.finishAir(inst, result, .{ .none, .none, .none }); } fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { @@ -4924,6 +4955,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier } const result: MCValue = result: { + if (self.liveness.isUnused(inst)) break :result .dead; + switch (info.return_value) { .register => { // Save function return value in a new register @@ -5137,7 +5170,10 @@ fn genTry( const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv); try self.genBody(body); try self.performReloc(reloc); - const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, err_union); + const result = if (self.liveness.isUnused(inst)) + .dead + else + try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, err_union); return result; } @@ -5234,7 +5270,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { } // Capture the state of register and stack allocation state so that we can revert to it. - const saved_state = try self.captureState(); + var saved_state = try self.captureState(); + defer saved_state.deinit(self.gpa); { try self.branch_stack.append(.{}); @@ -5252,7 +5289,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { var then_branch = self.branch_stack.pop(); defer then_branch.deinit(self.gpa); - self.revertState(saved_state); + try self.revertState(saved_state); try self.performReloc(reloc); @@ -5286,9 +5323,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { log.debug("Then branch: {}", .{then_branch.fmtDebug()}); log.debug("Else branch: {}", .{else_branch.fmtDebug()}); - - const parent_branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; - try self.canonicaliseBranches(parent_branch, &then_branch, &else_branch); + try self.canonicaliseBranches(true, &then_branch, &else_branch); // We already took care of pl_op.operand earlier, so we're going // to pass .none here @@ -5423,10 +5458,6 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! try self.genBinOpMir(.cmp, Type.anyerror, .{ .stack_offset = offset }, .{ .immediate = 0 }); }, .register => |reg| { - self.register_manager.getRegAssumeFree(.rcx, null); - const rcx_lock = if (err_off > 0) self.register_manager.lockRegAssumeUnused(.rcx) else null; - defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); - const eu_lock = self.register_manager.lockReg(reg); defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); @@ -5606,7 +5637,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { // break instruction will choose a MCValue for the block result and overwrite // this field. Following break instructions will use that MCValue to put their // block results. - .mcv = .none, + .mcv = if (self.liveness.isUnused(inst)) .dead else .none, }); defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); @@ -5646,21 +5677,29 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { } } - var branch_stack = std.ArrayList(Branch).init(self.gpa); - defer { - for (branch_stack.items) |*bs| { - bs.deinit(self.gpa); - } - branch_stack.deinit(); + log.debug("airSwitch: %{d}", .{inst}); + log.debug("Upper branches:", .{}); + for (self.branch_stack.items) |bs| { + log.debug("{}", .{bs.fmtDebug()}); } - try branch_stack.ensureTotalCapacityPrecise(switch_br.data.cases_len + 1); + var prev_branch: ?Branch = null; + defer if (prev_branch) |*branch| branch.deinit(self.gpa); + + // Capture the state of register and stack allocation state so that we can revert to it. + var saved_state = try self.captureState(); + defer saved_state.deinit(self.gpa); + + const cases_len = switch_br.data.cases_len + @boolToInt(switch_br.data.else_body_len > 0); while (case_i < switch_br.data.cases_len) : (case_i += 1) { const case = self.air.extraData(Air.SwitchBr.Case, extra_index); const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]); const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len]; extra_index = case.end + items.len + case_body.len; + // Revert to the previous register and stack allocation state. + if (prev_branch) |_| try self.revertState(saved_state); + var relocs = try self.gpa.alloc(u32, items.len); defer self.gpa.free(relocs); @@ -5671,12 +5710,9 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { reloc.* = try self.asmJccReloc(undefined, .ne); } - // Capture the state of register and stack allocation state so that we can revert to it. - const saved_state = try self.captureState(); - { - try self.branch_stack.append(.{}); - errdefer _ = self.branch_stack.pop(); + if (cases_len > 1) try self.branch_stack.append(.{}); + errdefer _ = if (cases_len > 1) self.branch_stack.pop(); try self.ensureProcessDeathCapacity(liveness.deaths[case_i].len); for (liveness.deaths[case_i]) |operand| { @@ -5686,25 +5722,31 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { try self.genBody(case_body); } - branch_stack.appendAssumeCapacity(self.branch_stack.pop()); + // Consolidate returned MCValues between prongs like we do in airCondBr. + if (cases_len > 1) { + var case_branch = self.branch_stack.pop(); + errdefer case_branch.deinit(self.gpa); - // Revert to the previous register and stack allocation state. - self.revertState(saved_state); - - for (relocs) |reloc| { - try self.performReloc(reloc); + log.debug("Case-{d} branch: {}", .{ case_i, case_branch.fmtDebug() }); + if (prev_branch) |*canon_branch| { + try self.canonicaliseBranches(case_i == cases_len - 1, canon_branch, &case_branch); + canon_branch.deinit(self.gpa); + } + prev_branch = case_branch; } + + for (relocs) |reloc| try self.performReloc(reloc); } if (switch_br.data.else_body_len > 0) { const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len]; - // Capture the state of register and stack allocation state so that we can revert to it. - const saved_state = try self.captureState(); + // Revert to the previous register and stack allocation state. + if (prev_branch) |_| try self.revertState(saved_state); { - try self.branch_stack.append(.{}); - errdefer _ = self.branch_stack.pop(); + if (cases_len > 1) try self.branch_stack.append(.{}); + errdefer _ = if (cases_len > 1) self.branch_stack.pop(); const else_deaths = liveness.deaths.len - 1; try self.ensureProcessDeathCapacity(liveness.deaths[else_deaths].len); @@ -5715,53 +5757,48 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { try self.genBody(else_body); } - branch_stack.appendAssumeCapacity(self.branch_stack.pop()); + // Consolidate returned MCValues between a prong and the else branch like we do in airCondBr. + if (cases_len > 1) { + var else_branch = self.branch_stack.pop(); + errdefer else_branch.deinit(self.gpa); - // Revert to the previous register and stack allocation state. - self.revertState(saved_state); + log.debug("Else branch: {}", .{else_branch.fmtDebug()}); + if (prev_branch) |*canon_branch| { + try self.canonicaliseBranches(true, canon_branch, &else_branch); + canon_branch.deinit(self.gpa); + } + prev_branch = else_branch; + } } - // Consolidate returned MCValues between prongs and else branch like we do - // in airCondBr. - log.debug("airSwitch: %{d}", .{inst}); - log.debug("Upper branches:", .{}); - for (self.branch_stack.items) |bs| { - log.debug("{}", .{bs.fmtDebug()}); - } - for (branch_stack.items, 0..) |bs, i| { - log.debug("Case-{d} branch: {}", .{ i, bs.fmtDebug() }); - } - - // TODO: can we reduce the complexity of this algorithm? - const parent_branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; - var i: usize = branch_stack.items.len; - while (i > 1) : (i -= 1) { - const canon_branch = &branch_stack.items[i - 2]; - const target_branch = &branch_stack.items[i - 1]; - try self.canonicaliseBranches(parent_branch, canon_branch, target_branch); - } - - // We already took care of pl_op.operand earlier, so we're going - // to pass .none here + // We already took care of pl_op.operand earlier, so we're going to pass .none here return self.finishAir(inst, .unreach, .{ .none, .none, .none }); } -fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Branch, target_branch: *Branch) !void { - try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, target_branch.inst_table.count()); +fn canonicaliseBranches( + self: *Self, + update_parent: bool, + canon_branch: *Branch, + target_branch: *const Branch, +) !void { + const parent_branch = + if (update_parent) &self.branch_stack.items[self.branch_stack.items.len - 1] else undefined; + if (update_parent) try self.ensureProcessDeathCapacity(target_branch.inst_table.count()); const target_slice = target_branch.inst_table.entries.slice(); for (target_slice.items(.key), target_slice.items(.value)) |target_key, target_value| { const canon_mcv = if (canon_branch.inst_table.fetchSwapRemove(target_key)) |canon_entry| blk: { // The instruction's MCValue is overridden in both branches. - parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); + if (update_parent) { + parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); + } if (target_value == .dead) { assert(canon_entry.value == .dead); continue; } break :blk canon_entry.value; } else blk: { - if (target_value == .dead) - continue; + if (target_value == .dead) continue; // The instruction is only overridden in the else branch. // If integer overflows occurs, the question is: why wasn't the instruction marked dead? break :blk self.getResolvedInstValue(target_key).?; @@ -5770,22 +5807,25 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran // TODO make sure the destination stack offset / register does not already have something // going on there. try self.setRegOrMem(self.air.typeOfIndex(target_key), canon_mcv, target_value); + self.freeValue(target_value); // TODO track the new register / stack allocation } - try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, canon_branch.inst_table.count()); + if (update_parent) try self.ensureProcessDeathCapacity(canon_branch.inst_table.count()); const canon_slice = canon_branch.inst_table.entries.slice(); for (canon_slice.items(.key), canon_slice.items(.value)) |canon_key, canon_value| { // We already deleted the items from this table that matched the target_branch. // So these are all instructions that are only overridden in the canon branch. - parent_branch.inst_table.putAssumeCapacity(canon_key, canon_value); - log.debug("canon_value = {}", .{canon_value}); - if (canon_value == .dead) - continue; - const parent_mcv = self.getResolvedInstValue(canon_key).?; + const parent_mcv = + if (canon_value != .dead) self.getResolvedInstValue(canon_key).? else undefined; + if (update_parent) { + parent_branch.inst_table.putAssumeCapacity(canon_key, canon_value); + } + if (canon_value == .dead) continue; log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value }); // TODO make sure the destination stack offset / register does not already have something // going on there. - try self.setRegOrMem(self.air.typeOfIndex(canon_key), parent_mcv, canon_value); + try self.setRegOrMem(self.air.typeOfIndex(canon_key), canon_value, parent_mcv); + self.freeValue(parent_mcv); // TODO track the new register / stack allocation } } @@ -5811,11 +5851,9 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { const block_data = self.blocks.getPtr(block).?; - - if (self.air.typeOf(operand).hasRuntimeBits()) { + if (block_data.mcv != .dead and self.air.typeOf(operand).hasRuntimeBits()) { const operand_mcv = try self.resolveInst(operand); - const block_mcv = block_data.mcv; - if (block_mcv == .none) { + if (block_data.mcv == .none) { block_data.mcv = switch (operand_mcv) { .none, .dead, .unreach => unreachable, .register, .stack_offset, .memory => operand_mcv, @@ -5827,7 +5865,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}), }; } else { - try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv); + try self.setRegOrMem(self.air.typeOfIndex(block), block_data.mcv, operand_mcv); } } return self.brVoid(block); @@ -6916,7 +6954,8 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void { const pl_op = self.air.instructions.items(.data)[inst].pl_op; const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; - const dst_reg = try self.register_manager.allocReg(inst, gp); + const unused = self.liveness.isUnused(inst); + const dst_reg = try self.register_manager.allocReg(if (unused) null else inst, gp); const ptr_ty = self.air.typeOf(pl_op.operand); const ptr_mcv = try self.resolveInst(pl_op.operand); @@ -6924,7 +6963,6 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void { const val_ty = self.air.typeOf(extra.operand); const val_mcv = try self.resolveInst(extra.operand); - const unused = self.liveness.isUnused(inst); try self.atomicOp(dst_reg, ptr_mcv, val_mcv, ptr_ty, val_ty, unused, extra.op(), extra.ordering()); const result: MCValue = if (unused) .dead else .{ .register = dst_reg }; return self.finishAir(inst, result, .{ pl_op.operand, extra.operand, .none }); diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index 193efa6dc4..e9da09b999 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -523,7 +523,7 @@ pub fn getCAbiIntReturnRegs(target: Target) []const Register { } const gp_regs = [_]Register{ - .rbx, .r12, .r13, .r14, .r15, .rax, .rcx, .rdx, .rsi, .rdi, .r8, .r9, .r10, .r11, + .rax, .rcx, .rdx, .rbx, .rsi, .rdi, .r8, .r9, .r10, .r11, .r12, .r13, .r14, .r15, }; const sse_avx_regs = [_]Register{ .ymm0, .ymm1, .ymm2, .ymm3, .ymm4, .ymm5, .ymm6, .ymm7, diff --git a/src/register_manager.zig b/src/register_manager.zig index 713b669b06..1a5d2fd501 100644 --- a/src/register_manager.zig +++ b/src/register_manager.zig @@ -210,13 +210,14 @@ pub fn RegisterManager( } assert(i == count); - for (regs, 0..) |reg, j| { + for (regs, insts) |reg, inst| { + log.debug("tryAllocReg {} for inst {?}", .{ reg, inst }); self.markRegAllocated(reg); - if (insts[j]) |inst| { + if (inst) |tracked_inst| { // Track the register const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null - self.registers[index] = inst; + self.registers[index] = tracked_inst; self.markRegUsed(reg); } } @@ -258,6 +259,7 @@ pub fn RegisterManager( if (excludeRegister(reg, register_class)) break; if (self.isRegLocked(reg)) continue; + log.debug("allocReg {} for inst {?}", .{ reg, insts[i] }); regs[i] = reg; self.markRegAllocated(reg); const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 484cab4722..96b1be1778 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -191,6 +191,7 @@ test "nested arrays of strings" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" }; for (array_of_strings, 0..) |s, i| { diff --git a/test/behavior/bugs/10970.zig b/test/behavior/bugs/10970.zig index e04680c443..539dfaff71 100644 --- a/test/behavior/bugs/10970.zig +++ b/test/behavior/bugs/10970.zig @@ -6,7 +6,6 @@ fn retOpt() ?u32 { test "breaking from a loop in an if statement" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var cond = true; diff --git a/test/behavior/for.zig b/test/behavior/for.zig index 98ffff85a3..8ab378c6d4 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -275,6 +275,7 @@ test "two counters" { test "1-based counter and ptr to array" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var ok: usize = 0; diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 948629038b..730c0713c6 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -112,7 +112,6 @@ test "if prongs cast to expected type instead of peer type resolution" { } test "if peer expressions inferred optional type" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/union.zig b/test/behavior/union.zig index f247bf6fa2..b78bac5c3e 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1514,7 +1514,6 @@ test "packed union with zero-bit field" { } test "reinterpreting enum value inside packed union" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO From 12c07fcf20aba9e986b5b2131515b33e3d27176a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Thu, 23 Mar 2023 02:03:43 -0400 Subject: [PATCH 092/216] x86_64: fix more value tracking bugs --- src/arch/x86_64/CodeGen.zig | 170 +++++++++++++++++------------------- test/behavior/cast.zig | 7 +- test/behavior/enum.zig | 1 + test/behavior/if.zig | 1 + test/behavior/switch.zig | 1 - 5 files changed, 85 insertions(+), 95 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 9dfa4f0502..852a8b47be 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -214,11 +214,6 @@ const StackAllocation = struct { const BlockData = struct { relocs: std.ArrayListUnmanaged(Mir.Inst.Index), - /// The first break instruction encounters `null` here and chooses a - /// machine code value for the block result, populating this field. - /// Following break instructions encounter that value and use it for - /// the location to store their block results. - mcv: MCValue, }; const BigTomb = struct { @@ -1078,16 +1073,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { var it = self.register_manager.free_registers.iterator(.{ .kind = .unset }); while (it.next()) |index| { const tracked_inst = self.register_manager.registers[index]; - switch (air_tags[tracked_inst]) { - .block => {}, - else => assert(RegisterManager.indexOfRegIntoTracked( - switch (self.getResolvedInstValue(tracked_inst).?) { - .register => |reg| reg, - .register_overflow => |ro| ro.reg, - else => unreachable, - }, - ).? == index), - } + const tracked_mcv = self.getResolvedInstValue(tracked_inst).?.*; + assert(RegisterManager.indexOfRegIntoTracked(switch (tracked_mcv) { + .register => |reg| reg, + .register_overflow => |ro| ro.reg, + else => unreachable, + }).? == index); } } } @@ -1114,7 +1105,7 @@ fn freeValue(self: *Self, value: MCValue) void { fn processDeath(self: *Self, inst: Air.Inst.Index) void { const air_tags = self.air.instructions.items(.tag); if (air_tags[inst] == .constant) return; // Constants are immortal. - const prev_value = self.getResolvedInstValue(inst) orelse return; + const prev_value = (self.getResolvedInstValue(inst) orelse return).*; log.debug("%{d} => {}", .{ inst, MCValue.dead }); // When editing this function, note that the logic must synchronize with `reuseOperand`. const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; @@ -1259,45 +1250,29 @@ fn allocRegOrMemAdvanced(self: *Self, elem_ty: Type, inst: ?Air.Inst.Index, reg_ } const State = struct { - next_stack_offset: u32, registers: abi.RegisterManager.TrackedRegisters, free_registers: abi.RegisterManager.RegisterBitSet, eflags_inst: ?Air.Inst.Index, - stack: std.AutoHashMapUnmanaged(u32, StackAllocation), - - fn deinit(state: *State, gpa: Allocator) void { - state.stack.deinit(gpa); - } }; -fn captureState(self: *Self) !State { +fn captureState(self: *Self) State { return State{ - .next_stack_offset = self.next_stack_offset, .registers = self.register_manager.registers, .free_registers = self.register_manager.free_registers, .eflags_inst = self.eflags_inst, - .stack = try self.stack.clone(self.gpa), }; } -fn revertState(self: *Self, state: State) !void { - var stack = try state.stack.clone(self.gpa); - errdefer stack.deinit(self.gpa); - - self.register_manager.registers = state.registers; +fn revertState(self: *Self, state: State) void { self.eflags_inst = state.eflags_inst; - - self.stack.deinit(self.gpa); - self.stack = stack; - - self.next_stack_offset = state.next_stack_offset; self.register_manager.free_registers = state.free_registers; + self.register_manager.registers = state.registers; } pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { const stack_mcv = try self.allocRegOrMem(inst, false); log.debug("spilling %{d} to stack mcv {any}", .{ inst, stack_mcv }); - const reg_mcv = self.getResolvedInstValue(inst).?; + const reg_mcv = self.getResolvedInstValue(inst).?.*; switch (reg_mcv) { .register => |other| { assert(reg.to64() == other.to64()); @@ -1314,7 +1289,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void pub fn spillEflagsIfOccupied(self: *Self) !void { if (self.eflags_inst) |inst_to_save| { - const mcv = self.getResolvedInstValue(inst_to_save).?; + const mcv = self.getResolvedInstValue(inst_to_save).?.*; const new_mcv = switch (mcv) { .register_overflow => try self.allocRegOrMem(inst_to_save, false), .eflags => try self.allocRegOrMem(inst_to_save, true), @@ -2607,7 +2582,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { const index_ty = self.air.typeOf(bin_op.rhs); const index = try self.resolveInst(bin_op.rhs); const index_lock: ?RegisterLock = switch (index) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + .register => |reg| self.register_manager.lockReg(reg), else => null, }; defer if (index_lock) |lock| self.register_manager.unlockReg(lock); @@ -2656,7 +2631,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { const index_ty = self.air.typeOf(extra.rhs); const index = try self.resolveInst(extra.rhs); const index_lock: ?RegisterLock = switch (index) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + .register => |reg| self.register_manager.lockReg(reg), else => null, }; defer if (index_lock) |lock| self.register_manager.unlockReg(lock); @@ -3202,8 +3177,8 @@ fn reuseOperand( .register => |reg| { // If it's in the registers table, need to associate the register with the // new instruction. - if (RegisterManager.indexOfRegIntoTracked(reg)) |index| { - if (!self.register_manager.isRegFree(reg)) { + if (!self.register_manager.isRegFree(reg)) { + if (RegisterManager.indexOfRegIntoTracked(reg)) |index| { self.register_manager.registers[index] = inst; } } @@ -3542,7 +3517,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { const value_ty = self.air.typeOf(bin_op.rhs); log.debug("airStore(%{d}): {} <- {}", .{ inst, ptr, value }); try self.store(ptr, value, ptr_ty, value_ty); - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); + return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { @@ -5270,8 +5245,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { } // Capture the state of register and stack allocation state so that we can revert to it. - var saved_state = try self.captureState(); - defer saved_state.deinit(self.gpa); + const saved_state = self.captureState(); { try self.branch_stack.append(.{}); @@ -5289,7 +5263,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { var then_branch = self.branch_stack.pop(); defer then_branch.deinit(self.gpa); - try self.revertState(saved_state); + self.revertState(saved_state); try self.performReloc(reloc); @@ -5632,24 +5606,28 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { try self.blocks.putNoClobber(self.gpa, inst, .{ // A block is a setup to be able to jump to the end. .relocs = .{}, - // It also acts as a receptacle for break operands. - // Here we use `MCValue.none` to represent a null value so that the first - // break instruction will choose a MCValue for the block result and overwrite - // this field. Following break instructions will use that MCValue to put their - // block results. - .mcv = if (self.liveness.isUnused(inst)) .dead else .none, }); defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); + { + // Here we use `.none` to represent a null value so that the first break + // instruction will choose a MCValue for the block result and overwrite + // this field. Following break instructions will use that MCValue to put + // their block results. + const ty = self.air.typeOfIndex(inst); + const result: MCValue = + if (!ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(inst)) .dead else .none; + const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; + branch.inst_table.putAssumeCapacityNoClobber(inst, result); + } + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.Block, ty_pl.payload); const body = self.air.extra[extra.end..][0..extra.data.body_len]; try self.genBody(body); for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc); - - const result = self.blocks.getPtr(inst).?.mcv; - return self.finishAir(inst, result, .{ .none, .none, .none }); + self.finishAirBookkeeping(); } fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { @@ -5687,8 +5665,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { defer if (prev_branch) |*branch| branch.deinit(self.gpa); // Capture the state of register and stack allocation state so that we can revert to it. - var saved_state = try self.captureState(); - defer saved_state.deinit(self.gpa); + const saved_state = self.captureState(); const cases_len = switch_br.data.cases_len + @boolToInt(switch_br.data.else_body_len > 0); while (case_i < switch_br.data.cases_len) : (case_i += 1) { @@ -5698,7 +5675,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { extra_index = case.end + items.len + case_body.len; // Revert to the previous register and stack allocation state. - if (prev_branch) |_| try self.revertState(saved_state); + if (prev_branch) |_| self.revertState(saved_state); var relocs = try self.gpa.alloc(u32, items.len); defer self.gpa.free(relocs); @@ -5742,7 +5719,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len]; // Revert to the previous register and stack allocation state. - if (prev_branch) |_| try self.revertState(saved_state); + if (prev_branch) |_| self.revertState(saved_state); { if (cases_len > 1) try self.branch_stack.append(.{}); @@ -5801,7 +5778,7 @@ fn canonicaliseBranches( if (target_value == .dead) continue; // The instruction is only overridden in the else branch. // If integer overflows occurs, the question is: why wasn't the instruction marked dead? - break :blk self.getResolvedInstValue(target_key).?; + break :blk self.getResolvedInstValue(target_key).?.*; }; log.debug("consolidating target_entry {d} {}=>{}", .{ target_key, target_value, canon_mcv }); // TODO make sure the destination stack offset / register does not already have something @@ -5816,17 +5793,18 @@ fn canonicaliseBranches( // We already deleted the items from this table that matched the target_branch. // So these are all instructions that are only overridden in the canon branch. const parent_mcv = - if (canon_value != .dead) self.getResolvedInstValue(canon_key).? else undefined; + if (canon_value != .dead) self.getResolvedInstValue(canon_key).?.* else undefined; + if (canon_value != .dead) { + log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value }); + // TODO make sure the destination stack offset / register does not already have something + // going on there. + try self.setRegOrMem(self.air.typeOfIndex(canon_key), canon_value, parent_mcv); + self.freeValue(parent_mcv); + // TODO track the new register / stack allocation + } if (update_parent) { parent_branch.inst_table.putAssumeCapacity(canon_key, canon_value); } - if (canon_value == .dead) continue; - log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value }); - // TODO make sure the destination stack offset / register does not already have something - // going on there. - try self.setRegOrMem(self.air.typeOfIndex(canon_key), canon_value, parent_mcv); - self.freeValue(parent_mcv); - // TODO track the new register / stack allocation } } @@ -5845,27 +5823,41 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void { fn airBr(self: *Self, inst: Air.Inst.Index) !void { const branch = self.air.instructions.items(.data)[inst].br; - try self.br(branch.block_inst, branch.operand); + try self.br(inst, branch.block_inst, branch.operand); return self.finishAir(inst, .dead, .{ branch.operand, .none, .none }); } -fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { - const block_data = self.blocks.getPtr(block).?; - if (block_data.mcv != .dead and self.air.typeOf(operand).hasRuntimeBits()) { - const operand_mcv = try self.resolveInst(operand); - if (block_data.mcv == .none) { - block_data.mcv = switch (operand_mcv) { - .none, .dead, .unreach => unreachable, - .register, .stack_offset, .memory => operand_mcv, - .eflags, .immediate, .ptr_stack_offset => blk: { - const new_mcv = try self.allocRegOrMem(block, true); - try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); - break :blk new_mcv; - }, - else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}), - }; - } else { - try self.setRegOrMem(self.air.typeOfIndex(block), block_data.mcv, operand_mcv); +fn br(self: *Self, inst: Air.Inst.Index, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { + // The first break instruction encounters `.none` here and chooses a + // machine code value for the block result, populating this field. + // Following break instructions encounter that value and use it for + // the location to store their block results. + if (self.getResolvedInstValue(block)) |dst_mcv| { + const src_mcv = try self.resolveInst(operand); + switch (dst_mcv.*) { + .none => { + const result = result: { + if (!self.reuseOperand(inst, operand, 0, src_mcv)) { + const new_mcv = try self.allocRegOrMem(block, true); + try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, src_mcv); + break :result new_mcv; + } + + // the value is actually tracked with block, not inst + switch (src_mcv) { + .register => |reg| if (!self.register_manager.isRegFree(reg)) { + if (RegisterManager.indexOfRegIntoTracked(reg)) |index| { + self.register_manager.registers[index] = block; + } + }, + .stack_offset => {}, + else => unreachable, + } + break :result src_mcv; + }; + dst_mcv.* = result; + }, + else => try self.setRegOrMem(self.air.typeOfIndex(block), dst_mcv.*, src_mcv), } } return self.brVoid(block); @@ -7243,17 +7235,17 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { return gop.value_ptr.*; }, .const_ty => unreachable, - else => return self.getResolvedInstValue(inst_index).?, + else => return self.getResolvedInstValue(inst_index).?.*, } } -fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) ?MCValue { +fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) ?*MCValue { // Treat each stack item as a "layer" on top of the previous one. var i: usize = self.branch_stack.items.len; while (true) { i -= 1; - if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| { - return if (mcv != .dead) mcv else null; + if (self.branch_stack.items[i].inst_table.getPtr(inst)) |mcv| { + return if (mcv.* != .dead) mcv else null; } } } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 7d27138ded..978c75c92f 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -38,6 +38,8 @@ fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { } test "resolve undefined with integer" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + try testResolveUndefWithInt(true, 1234); comptime try testResolveUndefWithInt(true, 1234); } @@ -419,7 +421,6 @@ fn testCastIntToErr(err: anyerror) !void { test "peer resolve array and const slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO try testPeerResolveArrayConstSlice(true); @@ -818,7 +819,6 @@ test "peer type resolution: error union after non-error" { test "peer cast *[0]T to E![]const T" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var buffer: [5]u8 = "abcde".*; @@ -833,7 +833,6 @@ test "peer cast *[0]T to E![]const T" { test "peer cast *[0]T to []const T" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var buffer: [5]u8 = "abcde".*; @@ -855,7 +854,6 @@ test "peer cast *[N]T to [*]T" { test "peer resolution of string literals" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { @@ -1360,7 +1358,6 @@ test "cast f128 to narrower types" { test "peer type resolution: unreachable, null, slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 9076f9f9ac..72784d9abc 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -904,6 +904,7 @@ test "enum literal casting to tagged union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const Arch = union(enum) { x86_64, diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 730c0713c6..223d73ac85 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -115,6 +115,7 @@ test "if peer expressions inferred optional type" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var self: []const u8 = "abcdef"; var index: usize = 0; diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 1643a2f697..132cef5c1e 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -509,7 +509,6 @@ test "return result loc and then switch with range implicit casted to error unio } test "switch with null and T peer types and inferred result location type" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From c604111e22cb2f41e3151b1062e19035f35a6dec Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 24 Mar 2023 00:03:39 -0400 Subject: [PATCH 093/216] x86_64: fix block result value tracking --- src/arch/x86_64/CodeGen.zig | 64 +++++++++++++++---------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 852a8b47be..45cb671e93 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1085,6 +1085,17 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { } } +fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { + const reg = switch (value) { + .register => |reg| reg, + .register_overflow => |ro| ro.reg, + else => return, + }; + if (self.register_manager.isRegFree(reg)) { + self.register_manager.getRegAssumeFree(reg, inst); + } +} + fn freeValue(self: *Self, value: MCValue) void { switch (value) { .register => |reg| { @@ -1136,25 +1147,10 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live log.debug("%{d} => {}", .{ inst, result }); const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; branch.inst_table.putAssumeCapacityNoClobber(inst, result); - - // In some cases (such as bitcast), an operand - // may be the same MCValue as the result. If - // that operand died and was a register, it - // was freed by processDeath. We have to - // "re-allocate" the register. - switch (result) { - .register => |reg| { - if (self.register_manager.isRegFree(reg)) { - self.register_manager.getRegAssumeFree(reg, inst); - } - }, - .register_overflow => |ro| { - if (self.register_manager.isRegFree(ro.reg)) { - self.register_manager.getRegAssumeFree(ro.reg, inst); - } - }, - else => {}, - } + // In some cases, an operand may be reused as the result. + // If that operand died and was a register, it was freed by + // processDeath, so we have to "re-allocate" the register. + self.getValue(result, inst); } else switch (result) { .none, .dead, .unreach => {}, else => unreachable, // Why didn't the result die? @@ -5609,14 +5605,14 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { }); defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); + const ty = self.air.typeOfIndex(inst); + const unused = !ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(inst); { // Here we use `.none` to represent a null value so that the first break // instruction will choose a MCValue for the block result and overwrite // this field. Following break instructions will use that MCValue to put // their block results. - const ty = self.air.typeOfIndex(inst); - const result: MCValue = - if (!ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(inst)) .dead else .none; + const result: MCValue = if (unused) .dead else .none; const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; branch.inst_table.putAssumeCapacityNoClobber(inst, result); } @@ -5627,6 +5623,9 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { try self.genBody(body); for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc); + + const result = if (unused) .dead else self.getResolvedInstValue(inst).?.*; + self.getValue(result, inst); self.finishAirBookkeeping(); } @@ -5837,25 +5836,14 @@ fn br(self: *Self, inst: Air.Inst.Index, block: Air.Inst.Index, operand: Air.Ins switch (dst_mcv.*) { .none => { const result = result: { - if (!self.reuseOperand(inst, operand, 0, src_mcv)) { - const new_mcv = try self.allocRegOrMem(block, true); - try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, src_mcv); - break :result new_mcv; - } + if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result src_mcv; - // the value is actually tracked with block, not inst - switch (src_mcv) { - .register => |reg| if (!self.register_manager.isRegFree(reg)) { - if (RegisterManager.indexOfRegIntoTracked(reg)) |index| { - self.register_manager.registers[index] = block; - } - }, - .stack_offset => {}, - else => unreachable, - } - break :result src_mcv; + const new_mcv = try self.allocRegOrMem(block, true); + try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, src_mcv); + break :result new_mcv; }; dst_mcv.* = result; + self.freeValue(result); }, else => try self.setRegOrMem(self.air.typeOfIndex(block), dst_mcv.*, src_mcv), } From 935ec9ec6a571010ddc11a9212ff0c93f82d0d74 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 24 Mar 2023 04:40:45 -0400 Subject: [PATCH 094/216] x86_64: canonicalize each br of a block --- src/arch/x86_64/CodeGen.zig | 139 ++++++++++++++++++++++++---------- test/behavior/cast.zig | 2 - test/behavior/enum.zig | 1 - test/behavior/if.zig | 1 - tools/lldb_pretty_printers.py | 15 ++++ 5 files changed, 114 insertions(+), 44 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 45cb671e93..b1efcca1ac 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -213,7 +213,15 @@ const StackAllocation = struct { }; const BlockData = struct { - relocs: std.ArrayListUnmanaged(Mir.Inst.Index), + relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}, + branch: ?Branch = null, + branch_depth: u32, + + fn deinit(self: *BlockData, gpa: Allocator) void { + if (self.branch) |*branch| branch.deinit(gpa); + self.relocs.deinit(gpa); + self.* = undefined; + } }; const BigTomb = struct { @@ -5233,11 +5241,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { // that death now instead of later as this has an effect on // whether it needs to be spilled in the branches if (self.liveness.operandDies(inst, 0)) { - const op_int = @enumToInt(pl_op.operand); - if (op_int >= Air.Inst.Ref.typed_value_map.len) { - const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len); - self.processDeath(op_index); - } + if (Air.refToIndex(pl_op.operand)) |op_inst| self.processDeath(op_inst); } // Capture the state of register and stack allocation state so that we can revert to it. @@ -5290,10 +5294,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { for (self.branch_stack.items) |bs| { log.debug("{}", .{bs.fmtDebug()}); } - log.debug("Then branch: {}", .{then_branch.fmtDebug()}); log.debug("Else branch: {}", .{else_branch.fmtDebug()}); - try self.canonicaliseBranches(true, &then_branch, &else_branch); + + try self.canonicaliseBranches(true, &then_branch, &else_branch, true); // We already took care of pl_op.operand earlier, so we're going // to pass .none here @@ -5599,11 +5603,16 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void { } fn airBlock(self: *Self, inst: Air.Inst.Index) !void { - try self.blocks.putNoClobber(self.gpa, inst, .{ - // A block is a setup to be able to jump to the end. - .relocs = .{}, - }); - defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); + // A block is a setup to be able to jump to the end. + const branch_depth = @intCast(u32, self.branch_stack.items.len); + try self.blocks.putNoClobber(self.gpa, inst, .{ .branch_depth = branch_depth }); + defer { + var block_data = self.blocks.fetchRemove(inst).?.value; + block_data.deinit(self.gpa); + } + + try self.branch_stack.append(.{}); + defer _ = self.branch_stack.pop(); const ty = self.air.typeOfIndex(inst); const unused = !ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(inst); @@ -5613,8 +5622,8 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { // this field. Following break instructions will use that MCValue to put // their block results. const result: MCValue = if (unused) .dead else .none; - const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; - branch.inst_table.putAssumeCapacityNoClobber(inst, result); + const branch = &self.branch_stack.items[branch_depth]; + try branch.inst_table.putNoClobber(self.gpa, inst, result); } const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; @@ -5622,7 +5631,23 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { const body = self.air.extra[extra.end..][0..extra.data.body_len]; try self.genBody(body); - for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc); + const block_data = self.blocks.getPtr(inst).?; + { + const src_branch = block_data.branch orelse self.branch_stack.items[branch_depth]; + const dst_branch = &self.branch_stack.items[branch_depth - 1]; + try dst_branch.inst_table.ensureUnusedCapacity(self.gpa, src_branch.inst_table.count()); + var it = src_branch.inst_table.iterator(); + while (it.next()) |entry| { + const tracked_inst = entry.key_ptr.*; + const tracked_value = entry.value_ptr.*; + if (dst_branch.inst_table.fetchPutAssumeCapacity(tracked_inst, tracked_value)) |old_entry| { + self.freeValue(old_entry.value); + } + self.getValue(tracked_value, tracked_inst); + } + } + + for (block_data.relocs.items) |reloc| try self.performReloc(reloc); const result = if (unused) .dead else self.getResolvedInstValue(inst).?.*; self.getValue(result, inst); @@ -5647,11 +5672,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { // that death now instead of later as this has an effect on // whether it needs to be spilled in the branches if (self.liveness.operandDies(inst, 0)) { - const op_int = @enumToInt(pl_op.operand); - if (op_int >= Air.Inst.Ref.typed_value_map.len) { - const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len); - self.processDeath(op_index); - } + if (Air.refToIndex(pl_op.operand)) |op_inst| self.processDeath(op_inst); } log.debug("airSwitch: %{d}", .{inst}); @@ -5704,8 +5725,9 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { errdefer case_branch.deinit(self.gpa); log.debug("Case-{d} branch: {}", .{ case_i, case_branch.fmtDebug() }); + const final = case_i == cases_len - 1; if (prev_branch) |*canon_branch| { - try self.canonicaliseBranches(case_i == cases_len - 1, canon_branch, &case_branch); + try self.canonicaliseBranches(final, canon_branch, &case_branch, true); canon_branch.deinit(self.gpa); } prev_branch = case_branch; @@ -5740,7 +5762,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { log.debug("Else branch: {}", .{else_branch.fmtDebug()}); if (prev_branch) |*canon_branch| { - try self.canonicaliseBranches(true, canon_branch, &else_branch); + try self.canonicaliseBranches(true, canon_branch, &else_branch, true); canon_branch.deinit(self.gpa); } prev_branch = else_branch; @@ -5756,27 +5778,30 @@ fn canonicaliseBranches( update_parent: bool, canon_branch: *Branch, target_branch: *const Branch, + comptime assert_same_deaths: bool, ) !void { const parent_branch = if (update_parent) &self.branch_stack.items[self.branch_stack.items.len - 1] else undefined; - if (update_parent) try self.ensureProcessDeathCapacity(target_branch.inst_table.count()); - const target_slice = target_branch.inst_table.entries.slice(); - for (target_slice.items(.key), target_slice.items(.value)) |target_key, target_value| { + if (update_parent) try self.ensureProcessDeathCapacity(target_branch.inst_table.count()); + var target_it = target_branch.inst_table.iterator(); + while (target_it.next()) |target_entry| { + const target_key = target_entry.key_ptr.*; + const target_value = target_entry.value_ptr.*; const canon_mcv = if (canon_branch.inst_table.fetchSwapRemove(target_key)) |canon_entry| blk: { // The instruction's MCValue is overridden in both branches. if (update_parent) { parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); } if (target_value == .dead) { - assert(canon_entry.value == .dead); + if (assert_same_deaths) assert(canon_entry.value == .dead); continue; } break :blk canon_entry.value; } else blk: { if (target_value == .dead) continue; // The instruction is only overridden in the else branch. - // If integer overflows occurs, the question is: why wasn't the instruction marked dead? + // If integer overflow occurs, the question is: why wasn't the instruction marked dead? break :blk self.getResolvedInstValue(target_key).?.*; }; log.debug("consolidating target_entry {d} {}=>{}", .{ target_key, target_value, canon_mcv }); @@ -5786,9 +5811,12 @@ fn canonicaliseBranches( self.freeValue(target_value); // TODO track the new register / stack allocation } + if (update_parent) try self.ensureProcessDeathCapacity(canon_branch.inst_table.count()); - const canon_slice = canon_branch.inst_table.entries.slice(); - for (canon_slice.items(.key), canon_slice.items(.value)) |canon_key, canon_value| { + var canon_it = canon_branch.inst_table.iterator(); + while (canon_it.next()) |canon_entry| { + const canon_key = canon_entry.key_ptr.*; + const canon_value = canon_entry.value_ptr.*; // We already deleted the items from this table that matched the target_branch. // So these are all instructions that are only overridden in the canon branch. const parent_mcv = @@ -5821,22 +5849,19 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void { } fn airBr(self: *Self, inst: Air.Inst.Index) !void { - const branch = self.air.instructions.items(.data)[inst].br; - try self.br(inst, branch.block_inst, branch.operand); - return self.finishAir(inst, .dead, .{ branch.operand, .none, .none }); -} + const br = self.air.instructions.items(.data)[inst].br; + const block = br.block_inst; -fn br(self: *Self, inst: Air.Inst.Index, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { // The first break instruction encounters `.none` here and chooses a // machine code value for the block result, populating this field. // Following break instructions encounter that value and use it for // the location to store their block results. if (self.getResolvedInstValue(block)) |dst_mcv| { - const src_mcv = try self.resolveInst(operand); + const src_mcv = try self.resolveInst(br.operand); switch (dst_mcv.*) { .none => { const result = result: { - if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result src_mcv; + if (self.reuseOperand(inst, br.operand, 0, src_mcv)) break :result src_mcv; const new_mcv = try self.allocRegOrMem(block, true); try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, src_mcv); @@ -5848,16 +5873,50 @@ fn br(self: *Self, inst: Air.Inst.Index, block: Air.Inst.Index, operand: Air.Ins else => try self.setRegOrMem(self.air.typeOfIndex(block), dst_mcv.*, src_mcv), } } - return self.brVoid(block); -} -fn brVoid(self: *Self, block: Air.Inst.Index) !void { + // Process operand death early so that it is properly accounted for in the Branch below. + if (self.liveness.operandDies(inst, 0)) { + if (Air.refToIndex(br.operand)) |op_inst| self.processDeath(op_inst); + } + const block_data = self.blocks.getPtr(block).?; + { + var branch = Branch{}; + errdefer branch.deinit(self.gpa); + + var branch_i = self.branch_stack.items.len - 1; + while (branch_i >= block_data.branch_depth) : (branch_i -= 1) { + const table = &self.branch_stack.items[branch_i].inst_table; + try branch.inst_table.ensureUnusedCapacity(self.gpa, table.count()); + var it = table.iterator(); + while (it.next()) |entry| { + const gop = branch.inst_table.getOrPutAssumeCapacity(entry.key_ptr.*); + if (!gop.found_existing) gop.value_ptr.* = entry.value_ptr.*; + } + } + + if (block_data.branch) |*prev_branch| { + log.debug("brVoid: %{d}", .{inst}); + log.debug("Upper branches:", .{}); + for (self.branch_stack.items) |bs| { + log.debug("{}", .{bs.fmtDebug()}); + } + log.debug("Prev branch: {}", .{prev_branch.fmtDebug()}); + log.debug("Cur branch: {}", .{branch.fmtDebug()}); + + try self.canonicaliseBranches(false, prev_branch, &branch, false); + prev_branch.deinit(self.gpa); + } + block_data.branch = branch; + } + // Emit a jump with a relocation. It will be patched up after the block ends. try block_data.relocs.ensureUnusedCapacity(self.gpa, 1); // Leave the jump offset undefined const jmp_reloc = try self.asmJmpReloc(undefined); block_data.relocs.appendAssumeCapacity(jmp_reloc); + + self.finishAirBookkeeping(); } fn airAsm(self: *Self, inst: Air.Inst.Index) !void { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 978c75c92f..9ba91c64f3 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -38,8 +38,6 @@ fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { } test "resolve undefined with integer" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - try testResolveUndefWithInt(true, 1234); comptime try testResolveUndefWithInt(true, 1234); } diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 72784d9abc..9076f9f9ac 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -904,7 +904,6 @@ test "enum literal casting to tagged union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const Arch = union(enum) { x86_64, diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 223d73ac85..730c0713c6 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -115,7 +115,6 @@ test "if peer expressions inferred optional type" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var self: []const u8 = "abcdef"; var index: usize = 0; diff --git a/tools/lldb_pretty_printers.py b/tools/lldb_pretty_printers.py index b72b6f9760..e0b84e1b41 100644 --- a/tools/lldb_pretty_printers.py +++ b/tools/lldb_pretty_printers.py @@ -164,6 +164,20 @@ class zig_ErrorUnion_SynthProvider: def get_child_index(self, name): return 0 if name == ('payload' if self.payload else 'error_set') else -1 def get_child_at_index(self, index): return self.payload or self.error_set if index == 0 else None +class zig_TaggedUnion_SynthProvider: + def __init__(self, value, _=None): self.value = value + def update(self): + try: + self.tag = self.value.GetChildMemberWithName('tag') + self.payload = self.value.GetChildMemberWithName('payload').GetChildMemberWithName(self.tag.value) + except: pass + def has_children(self): return True + def num_children(self): return 1 + (self.payload is not None) + def get_child_index(self, name): + try: return ('tag', 'payload').index(name) + except: return -1 + def get_child_at_index(self, index): return (self.tag, self.payload)[index] if index >= 0 and index < 2 else None + # Define Zig Standard Library class std_SegmentedList_SynthProvider: @@ -606,3 +620,4 @@ def __lldb_init_module(debugger, _=None): add(debugger, category='zig.stage2', type='type.Type', summary=True) add(debugger, category='zig.stage2', type='value.Value', identifier='TagOrPayloadPtr', synth=True) add(debugger, category='zig.stage2', type='value.Value', summary=True) + add(debugger, category='zig.stage2', type='arch.x86_64.CodeGen.MCValue', identifier='zig_TaggedUnion', synth=True, inline_children=True, summary=True) From 5e0f09168452bb099d487fd4e2fb6b9f37de5640 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 24 Mar 2023 17:44:26 -0400 Subject: [PATCH 095/216] x86_64: try to fix br canonicalization --- src/arch/x86_64/CodeGen.zig | 106 +++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 49 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b1efcca1ac..e5028b17fc 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -214,11 +214,11 @@ const StackAllocation = struct { const BlockData = struct { relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}, - branch: ?Branch = null, + branch: Branch = .{}, branch_depth: u32, fn deinit(self: *BlockData, gpa: Allocator) void { - if (self.branch) |*branch| branch.deinit(gpa); + self.branch.deinit(gpa); self.relocs.deinit(gpa); self.* = undefined; } @@ -2759,7 +2759,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { }; defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); - const dst_reg = try self.register_manager.allocReg(inst, gp); + const dst_reg = try self.register_manager.allocReg(null, gp); const dst_mcv = MCValue{ .register = dst_reg }; const dst_lock = self.register_manager.lockReg(dst_reg); defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); @@ -2774,14 +2774,14 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { } const src_bits = src_ty.bitSize(self.target.*); - const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); - const width_mcv = MCValue{ .register = width_reg }; + const width_mcv = + try self.copyToRegisterWithInstTracking(inst, dst_ty, .{ .immediate = src_bits }); try self.genBinOpMir(.bsr, src_ty, dst_mcv, mat_src_mcv); const dst_abi_size = @intCast(u32, @max(dst_ty.abiSize(self.target.*), 2)); try self.asmCmovccRegisterRegister( registerAlias(dst_reg, dst_abi_size), - registerAlias(width_reg, dst_abi_size), + registerAlias(width_mcv.register, dst_abi_size), .z, ); @@ -2845,7 +2845,6 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { registerAlias(width_reg, abi_size), .z, ); - break :result dst_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -5297,7 +5296,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { log.debug("Then branch: {}", .{then_branch.fmtDebug()}); log.debug("Else branch: {}", .{else_branch.fmtDebug()}); - try self.canonicaliseBranches(true, &then_branch, &else_branch, true); + try self.canonicaliseBranches(true, &then_branch, &else_branch, true, true); // We already took care of pl_op.operand earlier, so we're going // to pass .none here @@ -5611,41 +5610,32 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { block_data.deinit(self.gpa); } - try self.branch_stack.append(.{}); - defer _ = self.branch_stack.pop(); - const ty = self.air.typeOfIndex(inst); const unused = !ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(inst); + { // Here we use `.none` to represent a null value so that the first break // instruction will choose a MCValue for the block result and overwrite // this field. Following break instructions will use that MCValue to put // their block results. const result: MCValue = if (unused) .dead else .none; - const branch = &self.branch_stack.items[branch_depth]; + const branch = &self.branch_stack.items[branch_depth - 1]; try branch.inst_table.putNoClobber(self.gpa, inst, result); } - const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; - const extra = self.air.extraData(Air.Block, ty_pl.payload); - const body = self.air.extra[extra.end..][0..extra.data.body_len]; - try self.genBody(body); + { + try self.branch_stack.append(.{}); + errdefer _ = self.branch_stack.pop(); + + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + const extra = self.air.extraData(Air.Block, ty_pl.payload); + const body = self.air.extra[extra.end..][0..extra.data.body_len]; + try self.genBody(body); + } const block_data = self.blocks.getPtr(inst).?; - { - const src_branch = block_data.branch orelse self.branch_stack.items[branch_depth]; - const dst_branch = &self.branch_stack.items[branch_depth - 1]; - try dst_branch.inst_table.ensureUnusedCapacity(self.gpa, src_branch.inst_table.count()); - var it = src_branch.inst_table.iterator(); - while (it.next()) |entry| { - const tracked_inst = entry.key_ptr.*; - const tracked_value = entry.value_ptr.*; - if (dst_branch.inst_table.fetchPutAssumeCapacity(tracked_inst, tracked_value)) |old_entry| { - self.freeValue(old_entry.value); - } - self.getValue(tracked_value, tracked_inst); - } - } + const target_branch = self.branch_stack.pop(); + try self.canonicaliseBranches(true, &block_data.branch, &target_branch, false, false); for (block_data.relocs.items) |reloc| try self.performReloc(reloc); @@ -5727,7 +5717,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { log.debug("Case-{d} branch: {}", .{ case_i, case_branch.fmtDebug() }); const final = case_i == cases_len - 1; if (prev_branch) |*canon_branch| { - try self.canonicaliseBranches(final, canon_branch, &case_branch, true); + try self.canonicaliseBranches(final, canon_branch, &case_branch, true, true); canon_branch.deinit(self.gpa); } prev_branch = case_branch; @@ -5762,7 +5752,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { log.debug("Else branch: {}", .{else_branch.fmtDebug()}); if (prev_branch) |*canon_branch| { - try self.canonicaliseBranches(true, canon_branch, &else_branch, true); + try self.canonicaliseBranches(true, canon_branch, &else_branch, true, true); canon_branch.deinit(self.gpa); } prev_branch = else_branch; @@ -5778,6 +5768,7 @@ fn canonicaliseBranches( update_parent: bool, canon_branch: *Branch, target_branch: *const Branch, + comptime set_values: bool, comptime assert_same_deaths: bool, ) !void { const parent_branch = @@ -5790,16 +5781,24 @@ fn canonicaliseBranches( const target_value = target_entry.value_ptr.*; const canon_mcv = if (canon_branch.inst_table.fetchSwapRemove(target_key)) |canon_entry| blk: { // The instruction's MCValue is overridden in both branches. - if (update_parent) { - parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); - } if (target_value == .dead) { + if (update_parent) { + parent_branch.inst_table.putAssumeCapacity(target_key, .dead); + } if (assert_same_deaths) assert(canon_entry.value == .dead); continue; } + if (update_parent) { + parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); + } break :blk canon_entry.value; } else blk: { - if (target_value == .dead) continue; + if (target_value == .dead) { + if (update_parent) { + parent_branch.inst_table.putAssumeCapacity(target_key, .dead); + } + continue; + } // The instruction is only overridden in the else branch. // If integer overflow occurs, the question is: why wasn't the instruction marked dead? break :blk self.getResolvedInstValue(target_key).?.*; @@ -5807,7 +5806,9 @@ fn canonicaliseBranches( log.debug("consolidating target_entry {d} {}=>{}", .{ target_key, target_value, canon_mcv }); // TODO make sure the destination stack offset / register does not already have something // going on there. - try self.setRegOrMem(self.air.typeOfIndex(target_key), canon_mcv, target_value); + if (set_values) { + try self.setRegOrMem(self.air.typeOfIndex(target_key), canon_mcv, target_value); + } else self.getValue(canon_mcv, target_key); self.freeValue(target_value); // TODO track the new register / stack allocation } @@ -5825,7 +5826,9 @@ fn canonicaliseBranches( log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value }); // TODO make sure the destination stack offset / register does not already have something // going on there. - try self.setRegOrMem(self.air.typeOfIndex(canon_key), canon_value, parent_mcv); + if (set_values) { + try self.setRegOrMem(self.air.typeOfIndex(canon_key), canon_value, parent_mcv); + } else self.getValue(canon_value, canon_key); self.freeValue(parent_mcv); // TODO track the new register / stack allocation } @@ -5890,23 +5893,28 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { try branch.inst_table.ensureUnusedCapacity(self.gpa, table.count()); var it = table.iterator(); while (it.next()) |entry| { + // This loop could be avoided by tracking inst depth, which + // will be needed later anyway for reusing loop deaths. + var parent_branch_i = block_data.branch_depth - 1; + while (parent_branch_i > 0) : (parent_branch_i -= 1) { + const parent_table = &self.branch_stack.items[parent_branch_i].inst_table; + if (parent_table.contains(entry.key_ptr.*)) break; + } else continue; const gop = branch.inst_table.getOrPutAssumeCapacity(entry.key_ptr.*); if (!gop.found_existing) gop.value_ptr.* = entry.value_ptr.*; } } - if (block_data.branch) |*prev_branch| { - log.debug("brVoid: %{d}", .{inst}); - log.debug("Upper branches:", .{}); - for (self.branch_stack.items) |bs| { - log.debug("{}", .{bs.fmtDebug()}); - } - log.debug("Prev branch: {}", .{prev_branch.fmtDebug()}); - log.debug("Cur branch: {}", .{branch.fmtDebug()}); - - try self.canonicaliseBranches(false, prev_branch, &branch, false); - prev_branch.deinit(self.gpa); + log.debug("airBr: %{d}", .{inst}); + log.debug("Upper branches:", .{}); + for (self.branch_stack.items) |bs| { + log.debug("{}", .{bs.fmtDebug()}); } + log.debug("Prev branch: {}", .{block_data.branch.fmtDebug()}); + log.debug("Cur branch: {}", .{branch.fmtDebug()}); + + try self.canonicaliseBranches(false, &block_data.branch, &branch, true, false); + block_data.branch.deinit(self.gpa); block_data.branch = branch; } From 0987ed1970bc0332844a0e398b3c981b38627ed6 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 24 Mar 2023 17:55:47 -0400 Subject: [PATCH 096/216] x86_64: detect canonicalisation hazards --- src/arch/x86_64/CodeGen.zig | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index e5028b17fc..7335d3ac94 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5771,6 +5771,9 @@ fn canonicaliseBranches( comptime set_values: bool, comptime assert_same_deaths: bool, ) !void { + var hazard_map = std.AutoHashMap(MCValue, void).init(self.gpa); + defer hazard_map.deinit(); + const parent_branch = if (update_parent) &self.branch_stack.items[self.branch_stack.items.len - 1] else undefined; @@ -5804,8 +5807,10 @@ fn canonicaliseBranches( break :blk self.getResolvedInstValue(target_key).?.*; }; log.debug("consolidating target_entry {d} {}=>{}", .{ target_key, target_value, canon_mcv }); - // TODO make sure the destination stack offset / register does not already have something + // TODO handle the case where the destination stack offset / register has something // going on there. + assert(!hazard_map.contains(target_value)); + try hazard_map.putNoClobber(canon_mcv, {}); if (set_values) { try self.setRegOrMem(self.air.typeOfIndex(target_key), canon_mcv, target_value); } else self.getValue(canon_mcv, target_key); @@ -5824,8 +5829,10 @@ fn canonicaliseBranches( if (canon_value != .dead) self.getResolvedInstValue(canon_key).?.* else undefined; if (canon_value != .dead) { log.debug("consolidating canon_entry {d} {}=>{}", .{ canon_key, parent_mcv, canon_value }); - // TODO make sure the destination stack offset / register does not already have something + // TODO handle the case where the destination stack offset / register has something // going on there. + assert(!hazard_map.contains(parent_mcv)); + try hazard_map.putNoClobber(canon_value, {}); if (set_values) { try self.setRegOrMem(self.air.typeOfIndex(canon_key), canon_value, parent_mcv); } else self.getValue(canon_value, canon_key); From 4ab4bd04fe8f4308d67b757eaa88f5a356aea688 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 24 Mar 2023 21:33:17 -0400 Subject: [PATCH 097/216] x86_64: add back assume unused This seems to have been asserting due to a value tracking bug that has since been fixed. --- src/arch/x86_64/CodeGen.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 7335d3ac94..66e1904420 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2586,7 +2586,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { const index_ty = self.air.typeOf(bin_op.rhs); const index = try self.resolveInst(bin_op.rhs); const index_lock: ?RegisterLock = switch (index) { - .register => |reg| self.register_manager.lockReg(reg), + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), else => null, }; defer if (index_lock) |lock| self.register_manager.unlockReg(lock); @@ -2635,7 +2635,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { const index_ty = self.air.typeOf(extra.rhs); const index = try self.resolveInst(extra.rhs); const index_lock: ?RegisterLock = switch (index) { - .register => |reg| self.register_manager.lockReg(reg), + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), else => null, }; defer if (index_lock) |lock| self.register_manager.unlockReg(lock); From f6a2b72ba8b6ab8f8dbef223788c6458af3d4da0 Mon Sep 17 00:00:00 2001 From: tjog <28024277+tjog@users.noreply.github.com> Date: Thu, 23 Mar 2023 02:21:15 +0800 Subject: [PATCH 098/216] std.process.Child: implement maxrss on Darwin Notably the Darwin (XNU) kernel the maxrss field is number of bytes and not kilobytes (kibibytes) like other platforms (e.g. Linux, BSD). watchOS and tvOS are not supported because they do not have the ability to spawn a child process. iOS is enabled but due to OS sandboxing it should fail with a permission error. --- lib/std/child_process.zig | 28 ++++++++++++++++++++-------- lib/std/process.zig | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index ca447b068d..bd67d344c7 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -17,7 +17,6 @@ const Os = std.builtin.Os; const TailQueue = std.TailQueue; const maxInt = std.math.maxInt; const assert = std.debug.assert; -const is_darwin = builtin.target.isDarwin(); pub const ChildProcess = struct { pub const Id = switch (builtin.os.tag) { @@ -77,7 +76,7 @@ pub const ChildProcess = struct { /// requested statistics may or may not be available. If they are /// available, then the `resource_usage_statistics` field will be populated /// after calling `wait`. - /// On Linux, this obtains rusage statistics from wait4(). + /// On Linux and Darwin, this obtains rusage statistics from wait4(). request_resource_usage_statistics: bool = false, /// This is available after calling wait if @@ -106,12 +105,20 @@ pub const ChildProcess = struct { return null; } }, + .macos, .ios => { + if (rus.rusage) |ru| { + // Darwin oddly reports in bytes instead of kilobytes. + return @intCast(usize, ru.maxrss); + } else { + return null; + } + }, else => return null, } } const rusage_init = switch (builtin.os.tag) { - .linux => @as(?std.os.rusage, null), + .linux, .macos, .ios => @as(?std.os.rusage, null), .windows => @as(?windows.VM_COUNTERS, null), else => {}, }; @@ -385,11 +392,16 @@ pub const ChildProcess = struct { fn waitUnwrapped(self: *ChildProcess) !void { const res: os.WaitPidResult = res: { - if (builtin.os.tag == .linux and self.request_resource_usage_statistics) { - var ru: std.os.rusage = undefined; - const res = os.wait4(self.id, 0, &ru); - self.resource_usage_statistics.rusage = ru; - break :res res; + if (self.request_resource_usage_statistics) { + switch (builtin.os.tag) { + .linux, .macos, .ios => { + var ru: std.os.rusage = undefined; + const res = os.wait4(self.id, 0, &ru); + self.resource_usage_statistics.rusage = ru; + break :res res; + }, + else => {}, + } } break :res os.waitpid(self.id, 0); diff --git a/lib/std/process.zig b/lib/std/process.zig index d06a012af2..f870b85774 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1093,7 +1093,7 @@ pub const can_execv = switch (builtin.os.tag) { /// Tells whether spawning child processes is supported (e.g. via ChildProcess) pub const can_spawn = switch (builtin.os.tag) { - .wasi => false, + .wasi, .watchos, .tvos => false, else => true, }; From fcc86832d685c09c37570562ee1036aa1eb18ea6 Mon Sep 17 00:00:00 2001 From: Jay Petacat Date: Sat, 25 Mar 2023 00:03:22 -0600 Subject: [PATCH 099/216] std.enums.IndexedSet: Add initOne and initMany --- lib/std/enums.zig | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/std/enums.zig b/lib/std/enums.zig index 61c2f01e23..8ef097e909 100644 --- a/lib/std/enums.zig +++ b/lib/std/enums.zig @@ -775,6 +775,18 @@ pub fn IndexedSet(comptime I: type, comptime Ext: fn (type) type) type { return .{ .bits = BitSet.initFull() }; } + /// Returns a set containing multiple keys. + pub fn initMany(keys: []const Key) Self { + var set = initEmpty(); + for (keys) |key| set.insert(key); + return set; + } + + /// Returns a set containing a single key. + pub fn initOne(key: Key) Self { + return initMany(&[_]Key{key}); + } + /// Returns the number of keys in the set. pub fn count(self: Self) usize { return self.bits.count(); @@ -900,20 +912,8 @@ test "pure EnumSet fns" { const empty = EnumSet(Suit).initEmpty(); const full = EnumSet(Suit).initFull(); - - const black = black: { - var set = EnumSet(Suit).initEmpty(); - set.insert(.spades); - set.insert(.clubs); - break :black set; - }; - - const red = red: { - var set = EnumSet(Suit).initEmpty(); - set.insert(.hearts); - set.insert(.diamonds); - break :red set; - }; + const black = EnumSet(Suit).initMany(&[_]Suit{ .spades, .clubs }); + const red = EnumSet(Suit).initMany(&[_]Suit{ .hearts, .diamonds }); try testing.expect(empty.eql(empty)); try testing.expect(full.eql(full)); From 37f6f7990e882ac9869513cf920f8cd0c4850039 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Sat, 25 Mar 2023 22:49:40 +1300 Subject: [PATCH 100/216] enable more float-parsing tests Since removing the stage1 backend we no longer have a disagreement here. --- lib/std/fmt/parse_float.zig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/std/fmt/parse_float.zig b/lib/std/fmt/parse_float.zig index e92564ef01..b14fe5ca3c 100644 --- a/lib/std/fmt/parse_float.zig +++ b/lib/std/fmt/parse_float.zig @@ -149,7 +149,7 @@ test "fmt.parseFloat hex.f64" { try testing.expectEqual(try parseFloat(f64, "0x1p-1022"), math.floatMin(f64)); try testing.expectEqual(try parseFloat(f64, "-0x1p-1022"), -math.floatMin(f64)); // Min denormalized value. - //try testing.expectEqual(try parseFloat(f64, "0x1p-1074"), math.floatTrueMin(f64)); + try testing.expectEqual(try parseFloat(f64, "0x1p-1074"), math.floatTrueMin(f64)); try testing.expectEqual(try parseFloat(f64, "-0x1p-1074"), -math.floatTrueMin(f64)); } test "fmt.parseFloat hex.f128" { @@ -166,7 +166,6 @@ test "fmt.parseFloat hex.f128" { // // Min denormalized value. try testing.expectEqual(try parseFloat(f128, "0x1p-16494"), math.floatTrueMin(f128)); try testing.expectEqual(try parseFloat(f128, "-0x1p-16494"), -math.floatTrueMin(f128)); - - // NOTE: We are performing round-to-even. Previous behavior was round-up. - // try testing.expectEqual(try parseFloat(f128, "0x1.edcb34a235253948765432134674fp-1"), 0x1.edcb34a235253948765432134674fp-1); + // ensure round-to-even + try testing.expectEqual(try parseFloat(f128, "0x1.edcb34a235253948765432134674fp-1"), 0x1.edcb34a235253948765432134674fp-1); } From 3ece9758574e600c1d97add143c24fefed3d2d82 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 00:05:54 -0400 Subject: [PATCH 101/216] x86_64: implement saturating arithmetic --- src/arch/x86_64/CodeGen.zig | 199 +++++++++++++++++++++++++++++------- src/arch/x86_64/encoder.zig | 2 +- src/register_manager.zig | 19 +++- 3 files changed, 175 insertions(+), 45 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 66e1904420..6a459684ca 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1550,28 +1550,161 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ty = self.air.typeOf(bin_op.lhs); + + const lhs_mcv = try self.resolveInst(bin_op.lhs); + const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv)) + lhs_mcv + else + try self.copyToRegisterWithInstTracking(inst, ty, lhs_mcv); + const dst_reg = dst_mcv.register; + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const rhs_mcv = try self.resolveInst(bin_op.rhs); + const rhs_lock = switch (rhs_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); + + const limit_reg = try self.register_manager.allocReg(null, gp); + const limit_mcv = MCValue{ .register = limit_reg }; + const limit_lock = self.register_manager.lockRegAssumeUnused(limit_reg); + defer self.register_manager.unlockReg(limit_lock); + + const reg_bits = self.regBitSize(ty); + const cc: Condition = if (ty.isSignedInt()) cc: { + try self.genSetReg(ty, limit_reg, dst_mcv); + try self.genBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genBinOpMir(.xor, ty, limit_mcv, .{ + .immediate = (@as(u64, 1) << @intCast(u6, reg_bits - 1)) - 1, + }); + break :cc .o; + } else cc: { + try self.genSetReg(ty, limit_reg, .{ + .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(u6, 64 - reg_bits), + }); + break :cc .c; + }; + try self.genBinOpMir(.add, ty, dst_mcv, rhs_mcv); + + const abi_size = @intCast(u32, @max(ty.abiSize(self.target.*), 2)); + try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, abi_size), + registerAlias(limit_reg, abi_size), + cc, + ); + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ty = self.air.typeOf(bin_op.lhs); + + const lhs_mcv = try self.resolveInst(bin_op.lhs); + const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv)) + lhs_mcv + else + try self.copyToRegisterWithInstTracking(inst, ty, lhs_mcv); + const dst_reg = dst_mcv.register; + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const rhs_mcv = try self.resolveInst(bin_op.rhs); + const rhs_lock = switch (rhs_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); + + const limit_reg = try self.register_manager.allocReg(null, gp); + const limit_mcv = MCValue{ .register = limit_reg }; + const limit_lock = self.register_manager.lockRegAssumeUnused(limit_reg); + defer self.register_manager.unlockReg(limit_lock); + + const reg_bits = self.regBitSize(ty); + const cc: Condition = if (ty.isSignedInt()) cc: { + try self.genSetReg(ty, limit_reg, dst_mcv); + try self.genBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genBinOpMir(.xor, ty, limit_mcv, .{ + .immediate = (@as(u64, 1) << @intCast(u6, reg_bits - 1)) - 1, + }); + break :cc .o; + } else cc: { + try self.genSetReg(ty, limit_reg, .{ .immediate = 0 }); + break :cc .c; + }; + try self.genBinOpMir(.sub, ty, dst_mcv, rhs_mcv); + + const abi_size = @intCast(u32, @max(ty.abiSize(self.target.*), 2)); + try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, abi_size), + registerAlias(limit_reg, abi_size), + cc, + ); + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ty = self.air.typeOf(bin_op.lhs); + + try self.spillRegisters(&.{ .rax, .rdx }); + const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx }); + defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); + + const lhs_mcv = try self.resolveInst(bin_op.lhs); + const lhs_lock = switch (lhs_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); + + const rhs_mcv = try self.resolveInst(bin_op.rhs); + const rhs_lock = switch (rhs_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); + + const limit_reg = try self.register_manager.allocReg(null, gp); + const limit_mcv = MCValue{ .register = limit_reg }; + const limit_lock = self.register_manager.lockRegAssumeUnused(limit_reg); + defer self.register_manager.unlockReg(limit_lock); + + const reg_bits = self.regBitSize(ty); + const cc: Condition = if (ty.isSignedInt()) cc: { + try self.genSetReg(ty, limit_reg, lhs_mcv); + try self.genBinOpMir(.xor, ty, limit_mcv, rhs_mcv); + try self.genBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genBinOpMir(.xor, ty, limit_mcv, .{ + .immediate = (@as(u64, 1) << @intCast(u6, reg_bits - 1)) - 1, + }); + break :cc .o; + } else cc: { + try self.genSetReg(ty, limit_reg, .{ + .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(u6, 64 - reg_bits), + }); + break :cc .c; + }; + + const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, lhs_mcv, rhs_mcv); + const abi_size = @intCast(u32, @max(ty.abiSize(self.target.*), 2)); + try self.asmCmovccRegisterRegister( + registerAlias(dst_mcv.register, abi_size), + registerAlias(limit_reg, abi_size), + cc, + ); + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -3915,7 +4048,8 @@ fn genMulDivBinOp( if (ty.zigTypeTag() == .Vector or ty.zigTypeTag() == .Float) { return self.fail("TODO implement genMulDivBinOp for {}", .{ty.fmtDebug()}); } - if (ty.abiSize(self.target.*) > 8) { + const abi_size = @intCast(u32, ty.abiSize(self.target.*)); + if (abi_size > 8) { return self.fail("TODO implement genMulDivBinOp for {}", .{ty.fmtDebug()}); } if (tag == .div_float) { @@ -3925,10 +4059,8 @@ fn genMulDivBinOp( assert(self.register_manager.isRegFree(.rax)); assert(self.register_manager.isRegFree(.rdx)); - const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }); - defer for (reg_locks) |reg| { - self.register_manager.unlockReg(reg); - }; + const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx }); + defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); const int_info = ty.intInfo(self.target.*); const signedness = int_info.signedness; @@ -3953,35 +4085,24 @@ fn genMulDivBinOp( const mir_tag: Mir.Inst.Tag = switch (signedness) { .signed => switch (tag) { - .mul, .mulwrap => Mir.Inst.Tag.imul, - .div_trunc, .div_exact, .rem => Mir.Inst.Tag.idiv, + .mul, .mulwrap => .imul, + .div_trunc, .div_exact, .rem => .idiv, else => unreachable, }, .unsigned => switch (tag) { - .mul, .mulwrap => Mir.Inst.Tag.mul, - .div_trunc, .div_exact, .rem => Mir.Inst.Tag.div, + .mul, .mulwrap => .mul, + .div_trunc, .div_exact, .rem => .div, else => unreachable, }, }; try self.genIntMulDivOpMir(mir_tag, ty, .signed, lhs, rhs); - switch (signedness) { - .signed => switch (tag) { - .mul, .mulwrap, .div_trunc, .div_exact => return MCValue{ .register = .rax }, - .rem => return MCValue{ .register = .rdx }, - else => unreachable, - }, - .unsigned => switch (tag) { - .mul, .mulwrap, .div_trunc, .div_exact => return MCValue{ - .register = registerAlias(.rax, @intCast(u32, ty.abiSize(self.target.*))), - }, - .rem => return MCValue{ - .register = registerAlias(.rdx, @intCast(u32, ty.abiSize(self.target.*))), - }, - else => unreachable, - }, - } + return .{ .register = registerAlias(switch (tag) { + .mul, .mulwrap, .div_trunc, .div_exact => .rax, + .rem => .rdx, + else => unreachable, + }, abi_size) }; }, .mod => { @@ -3998,14 +4119,14 @@ fn genMulDivBinOp( const result: MCValue = if (maybe_inst) |inst| try self.copyToRegisterWithInstTracking(inst, ty, lhs) else - MCValue{ .register = try self.copyToTmpRegister(ty, lhs) }; + .{ .register = try self.copyToTmpRegister(ty, lhs) }; try self.genBinOpMir(.sub, ty, result, div_floor); return result; }, .unsigned => { try self.genIntMulDivOpMir(.div, ty, .unsigned, lhs, rhs); - return MCValue{ .register = registerAlias(.rdx, @intCast(u32, ty.abiSize(self.target.*))) }; + return .{ .register = registerAlias(.rdx, abi_size) }; }, } }, diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index b3de7ec1bd..9206923ece 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -117,7 +117,7 @@ pub const Instruction = struct { pub fn new(mnemonic: Mnemonic, args: Init) !Instruction { const encoding = (try Encoding.findByMnemonic(mnemonic, args)) orelse { - log.debug("no encoding found for: {s} {s} {s} {s} {s} {s}", .{ + log.err("no encoding found for: {s} {s} {s} {s} {s} {s}", .{ @tagName(args.prefix), @tagName(mnemonic), @tagName(Encoding.Op.fromOperand(args.op1)), diff --git a/src/register_manager.zig b/src/register_manager.zig index 1a5d2fd501..fe53ba3b95 100644 --- a/src/register_manager.zig +++ b/src/register_manager.zig @@ -149,17 +149,26 @@ pub fn RegisterManager( return RegisterLock{ .register = reg }; } + /// Like `lockReg` but locks multiple registers. + pub fn lockRegs( + self: *Self, + comptime count: comptime_int, + regs: [count]Register, + ) [count]?RegisterLock { + var results: [count]?RegisterLock = undefined; + for (&results, regs) |*result, reg| result.* = self.lockReg(reg); + return results; + } + /// Like `lockRegAssumeUnused` but locks multiple registers. pub fn lockRegsAssumeUnused( self: *Self, comptime count: comptime_int, regs: [count]Register, ) [count]RegisterLock { - var buf: [count]RegisterLock = undefined; - for (regs, 0..) |reg, i| { - buf[i] = self.lockRegAssumeUnused(reg); - } - return buf; + var results: [count]RegisterLock = undefined; + for (&results, regs) |*result, reg| result.* = self.lockRegAssumeUnused(reg); + return results; } /// Unlocks the register allowing its re-allocation and re-use. From d9ce69dc3949fb11c43520096001b7f06e1a96f3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 02:37:31 -0400 Subject: [PATCH 102/216] codegen: fix ptr-like optional constants --- src/codegen.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/codegen.zig b/src/codegen.zig index c48200e845..a99ff18dfd 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -1063,13 +1063,12 @@ pub fn genTypedValue( }, .Optional => { if (typed_value.ty.isPtrLikeOptional()) { - if (typed_value.val.isNull()) - return GenResult.mcv(.{ .immediate = 0 }); + if (typed_value.val.tag() == .null_value) return GenResult.mcv(.{ .immediate = 0 }); var buf: Type.Payload.ElemType = undefined; return genTypedValue(bin_file, src_loc, .{ .ty = typed_value.ty.optionalChild(&buf), - .val = typed_value.val, + .val = if (typed_value.val.castTag(.opt_payload)) |pl| pl.data else typed_value.val, }, owner_decl_index); } else if (typed_value.ty.abiSize(target) == 1) { return GenResult.mcv(.{ .immediate = @boolToInt(!typed_value.val.isNull()) }); From 0cfc0d0d13bd1e9f1a9119324fac624371aecdd3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 03:08:04 -0400 Subject: [PATCH 103/216] x86_64: implement struct_field_ptr for packed containers --- src/arch/x86_64/CodeGen.zig | 27 +++++++++++++++------------ test/behavior/bugs/12450.zig | 1 - test/behavior/bugs/2578.zig | 1 - test/behavior/bugs/726.zig | 2 -- test/behavior/fn.zig | 1 - test/behavior/packed-struct.zig | 1 - test/behavior/struct.zig | 1 - 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 6a459684ca..5b16ae5a1c 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3659,34 +3659,37 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; - const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index); + const result = try self.fieldPtr(inst, extra.struct_operand, extra.field_index); return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); } fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result = try self.structFieldPtr(inst, ty_op.operand, index); + const result = try self.fieldPtr(inst, ty_op.operand, index); return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } -fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { +fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { if (self.liveness.isUnused(inst)) { return MCValue.dead; } const mcv = try self.resolveInst(operand); const ptr_ty = self.air.typeOf(operand); - const struct_ty = ptr_ty.childType(); - if (struct_ty.zigTypeTag() == .Struct and struct_ty.containerLayout() == .Packed) { - return self.fail("TODO structFieldPtr implement packed structs", .{}); - } - const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); + const container_ty = ptr_ty.childType(); + const field_offset = switch (container_ty.containerLayout()) { + .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*)), + .Packed => if (container_ty.zigTypeTag() == .Struct and ptr_ty.ptrInfo().data.host_size == 0) + container_ty.packedStructFieldByteOffset(index, self.target.*) + else + 0, + }; const dst_mcv: MCValue = result: { switch (mcv) { .stack_offset => { const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ - .immediate = struct_field_offset, + .immediate = field_offset, }); const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); defer self.register_manager.unlockReg(offset_reg_lock); @@ -3696,7 +3699,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde break :result dst_mcv; }, .ptr_stack_offset => |off| { - const ptr_stack_offset = off - @intCast(i32, struct_field_offset); + const ptr_stack_offset = off - @intCast(i32, field_offset); break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; }, .register => |reg| { @@ -3704,7 +3707,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde defer self.register_manager.unlockReg(reg_lock); const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ - .immediate = struct_field_offset, + .immediate = field_offset, }); const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); defer self.register_manager.unlockReg(offset_reg_lock); @@ -3725,7 +3728,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde try self.genBinOpMir(.add, ptr_ty, .{ .register = result_reg }, .{ .register = offset_reg }); break :result MCValue{ .register = result_reg }; }, - else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), + else => return self.fail("TODO implement fieldPtr for {}", .{mcv}), } }; return dst_mcv; diff --git a/test/behavior/bugs/12450.zig b/test/behavior/bugs/12450.zig index 5161e3ffd3..89e5c774e0 100644 --- a/test/behavior/bugs/12450.zig +++ b/test/behavior/bugs/12450.zig @@ -10,7 +10,6 @@ var buffer: [256]u8 = undefined; test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/2578.zig b/test/behavior/bugs/2578.zig index ad4fb133e4..ff8ba141fa 100644 --- a/test/behavior/bugs/2578.zig +++ b/test/behavior/bugs/2578.zig @@ -14,7 +14,6 @@ fn bar(pointer: ?*anyopaque) void { test "fixed" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO bar(t); diff --git a/test/behavior/bugs/726.zig b/test/behavior/bugs/726.zig index 1c552e1df1..cc5c2a5fb7 100644 --- a/test/behavior/bugs/726.zig +++ b/test/behavior/bugs/726.zig @@ -4,7 +4,6 @@ const builtin = @import("builtin"); test "@ptrCast from const to nullable" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const c: u8 = 4; @@ -15,7 +14,6 @@ test "@ptrCast from const to nullable" { test "@ptrCast from var in empty struct to nullable" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const container = struct { diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 5113e21452..e854764649 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -96,7 +96,6 @@ test "discard the result of a function that returns a struct" { } test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 85214bd7d8..6b0570cb96 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -571,7 +571,6 @@ test "packed struct passed to callconv(.C) function" { test "overaligned pointer to packed struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const S = packed struct { a: u32, b: u32 }; var foo: S align(4) = .{ .a = 123, .b = 456 }; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index b250b5b087..25dd1c7958 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -827,7 +827,6 @@ test "non-packed struct with u128 entry in union" { } test "packed struct field passed to generic function" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From 8f385e77caae676ad675ca13baea51751230f200 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 03:44:02 -0400 Subject: [PATCH 104/216] x86_64: implement struct_field_val for packed containers --- src/arch/x86_64/CodeGen.zig | 47 ++++++++++++++++++--------------- test/behavior/bitcast.zig | 2 -- test/behavior/bugs/9584.zig | 1 - test/behavior/packed-struct.zig | 4 --- test/behavior/struct.zig | 3 --- test/behavior/union.zig | 2 -- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 5b16ae5a1c..a4e51c7a8d 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3745,18 +3745,22 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { } const mcv = try self.resolveInst(operand); - const struct_ty = self.air.typeOf(operand); - if (struct_ty.zigTypeTag() == .Struct and struct_ty.containerLayout() == .Packed) { - return self.fail("TODO airStructFieldVal implement packed structs", .{}); - } - const struct_field_offset = struct_ty.structFieldOffset(index, self.target.*); - const struct_field_ty = struct_ty.structFieldType(index); + const container_ty = self.air.typeOf(operand); + const field_ty = container_ty.structFieldType(index); + const field_bit_offset = switch (container_ty.containerLayout()) { + .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*) * 8), + .Packed => if (container_ty.castTag(.@"struct")) |struct_obj| + struct_obj.data.packedFieldBitOffset(self.target.*, index) + else + 0, + }; const result: MCValue = result: { switch (mcv) { .stack_offset => |off| { - const stack_offset = off - @intCast(i32, struct_field_offset); - break :result MCValue{ .stack_offset = stack_offset }; + const byte_offset = std.math.divExact(u32, field_bit_offset, 8) catch + return self.fail("TODO implement struct_field_val for a packed struct", .{}); + break :result MCValue{ .stack_offset = off - @intCast(i32, byte_offset) }; }, .register => |reg| { const reg_lock = self.register_manager.lockRegAssumeUnused(reg); @@ -3779,27 +3783,28 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); // Shift by struct_field_offset. - const shift = @intCast(u8, struct_field_offset * 8); - try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv.register, .{ .immediate = shift }); + try self.genShiftBinOpMir( + .shr, + Type.usize, + dst_mcv.register, + .{ .immediate = field_bit_offset }, + ); - // Mask with reg.bitSize() - struct_field_size - const max_reg_bit_width = Register.rax.bitSize(); - const mask_shift = @intCast(u6, (max_reg_bit_width - struct_field_ty.bitSize(self.target.*))); - const mask = (~@as(u64, 0)) >> mask_shift; + // Mask to field_bit_size bits + const field_bit_size = field_ty.bitSize(self.target.*); + const mask = ~@as(u64, 0) >> @intCast(u6, 64 - field_bit_size); const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask }); try self.genBinOpMir(.@"and", Type.usize, dst_mcv, .{ .register = tmp_reg }); - const signedness: std.builtin.Signedness = blk: { - if (struct_field_ty.zigTypeTag() != .Int) break :blk .unsigned; - break :blk struct_field_ty.intInfo(self.target.*).signedness; - }; - const field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); - if (signedness == .signed and field_size < 8) { + const signedness = + if (field_ty.isAbiInt()) field_ty.intInfo(self.target.*).signedness else .unsigned; + const field_byte_size = @intCast(u32, field_ty.abiSize(self.target.*)); + if (signedness == .signed and field_byte_size < 8) { try self.asmRegisterRegister( .movsx, dst_mcv.register, - registerAlias(dst_mcv.register, field_size), + registerAlias(dst_mcv.register, field_byte_size), ); } diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 552080c836..8ac87bb9c0 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -157,7 +157,6 @@ test "bitcast generates a temporary value" { } test "@bitCast packed structs at runtime and comptime" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -215,7 +214,6 @@ test "@bitCast extern structs at runtime and comptime" { } test "bitcast packed struct to integer and back" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/9584.zig b/test/behavior/bugs/9584.zig index f80ff05228..307f1689bf 100644 --- a/test/behavior/bugs/9584.zig +++ b/test/behavior/bugs/9584.zig @@ -44,7 +44,6 @@ pub fn b(x: *X) !void { } test { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 6b0570cb96..6cc021dd1a 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -254,7 +254,6 @@ test "regular in irregular packed struct" { } test "byte-aligned field pointer offsets" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -397,7 +396,6 @@ test "@ptrToInt on a packed struct field" { } test "optional pointer in packed struct" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -530,7 +528,6 @@ test "nested packed struct field access test" { test "runtime init of unnamed packed struct type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var z: u8 = 123; @@ -545,7 +542,6 @@ test "runtime init of unnamed packed struct type" { test "packed struct passed to callconv(.C) function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 25dd1c7958..61318ad6d2 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -387,7 +387,6 @@ const APackedStruct = packed struct { test "packed struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var foo = APackedStruct{ @@ -496,7 +495,6 @@ const Bitfields = packed struct { test "packed struct fields are ordered from LSB to MSB" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var all: u64 = 0x7765443322221111; @@ -632,7 +630,6 @@ test "default struct initialization fields" { } test "packed array 24bits" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/union.zig b/test/behavior/union.zig index b78bac5c3e..35bdca270e 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1408,7 +1408,6 @@ test "union field ptr - zero sized field" { } test "packed union in packed struct" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO @@ -1494,7 +1493,6 @@ test "union reassignment can use previous value" { } test "packed union with zero-bit field" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO From 77300c02d65af81da6019995e4f1a156ef364df4 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 05:16:33 -0400 Subject: [PATCH 105/216] x86_64: implement large ptr_elem_val --- src/arch/x86_64/CodeGen.zig | 150 ++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 82 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index a4e51c7a8d..2b62854fb9 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2386,8 +2386,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { .stack_offset => |off| try self.asmMemoryImmediate( .mov, - Memory.sib(.byte, .{ .base = .rsp, .disp = pl_abi_size - off }), - Immediate.u(0), + Memory.sib(.byte, .{ .base = .rbp, .disp = pl_abi_size - off }), + Immediate.u(1), ), } } @@ -2606,10 +2606,9 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { } fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { - const is_volatile = false; // TODO const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else result: { - const slice_ty = self.air.typeOf(bin_op.lhs); + const slice_ty = self.air.typeOf(bin_op.lhs); + const result = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: { var buf: Type.SlicePtrFieldTypeBuffer = undefined; const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf); const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs); @@ -2696,54 +2695,44 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { } fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { - const is_volatile = false; // TODO const bin_op = self.air.instructions.items(.data)[inst].bin_op; - - if (!is_volatile and self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } - - // this is identical to the `airPtrElemPtr` codegen expect here an - // additional `mov` is needed at the end to get the actual value - const ptr_ty = self.air.typeOf(bin_op.lhs); - const ptr = try self.resolveInst(bin_op.lhs); - const ptr_lock: ?RegisterLock = switch (ptr) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, + const result = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: { + // this is identical to the `airPtrElemPtr` codegen expect here an + // additional `mov` is needed at the end to get the actual value + + const elem_ty = ptr_ty.elemType2(); + const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*)); + const index_ty = self.air.typeOf(bin_op.rhs); + const index_mcv = try self.resolveInst(bin_op.rhs); + const index_lock = switch (index_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (index_lock) |lock| self.register_manager.unlockReg(lock); + + const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size); + const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg); + defer self.register_manager.unlockReg(offset_lock); + + const ptr_mcv = try self.resolveInst(bin_op.lhs); + const elem_ptr_reg = if (ptr_mcv.isRegister() and self.liveness.operandDies(inst, 0)) + ptr_mcv.register + else + try self.copyToTmpRegister(ptr_ty, ptr_mcv); + const elem_ptr_lock = self.register_manager.lockRegAssumeUnused(elem_ptr_reg); + defer self.register_manager.unlockReg(elem_ptr_lock); + try self.asmRegisterRegister(.add, elem_ptr_reg, offset_reg); + + const dst_mcv = try self.allocRegOrMem(inst, true); + const dst_lock = switch (dst_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + try self.load(dst_mcv, .{ .register = elem_ptr_reg }, ptr_ty); + break :result dst_mcv; }; - defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); - - const elem_ty = ptr_ty.elemType2(); - const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*)); - const index_ty = self.air.typeOf(bin_op.rhs); - const index = try self.resolveInst(bin_op.rhs); - const index_lock: ?RegisterLock = switch (index) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (index_lock) |lock| self.register_manager.unlockReg(lock); - - const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); - const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); - defer self.register_manager.unlockReg(offset_reg_lock); - - const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); - try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); - - const result: MCValue = result: { - if (elem_abi_size > 8) { - return self.fail("TODO copy value with size {} from pointer", .{elem_abi_size}); - } else { - try self.asmRegisterMemory( - .mov, - registerAlias(dst_mcv.register, elem_abi_size), - Memory.sib(Memory.PtrSize.fromSize(elem_abi_size), .{ .base = dst_mcv.register }), - ); - break :result .{ .register = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)) }; - } - }; - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -2751,36 +2740,34 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); - } + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_ty = self.air.typeOf(extra.lhs); + const ptr = try self.resolveInst(extra.lhs); + const ptr_lock: ?RegisterLock = switch (ptr) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); - const ptr_ty = self.air.typeOf(extra.lhs); - const ptr = try self.resolveInst(extra.lhs); - const ptr_lock: ?RegisterLock = switch (ptr) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, + const elem_ty = ptr_ty.elemType2(); + const elem_abi_size = elem_ty.abiSize(self.target.*); + const index_ty = self.air.typeOf(extra.rhs); + const index = try self.resolveInst(extra.rhs); + const index_lock: ?RegisterLock = switch (index) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (index_lock) |lock| self.register_manager.unlockReg(lock); + + const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); + const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); + defer self.register_manager.unlockReg(offset_reg_lock); + + const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); + try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); + break :result dst_mcv; }; - defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); - - const elem_ty = ptr_ty.elemType2(); - const elem_abi_size = elem_ty.abiSize(self.target.*); - const index_ty = self.air.typeOf(extra.rhs); - const index = try self.resolveInst(extra.rhs); - const index_lock: ?RegisterLock = switch (index) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (index_lock) |lock| self.register_manager.unlockReg(lock); - - const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); - const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); - defer self.register_manager.unlockReg(offset_reg_lock); - - const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); - try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); - - return self.finishAir(inst, dst_mcv, .{ extra.lhs, extra.rhs, .none }); + return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); } fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { @@ -2953,12 +2940,11 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { const extra_bits = self.regExtraBits(src_ty); const masked_mcv = if (extra_bits > 0) masked: { const mask_mcv = MCValue{ - .immediate = ((@as(u64, 1) << @intCast(u6, extra_bits)) - 1) << @intCast(u6, src_bits), + .immediate = ((@as(u64, 1) << @intCast(u6, extra_bits)) - 1) << + @intCast(u6, src_bits), }; const tmp_mcv = tmp: { - if (src_mcv.isImmediate() or self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) { - break :tmp src_mcv; - } + if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0)) break :tmp src_mcv; try self.genSetReg(src_ty, dst_reg, src_mcv); break :tmp dst_mcv; }; From d064cf639f0f05f0f5dda84c228783c37db010b8 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 08:58:00 -0400 Subject: [PATCH 106/216] x86_64: implement 128-bit shifts --- src/arch/x86_64/CodeGen.zig | 609 +++++++++++++++++++++------------- src/arch/x86_64/Emit.zig | 95 ++++-- src/arch/x86_64/Encoding.zig | 13 +- src/arch/x86_64/Mir.zig | 84 +++-- src/arch/x86_64/encoder.zig | 20 +- src/arch/x86_64/encodings.zig | 14 + 6 files changed, 543 insertions(+), 292 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 2b62854fb9..f010a00551 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -409,10 +409,7 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { _ = try self.addInst(.{ .tag = .setcc, .ops = .r_cc, - .data = .{ .r_cc = .{ - .r1 = reg, - .cc = cc, - } }, + .data = .{ .r_cc = .{ .r = reg, .cc = cc } }, }); } @@ -424,14 +421,11 @@ fn asmSetccMemory(self: *Self, m: Memory, cc: bits.Condition) !void { .rip => .m_rip_cc, else => unreachable, }, - .data = .{ .x_cc = .{ - .payload = switch (m) { - .sib => try self.addExtra(Mir.MemorySib.encode(m)), - .rip => try self.addExtra(Mir.MemoryRip.encode(m)), - else => unreachable, - }, - .cc = cc, - } }, + .data = .{ .x_cc = .{ .cc = cc, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, }); } @@ -439,11 +433,7 @@ fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bi _ = try self.addInst(.{ .tag = .cmovcc, .ops = .rr_cc, - .data = .{ .rr_cc = .{ - .r1 = reg1, - .r2 = reg2, - .cc = cc, - } }, + .data = .{ .rr_cc = .{ .r1 = reg1, .r2 = reg2, .cc = cc } }, }); } @@ -455,15 +445,11 @@ fn asmCmovccRegisterMemory(self: *Self, reg: Register, m: Memory, cc: bits.Condi .rip => .rm_rip_cc, else => unreachable, }, - .data = .{ .rx_cc = .{ - .r1 = reg, - .cc = cc, - .payload = switch (m) { - .sib => try self.addExtra(Mir.MemorySib.encode(m)), - .rip => try self.addExtra(Mir.MemoryRip.encode(m)), - else => unreachable, - }, - } }, + .data = .{ .rx_cc = .{ .r = reg, .cc = cc, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, }); } @@ -479,10 +465,7 @@ fn asmJccReloc(self: *Self, target: Mir.Inst.Index, cc: bits.Condition) !Mir.Ins return self.addInst(.{ .tag = .jcc, .ops = .inst_cc, - .data = .{ .inst_cc = .{ - .inst = target, - .cc = cc, - } }, + .data = .{ .inst_cc = .{ .inst = target, .cc = cc } }, }); } @@ -503,13 +486,15 @@ fn asmRegister(self: *Self, tag: Mir.Inst.Tag, reg: Register) !void { } fn asmImmediate(self: *Self, tag: Mir.Inst.Tag, imm: Immediate) !void { - const ops: Mir.Inst.Ops = if (imm == .signed) .imm_s else .imm_u; _ = try self.addInst(.{ .tag = tag, - .ops = ops, - .data = .{ .imm = switch (imm) { - .signed => |x| @bitCast(u32, x), - .unsigned => |x| @intCast(u32, x), + .ops = switch (imm) { + .signed => .i_s, + .unsigned => .i_u, + }, + .data = .{ .i = switch (imm) { + .signed => |s| @bitCast(u32, s), + .unsigned => |u| @intCast(u32, u), } }, }); } @@ -518,37 +503,43 @@ fn asmRegisterRegister(self: *Self, tag: Mir.Inst.Tag, reg1: Register, reg2: Reg _ = try self.addInst(.{ .tag = tag, .ops = .rr, - .data = .{ .rr = .{ - .r1 = reg1, - .r2 = reg2, - } }, + .data = .{ .rr = .{ .r1 = reg1, .r2 = reg2 } }, }); } fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.Tag, reg: Register, imm: Immediate) !void { const ops: Mir.Inst.Ops = switch (imm) { .signed => .ri_s, - .unsigned => |x| if (x <= math.maxInt(u32)) .ri_u else .ri64, - }; - const data: Mir.Inst.Data = switch (ops) { - .ri_s => .{ .ri = .{ - .r1 = reg, - .imm = @bitCast(u32, imm.signed), - } }, - .ri_u => .{ .ri = .{ - .r1 = reg, - .imm = @intCast(u32, imm.unsigned), - } }, - .ri64 => .{ .rx = .{ - .r1 = reg, - .payload = try self.addExtra(Mir.Imm64.encode(imm.unsigned)), - } }, - else => unreachable, + .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64, }; _ = try self.addInst(.{ .tag = tag, .ops = ops, - .data = data, + .data = switch (ops) { + .ri_s, .ri_u => .{ .ri = .{ .r = reg, .i = switch (imm) { + .signed => |s| @bitCast(u32, s), + .unsigned => |u| @intCast(u32, u), + } } }, + .ri64 => .{ .rx = .{ + .r = reg, + .payload = try self.addExtra(Mir.Imm64.encode(imm.unsigned)), + } }, + else => unreachable, + }, + }); +} + +fn asmRegisterRegisterRegister( + self: *Self, + tag: Mir.Inst.Tag, + reg1: Register, + reg2: Register, + reg3: Register, +) !void { + _ = try self.addInst(.{ + .tag = tag, + .ops = .rrr, + .data = .{ .rrr = .{ .r1 = reg1, .r2 = reg2, .r3 = reg3 } }, }); } @@ -559,109 +550,142 @@ fn asmRegisterRegisterImmediate( reg2: Register, imm: Immediate, ) !void { - const ops: Mir.Inst.Ops = switch (imm) { - .signed => .rri_s, - .unsigned => .rri_u, - }; - const data: Mir.Inst.Data = switch (ops) { - .rri_s => .{ .rri = .{ - .r1 = reg1, - .r2 = reg2, - .imm = @bitCast(u32, imm.signed), - } }, - .rri_u => .{ .rri = .{ - .r1 = reg1, - .r2 = reg2, - .imm = @intCast(u32, imm.unsigned), - } }, - else => unreachable, - }; _ = try self.addInst(.{ .tag = tag, - .ops = ops, - .data = data, + .ops = switch (imm) { + .signed => .rri_s, + .unsigned => .rri_u, + }, + .data = .{ .rri = .{ .r1 = reg1, .r2 = reg2, .i = switch (imm) { + .signed => |s| @bitCast(u32, s), + .unsigned => |u| @intCast(u32, u), + } } }, }); } fn asmMemory(self: *Self, tag: Mir.Inst.Tag, m: Memory) !void { - const ops: Mir.Inst.Ops = switch (m) { - .sib => .m_sib, - .rip => .m_rip, - else => unreachable, - }; - const data: Mir.Inst.Data = .{ .payload = switch (ops) { - .m_sib => try self.addExtra(Mir.MemorySib.encode(m)), - .m_rip => try self.addExtra(Mir.MemoryRip.encode(m)), - else => unreachable, - } }; _ = try self.addInst(.{ .tag = tag, - .ops = ops, - .data = data, - }); -} - -fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.Tag, m: Memory, imm: Immediate) !void { - const ops: Mir.Inst.Ops = switch (m) { - .sib => if (imm == .signed) .mi_s_sib else .mi_u_sib, - .rip => if (imm == .signed) .mi_s_rip else .mi_u_rip, - else => unreachable, - }; - const payload: u32 = switch (ops) { - .mi_s_sib, .mi_u_sib => try self.addExtra(Mir.MemorySib.encode(m)), - .mi_s_rip, .mi_u_rip => try self.addExtra(Mir.MemoryRip.encode(m)), - else => unreachable, - }; - const data: Mir.Inst.Data = .{ - .xi = .{ .payload = payload, .imm = switch (imm) { - .signed => |x| @bitCast(u32, x), - .unsigned => |x| @intCast(u32, x), + .ops = switch (m) { + .sib => .m_sib, + .rip => .m_rip, + else => unreachable, + }, + .data = .{ .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, } }, - }; - _ = try self.addInst(.{ - .tag = tag, - .ops = ops, - .data = data, }); } fn asmRegisterMemory(self: *Self, tag: Mir.Inst.Tag, reg: Register, m: Memory) !void { - const ops: Mir.Inst.Ops = switch (m) { - .sib => .rm_sib, - .rip => .rm_rip, - else => unreachable, - }; - const data: Mir.Inst.Data = .{ - .rx = .{ .r1 = reg, .payload = switch (ops) { - .rm_sib => try self.addExtra(Mir.MemorySib.encode(m)), - .rm_rip => try self.addExtra(Mir.MemoryRip.encode(m)), - else => unreachable, - } }, - }; _ = try self.addInst(.{ .tag = tag, - .ops = ops, - .data = data, + .ops = switch (m) { + .sib => .rm_sib, + .rip => .rm_rip, + else => unreachable, + }, + .data = .{ .rx = .{ .r = reg, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, }); } fn asmMemoryRegister(self: *Self, tag: Mir.Inst.Tag, m: Memory, reg: Register) !void { - const ops: Mir.Inst.Ops = switch (m) { - .sib => .mr_sib, - .rip => .mr_rip, - else => unreachable, - }; - const data: Mir.Inst.Data = .{ - .rx = .{ .r1 = reg, .payload = switch (ops) { - .mr_sib => try self.addExtra(Mir.MemorySib.encode(m)), - .mr_rip => try self.addExtra(Mir.MemoryRip.encode(m)), - else => unreachable, - } }, - }; _ = try self.addInst(.{ .tag = tag, - .ops = ops, - .data = data, + .ops = switch (m) { + .sib => .mr_sib, + .rip => .mr_rip, + else => unreachable, + }, + .data = .{ .rx = .{ .r = reg, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, + }); +} + +fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.Tag, m: Memory, imm: Immediate) !void { + _ = try self.addInst(.{ + .tag = tag, + .ops = switch (m) { + .sib => switch (imm) { + .signed => .mi_sib_s, + .unsigned => .mi_sib_u, + }, + .rip => switch (imm) { + .signed => .mi_rip_s, + .unsigned => .mi_rip_u, + }, + else => unreachable, + }, + .data = .{ .ix = .{ .i = switch (imm) { + .signed => |s| @bitCast(u32, s), + .unsigned => |u| @intCast(u32, u), + }, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, + }); +} + +fn asmMemoryRegisterRegister( + self: *Self, + tag: Mir.Inst.Tag, + m: Memory, + reg1: Register, + reg2: Register, +) !void { + _ = try self.addInst(.{ + .tag = tag, + .ops = switch (m) { + .sib => .mrr_sib, + .rip => .mrr_rip, + else => unreachable, + }, + .data = .{ .rrx = .{ .r1 = reg1, .r2 = reg2, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, + }); +} + +fn asmMemoryRegisterImmediate( + self: *Self, + tag: Mir.Inst.Tag, + m: Memory, + reg: Register, + imm: Immediate, +) !void { + _ = try self.addInst(.{ + .tag = tag, + .ops = switch (m) { + .sib => switch (imm) { + .signed => .mri_sib_s, + .unsigned => .mri_sib_u, + }, + .rip => switch (imm) { + .signed => .mri_rip_s, + .unsigned => .mri_sib_u, + }, + else => unreachable, + }, + .data = .{ .rix = .{ .r = reg, .i = switch (imm) { + .signed => |s| @bitCast(u32, s), + .unsigned => |u| @intCast(u32, u), + }, .payload = switch (m) { + .sib => try self.addExtra(Mir.MemorySib.encode(m)), + .rip => try self.addExtra(Mir.MemoryRip.encode(m)), + else => unreachable, + } } }, }); } @@ -768,18 +792,12 @@ fn gen(self: *Self) InnerError!void { self.mir_instructions.set(backpatch_stack_sub, .{ .tag = .sub, .ops = .ri_u, - .data = .{ .ri = .{ - .r1 = .rsp, - .imm = aligned_stack_end, - } }, + .data = .{ .ri = .{ .r = .rsp, .i = aligned_stack_end } }, }); self.mir_instructions.set(backpatch_stack_add, .{ .tag = .add, .ops = .ri_u, - .data = .{ .ri = .{ - .r1 = .rsp, - .imm = aligned_stack_end, - } }, + .data = .{ .ri = .{ .r = .rsp, .i = aligned_stack_end } }, }); const save_reg_list = try self.addExtra(Mir.SaveRegisterList{ @@ -1732,6 +1750,7 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { .add_with_overflow => try self.genBinOp(null, .add, bin_op.lhs, bin_op.rhs), .sub_with_overflow => try self.genBinOp(null, .sub, bin_op.lhs, bin_op.rhs), .shl_with_overflow => blk: { + try self.register_manager.getReg(.rcx, null); const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); const shift_ty = self.air.typeOf(bin_op.rhs); @@ -2022,6 +2041,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { try self.spillRegisters(&.{.rcx}); const tag = self.air.instructions.items(.tag)[inst]; + try self.register_manager.getReg(.rcx, null); const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); const lhs_ty = self.air.typeOf(bin_op.lhs); @@ -2151,7 +2171,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand); if (err_off > 0) { const shift = @intCast(u6, err_off * 8); - try self.genShiftBinOpMir(.shr, err_union_ty, result.register, .{ .immediate = shift }); + try self.genShiftBinOpMir(.shr, err_union_ty, result, .{ .immediate = shift }); } else { try self.truncateRegister(Type.anyerror, result.register); } @@ -2183,9 +2203,7 @@ fn genUnwrapErrorUnionPayloadMir( const payload_ty = err_union_ty.errorUnionPayload(); const result: MCValue = result: { - if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { - break :result MCValue.none; - } + if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; const payload_off = errUnionPayloadOffset(payload_ty, self.target.*); switch (err_union) { @@ -2198,17 +2216,17 @@ fn genUnwrapErrorUnionPayloadMir( const eu_lock = self.register_manager.lockReg(reg); defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); - const result_reg: Register = if (maybe_inst) |inst| - (try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union)).register + const result_mcv: MCValue = if (maybe_inst) |inst| + try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union) else - try self.copyToTmpRegister(err_union_ty, err_union); + .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) }; if (payload_off > 0) { const shift = @intCast(u6, payload_off * 8); - try self.genShiftBinOpMir(.shr, err_union_ty, result_reg, .{ .immediate = shift }); + try self.genShiftBinOpMir(.shr, err_union_ty, result_mcv, .{ .immediate = shift }); } else { - try self.truncateRegister(payload_ty, result_reg); + try self.truncateRegister(payload_ty, result_mcv.register); } - break :result MCValue{ .register = result_reg }; + break :result result_mcv; }, else => return self.fail("TODO implement genUnwrapErrorUnionPayloadMir for {}", .{err_union}), } @@ -2848,7 +2866,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { else 0; const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); - try self.genShiftBinOpMir(.shr, Type.usize, result.register, .{ .immediate = shift }); + try self.genShiftBinOpMir(.shr, Type.usize, result, .{ .immediate = shift }); break :blk MCValue{ .register = registerAlias(result.register, @intCast(u32, layout.tag_size)), }; @@ -3769,12 +3787,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); // Shift by struct_field_offset. - try self.genShiftBinOpMir( - .shr, - Type.usize, - dst_mcv.register, - .{ .immediate = field_bit_offset }, - ); + try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv, .{ .immediate = field_bit_offset }); // Mask to field_bit_size bits const field_bit_size = field_ty.bitSize(self.target.*); @@ -3932,29 +3945,186 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue } /// Clobbers .rcx for non-immediate shift value. -fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shift: MCValue) !void { - switch (tag) { - .sal, .sar, .shl, .shr => {}, - else => unreachable, - } - - const abi_size = @intCast(u32, ty.abiSize(self.target.*)); - blk: { - switch (shift) { +fn genShiftBinOpMir( + self: *Self, + tag: Mir.Inst.Tag, + ty: Type, + lhs_mcv: MCValue, + shift_mcv: MCValue, +) !void { + const rhs_mcv: MCValue = rhs: { + switch (shift_mcv) { .immediate => |imm| switch (imm) { 0 => return, - else => return self.asmRegisterImmediate(tag, registerAlias(reg, abi_size), Immediate.u(imm)), - }, - .register => |shift_reg| { - if (shift_reg == .rcx) break :blk; + else => break :rhs shift_mcv, }, + .register => |shift_reg| if (shift_reg == .rcx) break :rhs shift_mcv, else => {}, } self.register_manager.getRegAssumeFree(.rcx, null); - try self.genSetReg(Type.u8, .rcx, shift); - } + try self.genSetReg(Type.u8, .rcx, shift_mcv); + break :rhs .{ .register = .rcx }; + }; - try self.asmRegisterRegister(tag, registerAlias(reg, abi_size), .cl); + const abi_size = @intCast(u32, ty.abiSize(self.target.*)); + if (abi_size <= 8) { + switch (lhs_mcv) { + .register => |lhs_reg| switch (rhs_mcv) { + .immediate => |rhs_imm| try self.asmRegisterImmediate( + tag, + registerAlias(lhs_reg, abi_size), + Immediate.u(rhs_imm), + ), + .register => |rhs_reg| try self.asmRegisterRegister( + tag, + registerAlias(lhs_reg, abi_size), + registerAlias(rhs_reg, 1), + ), + else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + @tagName(lhs_mcv), + @tagName(rhs_mcv), + }), + }, + .stack_offset => |lhs_off| switch (rhs_mcv) { + .immediate => |rhs_imm| try self.asmMemoryImmediate( + tag, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -lhs_off }), + Immediate.u(rhs_imm), + ), + .register => |rhs_reg| try self.asmMemoryRegister( + tag, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -lhs_off }), + registerAlias(rhs_reg, 1), + ), + else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + @tagName(lhs_mcv), + @tagName(rhs_mcv), + }), + }, + else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + @tagName(lhs_mcv), + @tagName(rhs_mcv), + }), + } + } else if (abi_size <= 16) { + const tmp_reg = try self.register_manager.allocReg(null, gp); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); + + const info: struct { offsets: [2]i32, double_tag: Mir.Inst.Tag } = switch (tag) { + .shl, .sal => .{ .offsets = .{ 0, 8 }, .double_tag = .shld }, + .shr, .sar => .{ .offsets = .{ 8, 0 }, .double_tag = .shrd }, + else => unreachable, + }; + switch (lhs_mcv) { + .stack_offset => |dst_off| switch (rhs_mcv) { + .immediate => |rhs_imm| if (rhs_imm == 0) {} else if (rhs_imm < 64) { + try self.asmRegisterMemory( + .mov, + tmp_reg, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + ); + try self.asmMemoryRegisterImmediate( + info.double_tag, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[1] - dst_off }), + tmp_reg, + Immediate.u(rhs_imm), + ); + try self.asmMemoryImmediate( + tag, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + Immediate.u(rhs_imm), + ); + } else { + assert(rhs_imm < 128); + try self.asmRegisterMemory( + .mov, + tmp_reg, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + ); + if (rhs_imm > 64) { + try self.asmRegisterImmediate(tag, tmp_reg, Immediate.u(rhs_imm - 64)); + } + try self.asmMemoryRegister( + .mov, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[1] - dst_off }), + tmp_reg, + ); + switch (tag) { + .shl, .sal, .shr => { + try self.asmRegisterRegister(.xor, tmp_reg.to32(), tmp_reg.to32()); + try self.asmMemoryRegister( + .mov, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + tmp_reg, + ); + }, + .sar => try self.asmMemoryImmediate( + tag, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + Immediate.u(63), + ), + else => unreachable, + } + }, + else => { + const first_reg = try self.register_manager.allocReg(null, gp); + const first_lock = self.register_manager.lockRegAssumeUnused(first_reg); + defer self.register_manager.unlockReg(first_lock); + + const second_reg = try self.register_manager.allocReg(null, gp); + const second_lock = self.register_manager.lockRegAssumeUnused(second_reg); + defer self.register_manager.unlockReg(second_lock); + + try self.genSetReg(Type.u8, .cl, rhs_mcv); + try self.asmRegisterMemory( + .mov, + first_reg, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + ); + try self.asmRegisterMemory( + .mov, + second_reg, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[1] - dst_off }), + ); + switch (tag) { + .shl, .sal, .shr => try self.asmRegisterRegister( + .xor, + tmp_reg.to32(), + tmp_reg.to32(), + ), + .sar => { + try self.asmRegisterRegister(.mov, tmp_reg, first_reg); + try self.asmRegisterImmediate(tag, tmp_reg, Immediate.u(63)); + }, + else => unreachable, + } + try self.asmRegisterRegisterRegister(info.double_tag, second_reg, first_reg, .cl); + try self.asmRegisterRegister(tag, first_reg, .cl); + try self.asmRegisterImmediate(.cmp, .cl, Immediate.u(64)); + try self.asmCmovccRegisterRegister(second_reg, first_reg, .ae); + try self.asmCmovccRegisterRegister(first_reg, tmp_reg, .ae); + try self.asmMemoryRegister( + .mov, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[1] - dst_off }), + second_reg, + ); + try self.asmMemoryRegister( + .mov, + Memory.sib(.qword, .{ .base = .rbp, .disp = info.offsets[0] - dst_off }), + first_reg, + ); + }, + }, + else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + @tagName(lhs_mcv), + @tagName(rhs_mcv), + }), + } + } else return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + @tagName(lhs_mcv), + @tagName(rhs_mcv), + }); } /// Result is always a register. @@ -3964,68 +4134,61 @@ fn genShiftBinOp( self: *Self, tag: Air.Inst.Tag, maybe_inst: ?Air.Inst.Index, - lhs: MCValue, - rhs: MCValue, + lhs_mcv: MCValue, + rhs_mcv: MCValue, lhs_ty: Type, rhs_ty: Type, ) !MCValue { - if (lhs_ty.zigTypeTag() == .Vector or lhs_ty.zigTypeTag() == .Float) { - return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()}); - } - if (lhs_ty.abiSize(self.target.*) > 8) { + if (lhs_ty.zigTypeTag() == .Vector) { return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()}); } assert(rhs_ty.abiSize(self.target.*) == 1); - const lhs_lock: ?RegisterLock = switch (lhs) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); - - const rhs_lock: ?RegisterLock = switch (rhs) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); + const lhs_abi_size = lhs_ty.abiSize(self.target.*); + if (lhs_abi_size > 16) { + return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()}); + } self.register_manager.getRegAssumeFree(.rcx, null); const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx); defer self.register_manager.unlockReg(rcx_lock); - const dst: MCValue = blk: { + const lhs_lock = switch (lhs_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); + + const rhs_lock = switch (rhs_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv: MCValue = dst: { if (maybe_inst) |inst| { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - // TODO dst can also be a memory location - if (self.reuseOperand(inst, bin_op.lhs, 0, lhs) and lhs.isRegister()) { - break :blk lhs; - } - break :blk try self.copyToRegisterWithInstTracking(inst, lhs_ty, lhs); + if (self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv)) break :dst lhs_mcv; } - break :blk MCValue{ .register = try self.copyToTmpRegister(lhs_ty, lhs) }; + const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); + try self.setRegOrMem(lhs_ty, dst_mcv, lhs_mcv); + break :dst dst_mcv; }; const signedness = lhs_ty.intInfo(self.target.*).signedness; - switch (tag) { - .shl => try self.genShiftBinOpMir(switch (signedness) { + try self.genShiftBinOpMir(switch (tag) { + .shl, .shl_exact => switch (signedness) { .signed => .sal, .unsigned => .shl, - }, lhs_ty, dst.register, rhs), - - .shl_exact => try self.genShiftBinOpMir(.shl, lhs_ty, dst.register, rhs), - - .shr, - .shr_exact, - => try self.genShiftBinOpMir(switch (signedness) { + }, + .shr, .shr_exact => switch (signedness) { .signed => .sar, .unsigned => .shr, - }, lhs_ty, dst.register, rhs), - + }, else => unreachable, - } - - return dst; + }, lhs_ty, dst_mcv, rhs_mcv); + return dst_mcv; } /// Result is always a register. @@ -5552,7 +5715,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! const tmp_reg = try self.copyToTmpRegister(ty, operand); if (err_off > 0) { const shift = @intCast(u6, err_off * 8); - try self.genShiftBinOpMir(.shr, ty, tmp_reg, .{ .immediate = shift }); + try self.genShiftBinOpMir(.shr, ty, .{ .register = tmp_reg }, .{ .immediate = shift }); } else { try self.truncateRegister(Type.anyerror, tmp_reg); } @@ -6506,7 +6669,7 @@ fn genInlineMemcpyRegisterRegister( }), registerAlias(tmp_reg, nearest_power_of_two)); if (nearest_power_of_two > 1) { - try self.genShiftBinOpMir(.shr, ty, tmp_reg, .{ + try self.genShiftBinOpMir(.shr, ty, .{ .register = tmp_reg }, .{ .immediate = nearest_power_of_two * 8, }); } @@ -7032,7 +7195,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { try self.spillEflagsIfOccupied(); _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{ - .r1 = new_reg, + .r = new_reg, .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), } } }); @@ -7110,7 +7273,7 @@ fn atomicOp( .xadd, .add, .sub, .@"and", .@"or", .xor => .lock_mr_sib, else => unreachable, }, .data = .{ .rx = .{ - .r1 = registerAlias(dst_reg, val_abi_size), + .r = registerAlias(dst_reg, val_abi_size), .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), } } }); return; @@ -7702,8 +7865,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { switch (int_info.signedness) { .signed => { const shift = @intCast(u6, max_reg_bit_width - int_info.bits); - try self.genShiftBinOpMir(.sal, Type.isize, reg, .{ .immediate = shift }); - try self.genShiftBinOpMir(.sar, Type.isize, reg, .{ .immediate = shift }); + try self.genShiftBinOpMir(.sal, Type.isize, .{ .register = reg }, .{ .immediate = shift }); + try self.genShiftBinOpMir(.sar, Type.isize, .{ .register = reg }, .{ .immediate = shift }); }, .unsigned => { const shift = @intCast(u6, max_reg_bit_width - int_info.bits); diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index cd8389aa49..b4218f48a9 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -121,7 +121,9 @@ pub fn lowerMir(emit: *Emit) InnerError!void { .sbb, .sfence, .shl, + .shld, .shr, + .shrd, .sub, .syscall, .@"test", @@ -231,10 +233,10 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE const prefix: Instruction.Prefix = switch (ops) { .lock_m_sib, .lock_m_rip, - .lock_mi_u_sib, - .lock_mi_u_rip, - .lock_mi_s_sib, - .lock_mi_s_rip, + .lock_mi_sib_u, + .lock_mi_rip_u, + .lock_mi_sib_s, + .lock_mi_rip_s, .lock_mr_sib, .lock_mr_rip, .lock_moffs_rax, @@ -249,31 +251,36 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE switch (ops) { .none => {}, - .imm_s => op1 = .{ .imm = Immediate.s(@bitCast(i32, data.imm)) }, - .imm_u => op1 = .{ .imm = Immediate.u(data.imm) }, + .i_s => op1 = .{ .imm = Immediate.s(@bitCast(i32, data.i)) }, + .i_u => op1 = .{ .imm = Immediate.u(data.i) }, .r => op1 = .{ .reg = data.r }, .rr => { op1 = .{ .reg = data.rr.r1 }; op2 = .{ .reg = data.rr.r2 }; }, + .rrr => { + op1 = .{ .reg = data.rrr.r1 }; + op2 = .{ .reg = data.rrr.r2 }; + op3 = .{ .reg = data.rrr.r3 }; + }, .ri_s, .ri_u => { const imm = switch (ops) { - .ri_s => Immediate.s(@bitCast(i32, data.ri.imm)), - .ri_u => Immediate.u(data.ri.imm), + .ri_s => Immediate.s(@bitCast(i32, data.ri.i)), + .ri_u => Immediate.u(data.ri.i), else => unreachable, }; - op1 = .{ .reg = data.ri.r1 }; + op1 = .{ .reg = data.ri.r }; op2 = .{ .imm = imm }; }, .ri64 => { const imm64 = emit.mir.extraData(Mir.Imm64, data.rx.payload).data; - op1 = .{ .reg = data.rx.r1 }; + op1 = .{ .reg = data.rx.r }; op2 = .{ .imm = Immediate.u(Mir.Imm64.decode(imm64)) }; }, .rri_s, .rri_u => { const imm = switch (ops) { - .rri_s => Immediate.s(@bitCast(i32, data.rri.imm)), - .rri_u => Immediate.u(data.rri.imm), + .rri_s => Immediate.s(@bitCast(i32, data.rri.i)), + .rri_u => Immediate.u(data.rri.i), else => unreachable, }; op1 = .{ .reg = data.rri.r1 }; @@ -288,21 +295,21 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE const mrip = emit.mir.extraData(Mir.MemoryRip, data.payload).data; op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; }, - .mi_s_sib, .mi_u_sib, .lock_mi_s_sib, .lock_mi_u_sib => { - const msib = emit.mir.extraData(Mir.MemorySib, data.xi.payload).data; + .mi_sib_s, .mi_sib_u, .lock_mi_sib_s, .lock_mi_sib_u => { + const msib = emit.mir.extraData(Mir.MemorySib, data.ix.payload).data; const imm = switch (ops) { - .mi_s_sib, .lock_mi_s_sib => Immediate.s(@bitCast(i32, data.xi.imm)), - .mi_u_sib, .lock_mi_u_sib => Immediate.u(data.xi.imm), + .mi_sib_s, .lock_mi_sib_s => Immediate.s(@bitCast(i32, data.ix.i)), + .mi_sib_u, .lock_mi_sib_u => Immediate.u(data.ix.i), else => unreachable, }; op1 = .{ .mem = Mir.MemorySib.decode(msib) }; op2 = .{ .imm = imm }; }, - .mi_u_rip, .mi_s_rip, .lock_mi_u_rip, .lock_mi_s_rip => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.xi.payload).data; + .mi_rip_u, .mi_rip_s, .lock_mi_rip_u, .lock_mi_rip_s => { + const mrip = emit.mir.extraData(Mir.MemoryRip, data.ix.payload).data; const imm = switch (ops) { - .mi_s_rip, .lock_mi_s_rip => Immediate.s(@bitCast(i32, data.xi.imm)), - .mi_u_rip, .lock_mi_u_rip => Immediate.u(data.xi.imm), + .mi_rip_s, .lock_mi_rip_s => Immediate.s(@bitCast(i32, data.ix.i)), + .mi_rip_u, .lock_mi_rip_u => Immediate.u(data.ix.i), else => unreachable, }; op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; @@ -310,7 +317,7 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE }, .rm_sib, .mr_sib, .lock_mr_sib => { const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data; - const op_r = .{ .reg = data.rx.r1 }; + const op_r = .{ .reg = data.rx.r }; const op_m = .{ .mem = Mir.MemorySib.decode(msib) }; switch (ops) { .rm_sib => { @@ -326,7 +333,7 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE }, .rm_rip, .mr_rip, .lock_mr_rip => { const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data; - const op_r = .{ .reg = data.rx.r1 }; + const op_r = .{ .reg = data.rx.r }; const op_m = .{ .mem = Mir.MemoryRip.decode(mrip) }; switch (ops) { .rm_rip => { @@ -340,6 +347,40 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE else => unreachable, } }, + .mrr_sib => { + const msib = emit.mir.extraData(Mir.MemorySib, data.rrx.payload).data; + op1 = .{ .mem = Mir.MemorySib.decode(msib) }; + op2 = .{ .reg = data.rrx.r1 }; + op2 = .{ .reg = data.rrx.r2 }; + }, + .mrr_rip => { + const mrip = emit.mir.extraData(Mir.MemoryRip, data.rrx.payload).data; + op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; + op2 = .{ .reg = data.rrx.r1 }; + op2 = .{ .reg = data.rrx.r2 }; + }, + .mri_sib_u, .mri_sib_s => { + const msib = emit.mir.extraData(Mir.MemorySib, data.rix.payload).data; + const imm = switch (ops) { + .mri_sib_s => Immediate.s(@bitCast(i32, data.rix.i)), + .mri_sib_u, .lock_mi_rip_u => Immediate.u(data.rix.i), + else => unreachable, + }; + op1 = .{ .mem = Mir.MemorySib.decode(msib) }; + op2 = .{ .reg = data.rix.r }; + op3 = .{ .imm = imm }; + }, + .mri_rip_u, .mri_rip_s => { + const mrip = emit.mir.extraData(Mir.MemoryRip, data.rix.payload).data; + const imm = switch (ops) { + .mri_rip_s => Immediate.s(@bitCast(i32, data.rix.i)), + .mri_rip_u, .lock_mi_rip_u => Immediate.u(data.rix.i), + else => unreachable, + }; + op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; + op2 = .{ .reg = data.rix.r }; + op3 = .{ .imm = imm }; + }, else => return emit.fail("TODO handle generic encoding: {s}, {s}", .{ @tagName(mnemonic), @tagName(ops), @@ -451,12 +492,12 @@ fn mirMovsx(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { }, .rm_sib => { const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data; - op1 = .{ .reg = data.rx.r1 }; + op1 = .{ .reg = data.rx.r }; op2 = .{ .mem = Mir.MemorySib.decode(msib) }; }, .rm_rip => { const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data; - op1 = .{ .reg = data.rx.r1 }; + op1 = .{ .reg = data.rx.r }; op2 = .{ .mem = Mir.MemoryRip.decode(mrip) }; }, else => unreachable, // TODO @@ -495,7 +536,7 @@ fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data; const mnemonic = mnemonicFromConditionCode("cmov", data.cc); return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r1 }, + .op1 = .{ .reg = data.r }, .op2 = .{ .mem = Mir.MemorySib.decode(extra) }, }); }, @@ -504,7 +545,7 @@ fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data; const mnemonic = mnemonicFromConditionCode("cmov", data.cc); return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r1 }, + .op1 = .{ .reg = data.r }, .op2 = .{ .mem = Mir.MemoryRip.decode(extra) }, }); }, @@ -519,7 +560,7 @@ fn mirSetcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { const data = emit.mir.instructions.items(.data)[inst].r_cc; const mnemonic = mnemonicFromConditionCode("set", data.cc); return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r1 }, + .op1 = .{ .reg = data.r }, }); }, .m_sib_cc => { diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 891fc4e9a1..de669a9f8d 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -262,15 +262,15 @@ pub fn format( try writer.print("+{s} ", .{tag}); }, .m, .mi, .m1, .mc => try writer.print("/{d} ", .{encoding.modRmExt()}), - .mr, .rm, .rmi => try writer.writeAll("/r "), + .mr, .rm, .rmi, .mri, .mrc => try writer.writeAll("/r "), } switch (encoding.op_en) { - .i, .d, .zi, .oi, .mi, .rmi => { + .i, .d, .zi, .oi, .mi, .rmi, .mri => { const op = switch (encoding.op_en) { .i, .d => encoding.op1, .zi, .oi, .mi => encoding.op2, - .rmi => encoding.op3, + .rmi, .mri => encoding.op3, else => unreachable, }; const tag = switch (op) { @@ -285,7 +285,7 @@ pub fn format( }; try writer.print("{s} ", .{tag}); }, - .np, .fd, .td, .o, .m, .m1, .mc, .mr, .rm => {}, + .np, .fd, .td, .o, .m, .m1, .mc, .mr, .rm, .mrc => {}, } try writer.print("{s} ", .{@tagName(encoding.mnemonic)}); @@ -334,7 +334,7 @@ pub const Mnemonic = enum { rcl, rcr, ret, rol, ror, sal, sar, sbb, scas, scasb, scasd, scasq, scasw, - shl, shr, sub, syscall, + shl, shld, shr, shrd, sub, syscall, seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae, setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns, setnz, seto, setp, setpe, setpo, sets, setz, @@ -374,7 +374,8 @@ pub const OpEn = enum { i, zi, d, m, fd, td, - m1, mc, mi, mr, rm, rmi, + m1, mc, mi, mr, rm, + rmi, mri, mrc, // zig fmt: on }; diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 59c292c500..9b2fa2e969 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -138,8 +138,12 @@ pub const Inst = struct { sfence, /// Logical shift left shl, + /// Double precision shift left + shld, /// Logical shift right shr, + /// Double precision shift right + shrd, /// Subtract sub, /// Syscall @@ -284,10 +288,10 @@ pub const Inst = struct { ri64, /// Immediate (sign-extended) operand. /// Uses `imm` payload. - imm_s, + i_s, /// Immediate (unsigned) operand. /// Uses `imm` payload. - imm_u, + i_u, /// Relative displacement operand. /// Uses `imm` payload. rel, @@ -316,23 +320,41 @@ pub const Inst = struct { /// Uses `x_cc` with extra data of type `MemoryRip`. m_rip_cc, /// Memory (SIB), immediate (unsigned) operands. - /// Uses `xi` payload with extra data of type `MemorySib`. - mi_u_sib, + /// Uses `ix` payload with extra data of type `MemorySib`. + mi_sib_u, /// Memory (RIP), immediate (unsigned) operands. - /// Uses `xi` payload with extra data of type `MemoryRip`. - mi_u_rip, + /// Uses `ix` payload with extra data of type `MemoryRip`. + mi_rip_u, /// Memory (SIB), immediate (sign-extend) operands. - /// Uses `xi` payload with extra data of type `MemorySib`. - mi_s_sib, + /// Uses `ix` payload with extra data of type `MemorySib`. + mi_sib_s, /// Memory (RIP), immediate (sign-extend) operands. - /// Uses `xi` payload with extra data of type `MemoryRip`. - mi_s_rip, + /// Uses `ix` payload with extra data of type `MemoryRip`. + mi_rip_s, /// Memory (SIB), register operands. /// Uses `rx` payload with extra data of type `MemorySib`. mr_sib, /// Memory (RIP), register operands. /// Uses `rx` payload with extra data of type `MemoryRip`. mr_rip, + /// Memory (SIB), register, register operands. + /// Uses `rrx` payload with extra data of type `MemorySib`. + mrr_sib, + /// Memory (RIP), register, register operands. + /// Uses `rrx` payload with extra data of type `MemoryRip`. + mrr_rip, + /// Memory (SIB), register, immediate (unsigned) operands. + /// Uses `rix` payload with extra data of type `MemorySib`. + mri_sib_u, + /// Memory (RIP), register, immediate (unsigned) operands. + /// Uses `rix` payload with extra data of type `MemoryRip`. + mri_rip_u, + /// Memory (SIB), register, immediate (signed) operands. + /// Uses `rix` payload with extra data of type `MemorySib`. + mri_sib_s, + /// Memory (RIP), register, immediate (signed) operands. + /// Uses `rix` payload with extra data of type `MemoryRip`. + mri_rip_s, /// Rax, Memory moffs. /// Uses `payload` with extra data of type `MemoryMoffs`. rax_moffs, @@ -347,16 +369,16 @@ pub const Inst = struct { lock_m_rip, /// Memory (SIB), immediate (unsigned) operands with lock prefix. /// Uses `xi` payload with extra data of type `MemorySib`. - lock_mi_u_sib, + lock_mi_sib_u, /// Memory (RIP), immediate (unsigned) operands with lock prefix. /// Uses `xi` payload with extra data of type `MemoryRip`. - lock_mi_u_rip, + lock_mi_rip_u, /// Memory (SIB), immediate (sign-extend) operands with lock prefix. /// Uses `xi` payload with extra data of type `MemorySib`. - lock_mi_s_sib, + lock_mi_sib_s, /// Memory (RIP), immediate (sign-extend) operands with lock prefix. /// Uses `xi` payload with extra data of type `MemoryRip`. - lock_mi_s_rip, + lock_mi_rip_s, /// Memory (SIB), register operands with lock prefix. /// Uses `rx` payload with extra data of type `MemorySib`. lock_mr_sib, @@ -400,7 +422,7 @@ pub const Inst = struct { cc: bits.Condition, }, /// A 32-bit immediate value. - imm: u32, + i: u32, r: Register, rr: struct { r1: Register, @@ -414,16 +436,16 @@ pub const Inst = struct { rri: struct { r1: Register, r2: Register, - imm: u32, + i: u32, }, /// Condition code (CC), followed by custom payload found in extra. x_cc: struct { - payload: u32, cc: bits.Condition, + payload: u32, }, /// Register with condition code (CC). r_cc: struct { - r1: Register, + r: Register, cc: bits.Condition, }, /// Register, register with condition code (CC). @@ -434,24 +456,36 @@ pub const Inst = struct { }, /// Register, immediate. ri: struct { - r1: Register, - imm: u32, + r: Register, + i: u32, }, /// Register, followed by custom payload found in extra. rx: struct { - r1: Register, + r: Register, payload: u32, }, /// Register with condition code (CC), followed by custom payload found in extra. rx_cc: struct { - r1: Register, + r: Register, cc: bits.Condition, payload: u32, }, - /// Custom payload followed by an immediate. - xi: struct { + /// Immediate, followed by Custom payload found in extra. + ix: struct { + i: u32, + payload: u32, + }, + /// Register, register, followed by Custom payload found in extra. + rrx: struct { + r1: Register, + r2: Register, + payload: u32, + }, + /// Register, immediate, followed by Custom payload found in extra. + rix: struct { + r: Register, + i: u32, payload: u32, - imm: u32, }, /// String instruction prefix and width. string: struct { diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 9206923ece..05f66062ac 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -174,7 +174,7 @@ pub const Instruction = struct { .td => try encoder.imm64(inst.op1.mem.moffs.offset), else => { const mem_op = switch (encoding.op_en) { - .m, .mi, .m1, .mc, .mr => inst.op1, + .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.op1, .rm, .rmi => inst.op2, else => unreachable, }; @@ -182,7 +182,7 @@ pub const Instruction = struct { .reg => |reg| { const rm = switch (encoding.op_en) { .m, .mi, .m1, .mc => encoding.modRmExt(), - .mr => inst.op2.reg.lowEnc(), + .mr, .mri, .mrc => inst.op2.reg.lowEnc(), .rm, .rmi => inst.op1.reg.lowEnc(), else => unreachable, }; @@ -191,7 +191,7 @@ pub const Instruction = struct { .mem => |mem| { const op = switch (encoding.op_en) { .m, .mi, .m1, .mc => .none, - .mr => inst.op2, + .mr, .mri, .mrc => inst.op2, .rm, .rmi => inst.op1, else => unreachable, }; @@ -202,7 +202,7 @@ pub const Instruction = struct { switch (encoding.op_en) { .mi => try encodeImm(inst.op2.imm, encoding.op2, encoder), - .rmi => try encodeImm(inst.op3.imm, encoding.op3, encoder), + .rmi, .mri => try encodeImm(inst.op3.imm, encoding.op3, encoder), else => {}, } }, @@ -251,7 +251,7 @@ pub const Instruction = struct { else => unreachable, }; } else null, - .m, .mi, .m1, .mc, .mr => if (inst.op1.isSegmentRegister()) blk: { + .m, .mi, .m1, .mc, .mr, .mri, .mrc => if (inst.op1.isSegmentRegister()) blk: { break :blk switch (inst.op1) { .reg => |r| r, .mem => |m| m.base().?, @@ -275,13 +275,11 @@ pub const Instruction = struct { switch (op_en) { .np, .i, .zi, .fd, .td, .d => {}, - .o, .oi => { - rex.b = inst.op1.reg.isExtended(); - }, - .m, .mi, .m1, .mc, .mr, .rm, .rmi => { + .o, .oi => rex.b = inst.op1.reg.isExtended(), + .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc => { const r_op = switch (op_en) { .rm, .rmi => inst.op1, - .mr => inst.op2, + .mr, .mri, .mrc => inst.op2, else => null, }; if (r_op) |op| { @@ -290,7 +288,7 @@ pub const Instruction = struct { const b_x_op = switch (op_en) { .rm, .rmi => inst.op2, - .m, .mi, .m1, .mc, .mr => inst.op1, + .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.op1, else => unreachable, }; switch (b_x_op) { diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 23a125789b..d0ded0136b 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -693,6 +693,13 @@ pub const table = &[_]Entry{ .{ .shl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, .{ .shl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long }, + .{ .shld, .mri, .rm16, .r16, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .none }, + .{ .shld, .mrc, .rm16, .r16, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .none }, + .{ .shld, .mri, .rm32, .r32, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .none }, + .{ .shld, .mri, .rm64, .r64, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .long }, + .{ .shld, .mrc, .rm32, .r32, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .none }, + .{ .shld, .mrc, .rm64, .r64, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .long }, + .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .none }, .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .rex }, .{ .shr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 5, .none }, @@ -709,6 +716,13 @@ pub const table = &[_]Entry{ .{ .shr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 5, .none }, .{ .shr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 5, .long }, + .{ .shrd, .mri, .rm16, .r16, .imm8, .none, &.{ 0x0f, 0xac }, 0, .none }, + .{ .shrd, .mrc, .rm16, .r16, .cl, .none, &.{ 0x0f, 0xad }, 0, .none }, + .{ .shrd, .mri, .rm32, .r32, .imm8, .none, &.{ 0x0f, 0xac }, 0, .none }, + .{ .shrd, .mri, .rm64, .r64, .imm8, .none, &.{ 0x0f, 0xac }, 0, .long }, + .{ .shrd, .mrc, .rm32, .r32, .cl, .none, &.{ 0x0f, 0xad }, 0, .none }, + .{ .shrd, .mrc, .rm64, .r64, .cl, .none, &.{ 0x0f, 0xad }, 0, .long }, + .{ .stos, .np, .m8, .none, .none, .none, &.{ 0xaa }, 0, .none }, .{ .stos, .np, .m16, .none, .none, .none, &.{ 0xab }, 0, .none }, .{ .stos, .np, .m32, .none, .none, .none, &.{ 0xab }, 0, .none }, From a2f6e068b0082692f2c5475c1e31290b9c016010 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 11:00:26 -0400 Subject: [PATCH 107/216] x86_64: implement 128-bit intcast --- src/arch/x86_64/CodeGen.zig | 125 +++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 39 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f010a00551..3c64f15ef1 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1410,38 +1410,80 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - if (self.liveness.isUnused(inst)) - return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); - - const operand_ty = self.air.typeOf(ty_op.operand); - const operand = try self.resolveInst(ty_op.operand); - const info_a = operand_ty.intInfo(self.target.*); - const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*); - - const operand_abi_size = operand_ty.abiSize(self.target.*); - const dest_ty = self.air.typeOfIndex(inst); - const dest_abi_size = dest_ty.abiSize(self.target.*); - const dst_mcv: MCValue = blk: { - if (info_a.bits == info_b.bits) { - break :blk operand; - } - if (operand_abi_size > 8 or dest_abi_size > 8) { - return self.fail("TODO implement intCast for abi sizes larger than 8", .{}); - } - - const operand_lock: ?RegisterLock = switch (operand) { + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const src_ty = self.air.typeOf(ty_op.operand); + const src_int_info = src_ty.intInfo(self.target.*); + const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); + const src_mcv = try self.resolveInst(ty_op.operand); + const src_lock = switch (src_mcv) { .register => |reg| self.register_manager.lockRegAssumeUnused(reg), else => null, }; - defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); + defer if (src_lock) |lock| self.register_manager.unlockReg(lock); - const reg = try self.register_manager.allocReg(inst, gp); - try self.genSetReg(dest_ty, reg, .{ .immediate = 0 }); - try self.genSetReg(operand_ty, reg, operand); - break :blk MCValue{ .register = reg }; + const dst_ty = self.air.typeOfIndex(inst); + const dst_int_info = dst_ty.intInfo(self.target.*); + const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); + const dst_mcv = if (dst_abi_size <= src_abi_size and + self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try self.allocRegOrMem(inst, true); + + const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty; + const signedness: std.builtin.Signedness = if (dst_int_info.signedness == .signed and + src_int_info.signedness == .signed) .signed else .unsigned; + switch (dst_mcv) { + .register => |dst_reg| { + const min_abi_size = @min(dst_abi_size, src_abi_size); + const tag: Mir.Inst.Tag = switch (signedness) { + .signed => .movsx, + .unsigned => if (min_abi_size == 4) .mov else .movzx, + }; + const dst_alias = switch (tag) { + .movsx => dst_reg.to64(), + .mov, .movzx => if (min_abi_size > 4) dst_reg.to64() else dst_reg.to32(), + else => unreachable, + }; + switch (src_mcv) { + .register => |src_reg| { + try self.asmRegisterRegister( + tag, + dst_alias, + registerAlias(src_reg, min_abi_size), + ); + }, + .stack_offset => |src_off| { + try self.asmRegisterMemory(tag, dst_alias, Memory.sib( + Memory.PtrSize.fromSize(min_abi_size), + .{ .base = .rbp, .disp = -src_off }, + )); + }, + else => return self.fail("TODO airIntCast from {s} to {s}", .{ + @tagName(src_mcv), + @tagName(dst_mcv), + }), + } + if (self.regExtraBits(min_ty) > 0) try self.truncateRegister(min_ty, dst_reg); + }, + else => { + try self.setRegOrMem(min_ty, dst_mcv, src_mcv); + const extra = dst_abi_size * 8 - dst_int_info.bits; + if (extra > 0) { + try self.genShiftBinOpMir(switch (signedness) { + .signed => .sal, + .unsigned => .shl, + }, dst_ty, dst_mcv, .{ .immediate = extra }); + try self.genShiftBinOpMir(switch (signedness) { + .signed => .sar, + .unsigned => .shr, + }, dst_ty, dst_mcv, .{ .immediate = extra }); + } + }, + } + break :result dst_mcv; }; - - return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { @@ -6555,20 +6597,25 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl .disp = -stack_offset, }), immediate); }, - 8 => { + 3, 5...7 => unreachable, + else => { // 64 bit write to memory would take two mov's anyways so we // insted just use two 32 bit writes to avoid register allocation - try self.asmMemoryImmediate(.mov, Memory.sib(.dword, .{ - .base = base_reg, - .disp = -stack_offset + 4, - }), Immediate.u(@truncate(u32, x_big >> 32))); - try self.asmMemoryImmediate(.mov, Memory.sib(.dword, .{ - .base = base_reg, - .disp = -stack_offset, - }), Immediate.u(@truncate(u32, x_big))); - }, - else => { - return self.fail("TODO implement set abi_size=large stack variable with immediate", .{}); + var offset: i32 = 0; + while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate( + .mov, + Memory.sib(.dword, .{ .base = base_reg, .disp = offset - stack_offset }), + if (ty.isSignedInt()) + Immediate.s(@truncate( + i32, + @bitCast(i64, x_big) >> (math.cast(u6, offset * 8) orelse 63), + )) + else + Immediate.u(@truncate( + u32, + if (math.cast(u6, offset * 8)) |shift| x_big >> shift else 0, + )), + ); }, } }, From 6d9bdc8733419ebfc9527d114b637c57d3fd8a42 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 11:00:42 -0400 Subject: [PATCH 108/216] x86_64: fix cmpxchg --- src/arch/x86_64/CodeGen.zig | 2 +- src/arch/x86_64/encodings.zig | 4 ++-- test/behavior/atomics.zig | 4 ---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 3c64f15ef1..c7326ef3b0 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -7242,7 +7242,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { try self.spillEflagsIfOccupied(); _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{ - .r = new_reg, + .r = registerAlias(new_reg, val_abi_size), .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), } } }); diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index d0ded0136b..9683ef991a 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -257,8 +257,8 @@ pub const table = &[_]Entry{ .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .none }, .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .rex }, - .{ .cmpxchg, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb1 }, 0, .rex }, - .{ .cmpxchg, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb1 }, 0, .rex }, + .{ .cmpxchg, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb1 }, 0, .none }, + .{ .cmpxchg, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb1 }, 0, .none }, .{ .cmpxchg, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb1 }, 0, .long }, .{ .cmpxchg8b , .m, .m64, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .none }, diff --git a/test/behavior/atomics.zig b/test/behavior/atomics.zig index a1e3af6e9a..e6000cd848 100644 --- a/test/behavior/atomics.zig +++ b/test/behavior/atomics.zig @@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual; test "cmpxchg" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -96,7 +95,6 @@ test "cmpxchg with ptr" { test "cmpxchg with ignored result" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -143,7 +141,6 @@ var a_global_variable = @as(u32, 1234); test "cmpxchg on a global variable" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -384,7 +381,6 @@ fn testAtomicRmwInt128(comptime signedness: std.builtin.Signedness) !void { test "atomics with different types" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO From 1e080e505617b8a7961971630c059592f7366223 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 13:44:50 -0400 Subject: [PATCH 109/216] x86_64: implement atomic loops --- src/arch/x86_64/CodeGen.zig | 295 ++++++++++++++---- src/arch/x86_64/bits.zig | 23 +- test/behavior/array.zig | 2 - test/behavior/bugs/10684.zig | 1 - test/behavior/bugs/12051.zig | 1 - test/behavior/bugs/12092.zig | 1 - test/behavior/bugs/12142.zig | 1 - test/behavior/bugs/6456.zig | 1 - test/behavior/bugs/8646.zig | 1 - test/behavior/empty_tuple_fields.zig | 2 - test/behavior/lower_strlit_to_vector.zig | 1 - test/behavior/math.zig | 1 - test/behavior/optional.zig | 1 - test/behavior/packed-struct.zig | 2 - .../packed_struct_explicit_backing_int.zig | 1 - test/behavior/pointers.zig | 2 - test/behavior/slice.zig | 3 - test/behavior/struct.zig | 1 - test/behavior/switch.zig | 1 - test/behavior/threadlocal.zig | 1 - test/behavior/translate_c_macros.zig | 8 - test/behavior/tuple.zig | 1 - test/behavior/tuple_declarations.zig | 2 - test/behavior/type.zig | 2 - test/behavior/type_info.zig | 1 - test/behavior/typename.zig | 2 - test/behavior/vector.zig | 1 - 27 files changed, 249 insertions(+), 110 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index c7326ef3b0..f6ccedb91d 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1438,7 +1438,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { const min_abi_size = @min(dst_abi_size, src_abi_size); const tag: Mir.Inst.Tag = switch (signedness) { .signed => .movsx, - .unsigned => if (min_abi_size == 4) .mov else .movzx, + .unsigned => if (min_abi_size > 2) .mov else .movzx, }; const dst_alias = switch (tag) { .movsx => dst_reg.to64(), @@ -3889,10 +3889,10 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: const src_ty = self.air.typeOf(src_air); const src_mcv = try self.resolveInst(src_air); if (src_ty.zigTypeTag() == .Vector) { - return self.fail("TODO implement genBinOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)}); + return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)}); } if (src_ty.abiSize(self.target.*) > 8) { - return self.fail("TODO implement genBinOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)}); + return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)}); } switch (src_mcv) { @@ -4192,7 +4192,7 @@ fn genShiftBinOp( return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()}); } - self.register_manager.getRegAssumeFree(.rcx, null); + try self.register_manager.getReg(.rcx, null); const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx); defer self.register_manager.unlockReg(rcx_lock); @@ -4717,7 +4717,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu ); } }, - else => return self.fail("TODO getBinOpMir implement large immediate ABI", .{}), + else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}), } }, .memory, @@ -4798,28 +4798,28 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu ); } }, - else => return self.fail("TODO getBinOpMir implement large immediate ABI", .{}), + else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}), } }, .memory, .stack_offset, .ptr_stack_offset, => { - return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); + return self.fail("TODO implement x86 genBinOpMir source memory", .{}); }, .linker_load => { - return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{}); + return self.fail("TODO implement x86 genBinOpMir source symbol at index in linker", .{}); }, .eflags => { - return self.fail("TODO implement x86 ADD/SUB/CMP source eflags", .{}); + return self.fail("TODO implement x86 genBinOpMir source eflags", .{}); }, } }, .memory => { - return self.fail("TODO implement x86 ADD/SUB/CMP destination memory", .{}); + return self.fail("TODO implement x86 genBinOpMir destination memory", .{}); }, .linker_load => { - return self.fail("TODO implement x86 ADD/SUB/CMP destination symbol at index", .{}); + return self.fail("TODO implement x86 genBinOpMir destination symbol at index", .{}); }, } } @@ -7219,20 +7219,37 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { const ptr_ty = self.air.typeOf(extra.ptr); const ptr_mcv = try self.resolveInst(extra.ptr); const val_ty = self.air.typeOf(extra.expected_value); + const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); + + try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx }); + const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx }); + for (regs_lock) |lock| self.register_manager.unlockReg(lock); const exp_mcv = try self.resolveInst(extra.expected_value); - try self.genSetReg(val_ty, .rax, exp_mcv); + if (val_abi_size > 8) switch (exp_mcv) { + .stack_offset => |exp_off| { + try self.genSetReg(Type.usize, .rax, .{ .stack_offset = exp_off - 0 }); + try self.genSetReg(Type.usize, .rdx, .{ .stack_offset = exp_off - 8 }); + }, + else => return self.fail("TODO implement cmpxchg for {s}", .{@tagName(exp_mcv)}), + } else try self.genSetReg(val_ty, .rax, exp_mcv); const rax_lock = self.register_manager.lockRegAssumeUnused(.rax); defer self.register_manager.unlockReg(rax_lock); const new_mcv = try self.resolveInst(extra.new_value); - const new_reg = try self.copyToTmpRegister(val_ty, new_mcv); + const new_reg: Register = if (val_abi_size > 8) switch (new_mcv) { + .stack_offset => |new_off| new: { + try self.genSetReg(Type.usize, .rbx, .{ .stack_offset = new_off - 0 }); + try self.genSetReg(Type.usize, .rcx, .{ .stack_offset = new_off - 8 }); + break :new undefined; + }, + else => return self.fail("TODO implement cmpxchg for {s}", .{@tagName(exp_mcv)}), + } else try self.copyToTmpRegister(val_ty, new_mcv); const new_lock = self.register_manager.lockRegAssumeUnused(new_reg); defer self.register_manager.unlockReg(new_lock); - const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); const ptr_size = Memory.PtrSize.fromSize(val_abi_size); - const ptr_mem: Memory = switch (ptr_mcv) { + const ptr_mem = switch (ptr_mcv) { .register => |reg| Memory.sib(ptr_size, .{ .base = reg }), .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }), else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }), @@ -7241,16 +7258,30 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); try self.spillEflagsIfOccupied(); - _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{ - .r = registerAlias(new_reg, val_abi_size), - .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), - } } }); + if (val_abi_size <= 8) { + _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{ + .r = registerAlias(new_reg, val_abi_size), + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } } }); + } else { + _ = try self.addInst(.{ .tag = .cmpxchgb, .ops = .lock_m_sib, .data = .{ + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } }); + } const result: MCValue = result: { if (self.liveness.isUnused(inst)) break :result .dead; - self.eflags_inst = inst; - break :result .{ .register_overflow = .{ .reg = .rax, .eflags = .ne } }; + if (val_abi_size <= 8) { + self.eflags_inst = inst; + break :result .{ .register_overflow = .{ .reg = .rax, .eflags = .ne } }; + } + + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.genSetStack(Type.bool, dst_mcv.stack_offset - 16, .{ .eflags = .ne }, .{}); + try self.genSetStack(Type.usize, dst_mcv.stack_offset - 8, .{ .register = .rdx }, .{}); + try self.genSetStack(Type.usize, dst_mcv.stack_offset - 0, .{ .register = .rax }, .{}); + break :result dst_mcv; }; return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); } @@ -7263,9 +7294,10 @@ fn atomicOp( ptr_ty: Type, val_ty: Type, unused: bool, - op: ?std.builtin.AtomicRmwOp, + rmw_op: ?std.builtin.AtomicRmwOp, order: std.builtin.AtomicOrder, ) InnerError!void { + const dst_mcv = MCValue{ .register = dst_reg }; const dst_lock = self.register_manager.lockReg(dst_reg); defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); @@ -7283,7 +7315,7 @@ fn atomicOp( const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*)); const ptr_size = Memory.PtrSize.fromSize(val_abi_size); - const ptr_mem: Memory = switch (ptr_mcv) { + const ptr_mem = switch (ptr_mcv) { .register => |reg| Memory.sib(ptr_size, .{ .base = reg }), .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }), else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }), @@ -7291,48 +7323,197 @@ fn atomicOp( const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null; defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); - try self.genSetReg(val_ty, dst_reg, val_mcv); + const method: enum { lock, loop, libcall } = if (val_ty.isRuntimeFloat()) + .loop + else switch (rmw_op orelse .Xchg) { + .Xchg, + .Add, + .Sub, + => if (val_abi_size <= 8) .lock else if (val_abi_size <= 16) .loop else .libcall, + .And, + .Or, + .Xor, + => if (val_abi_size <= 8 and unused) .lock else if (val_abi_size <= 16) .loop else .libcall, + .Nand, + .Max, + .Min, + => if (val_abi_size <= 16) .loop else .libcall, + }; + switch (method) { + .lock => { + const tag: Mir.Inst.Tag = if (rmw_op) |op| switch (op) { + .Xchg => if (unused) .mov else .xchg, + .Add => if (unused) .add else .xadd, + .Sub => if (unused) .sub else .xadd, + .And => .@"and", + .Or => .@"or", + .Xor => .xor, + else => unreachable, + } else switch (order) { + .Unordered, .Monotonic, .Release, .AcqRel => .mov, + .Acquire => unreachable, + .SeqCst => .xchg, + }; - const need_loop = val_ty.isRuntimeFloat() or if (op) |rmw| switch (rmw) { - .Xchg, .Add, .Sub => false, - .And, .Or, .Xor => !unused, - .Nand, .Max, .Min => true, - } else false; - if (!need_loop) { - const tag: Mir.Inst.Tag = if (op) |rmw| switch (rmw) { - .Xchg => if (unused) .mov else .xchg, - .Add => if (unused) .add else .xadd, - .Sub => if (unused) .sub else .xadd, - .And => .@"and", - .Or => .@"or", - .Xor => .xor, - else => unreachable, - } else switch (order) { - .Unordered, .Monotonic, .Release, .AcqRel => .mov, - .Acquire => unreachable, - .SeqCst => .xchg, - }; - if (op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) { - try self.genUnOpMir(.neg, val_ty, .{ .register = dst_reg }); - } - _ = try self.addInst(.{ .tag = tag, .ops = switch (tag) { - .mov, .xchg => .mr_sib, - .xadd, .add, .sub, .@"and", .@"or", .xor => .lock_mr_sib, - else => unreachable, - }, .data = .{ .rx = .{ - .r = registerAlias(dst_reg, val_abi_size), - .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), - } } }); - return; + try self.genSetReg(val_ty, dst_reg, val_mcv); + if (rmw_op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) { + try self.genUnOpMir(.neg, val_ty, .{ .register = dst_reg }); + } + _ = try self.addInst(.{ .tag = tag, .ops = switch (tag) { + .mov, .xchg => .mr_sib, + .xadd, .add, .sub, .@"and", .@"or", .xor => .lock_mr_sib, + else => unreachable, + }, .data = .{ .rx = .{ + .r = registerAlias(dst_reg, val_abi_size), + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } } }); + }, + .loop => _ = try self.asmJccReloc(if (val_abi_size <= 8) loop: { + try self.genSetReg(val_ty, dst_reg, val_mcv); + try self.asmRegisterMemory(.mov, registerAlias(.rax, val_abi_size), ptr_mem); + const loop = @intCast(u32, self.mir_instructions.len); + if (rmw_op != std.builtin.AtomicRmwOp.Xchg) { + try self.genSetReg(val_ty, dst_reg, .{ .register = .rax }); + } + if (rmw_op) |op| switch (op) { + .Xchg => try self.genSetReg(val_ty, dst_reg, val_mcv), + .Add => try self.genBinOpMir(.add, val_ty, dst_mcv, val_mcv), + .Sub => try self.genBinOpMir(.sub, val_ty, dst_mcv, val_mcv), + .And => try self.genBinOpMir(.@"and", val_ty, dst_mcv, val_mcv), + .Nand => { + try self.genBinOpMir(.@"and", val_ty, dst_mcv, val_mcv); + try self.genUnOpMir(.not, val_ty, dst_mcv); + }, + .Or => try self.genBinOpMir(.@"or", val_ty, dst_mcv, val_mcv), + .Xor => try self.genBinOpMir(.xor, val_ty, dst_mcv, val_mcv), + .Min, .Max => { + const cc: Condition = switch (if (val_ty.isAbiInt()) + val_ty.intInfo(self.target.*).signedness + else + .unsigned) { + .unsigned => switch (op) { + .Min => .a, + .Max => .b, + else => unreachable, + }, + .signed => switch (op) { + .Min => .g, + .Max => .l, + else => unreachable, + }, + }; + + try self.genBinOpMir(.cmp, val_ty, dst_mcv, val_mcv); + switch (val_mcv) { + .register => |val_reg| try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, val_abi_size), + registerAlias(val_reg, val_abi_size), + cc, + ), + .stack_offset => |val_off| try self.asmCmovccRegisterMemory( + registerAlias(dst_reg, val_abi_size), + Memory.sib( + Memory.PtrSize.fromSize(val_abi_size), + .{ .base = .rbp, .disp = -val_off }, + ), + cc, + ), + else => { + const val_reg = try self.copyToTmpRegister(val_ty, val_mcv); + try self.asmCmovccRegisterRegister( + registerAlias(dst_reg, val_abi_size), + registerAlias(val_reg, val_abi_size), + cc, + ); + }, + } + }, + }; + _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{ + .r = registerAlias(dst_reg, val_abi_size), + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } } }); + break :loop loop; + } else loop: { + try self.asmRegisterMemory(.mov, .rax, Memory.sib(.qword, .{ + .base = ptr_mem.sib.base, + .scale_index = ptr_mem.sib.scale_index, + .disp = ptr_mem.sib.disp + 0, + })); + try self.asmRegisterMemory(.mov, .rdx, Memory.sib(.qword, .{ + .base = ptr_mem.sib.base, + .scale_index = ptr_mem.sib.scale_index, + .disp = ptr_mem.sib.disp + 8, + })); + const loop = @intCast(u32, self.mir_instructions.len); + switch (val_mcv) { + .stack_offset => |val_off| { + const val_lo_mem = Memory.sib(.qword, .{ .base = .rbp, .disp = 0 - val_off }); + const val_hi_mem = Memory.sib(.qword, .{ .base = .rbp, .disp = 8 - val_off }); + + if (rmw_op != std.builtin.AtomicRmwOp.Xchg) { + try self.asmRegisterRegister(.mov, .rbx, .rax); + try self.asmRegisterRegister(.mov, .rcx, .rdx); + } + if (rmw_op) |op| switch (op) { + .Xchg => { + try self.asmRegisterMemory(.mov, .rbx, val_lo_mem); + try self.asmRegisterMemory(.mov, .rcx, val_hi_mem); + }, + .Add => { + try self.asmRegisterMemory(.add, .rbx, val_lo_mem); + try self.asmRegisterMemory(.adc, .rcx, val_hi_mem); + }, + .Sub => { + try self.asmRegisterMemory(.sub, .rbx, val_lo_mem); + try self.asmRegisterMemory(.sbb, .rcx, val_hi_mem); + }, + .And => { + try self.asmRegisterMemory(.@"and", .rbx, val_lo_mem); + try self.asmRegisterMemory(.@"and", .rcx, val_hi_mem); + }, + .Nand => { + try self.asmRegisterMemory(.@"and", .rbx, val_lo_mem); + try self.asmRegisterMemory(.@"and", .rcx, val_hi_mem); + try self.asmRegister(.not, .rbx); + try self.asmRegister(.not, .rcx); + }, + .Or => { + try self.asmRegisterMemory(.@"or", .rbx, val_lo_mem); + try self.asmRegisterMemory(.@"or", .rcx, val_hi_mem); + }, + .Xor => { + try self.asmRegisterMemory(.xor, .rbx, val_lo_mem); + try self.asmRegisterMemory(.xor, .rcx, val_hi_mem); + }, + else => return self.fail( + "TODO implement x86 atomic loop for large abi {s}", + .{@tagName(op)}, + ), + }; + }, + else => return self.fail( + "TODO implement x86 atomic loop for large abi {s}", + .{@tagName(val_mcv)}, + ), + } + _ = try self.addInst(.{ .tag = .cmpxchgb, .ops = .lock_m_sib, .data = .{ + .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)), + } }); + break :loop loop; + }, .ne), + .libcall => return self.fail("TODO implement x86 atomic libcall", .{}), } - - return self.fail("TODO implement x86 atomic loop", .{}); } fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void { const pl_op = self.air.instructions.items(.data)[inst].pl_op; const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; + try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx }); + const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx }); + defer for (regs_lock) |lock| self.register_manager.unlockReg(lock); + const unused = self.liveness.isUnused(inst); const dst_reg = try self.register_manager.allocReg(if (unused) null else inst, gp); diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index c10bfe4039..76ad26a9a0 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -411,20 +411,17 @@ pub const Memory = union(enum) { dword, qword, tbyte, + dqword, pub fn fromSize(size: u32) PtrSize { - return if (size <= 1) - .byte - else if (size <= 2) - .word - else if (size <= 4) - .dword - else if (size <= 8) - .qword - else if (size == 10) - .tbyte - else - unreachable; + return switch (size) { + 1...1 => .byte, + 2...2 => .word, + 3...4 => .dword, + 5...8 => .qword, + 9...16 => .dqword, + else => unreachable, + }; } pub fn fromBitSize(bit_size: u64) PtrSize { @@ -434,6 +431,7 @@ pub const Memory = union(enum) { 32 => .dword, 64 => .qword, 80 => .tbyte, + 128 => .dqword, else => unreachable, }; } @@ -445,6 +443,7 @@ pub const Memory = union(enum) { .dword => 32, .qword => 64, .tbyte => 80, + .dqword => 128, }; } }; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 96b1be1778..b2d9816c18 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -70,7 +70,6 @@ test "array concat with undefined" { test "array concat with tuple" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const array: [2]u8 = .{ 1, 2 }; { @@ -641,7 +640,6 @@ test "tuple to array handles sentinel" { } test "array init of container level array variable" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/10684.zig b/test/behavior/bugs/10684.zig index 8b0bd6ebca..ef104a3f0c 100644 --- a/test/behavior/bugs/10684.zig +++ b/test/behavior/bugs/10684.zig @@ -4,7 +4,6 @@ const expectEqualStrings = std.testing.expectEqualStrings; test "slicing slices" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/12051.zig b/test/behavior/bugs/12051.zig index efbfc88404..5e2087d422 100644 --- a/test/behavior/bugs/12051.zig +++ b/test/behavior/bugs/12051.zig @@ -3,7 +3,6 @@ const builtin = @import("builtin"); test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/12092.zig b/test/behavior/bugs/12092.zig index 3a7b9766a3..216138d748 100644 --- a/test/behavior/bugs/12092.zig +++ b/test/behavior/bugs/12092.zig @@ -15,7 +15,6 @@ fn takeFoo(foo: *const Foo) !void { test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/12142.zig b/test/behavior/bugs/12142.zig index db303d617a..1efbd0dbb4 100644 --- a/test/behavior/bugs/12142.zig +++ b/test/behavior/bugs/12142.zig @@ -20,7 +20,6 @@ fn letter(e: Letter) u8 { test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/6456.zig b/test/behavior/bugs/6456.zig index 03c687232f..3dbec7bc70 100644 --- a/test/behavior/bugs/6456.zig +++ b/test/behavior/bugs/6456.zig @@ -11,7 +11,6 @@ const text = ; test "issue 6456" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/8646.zig b/test/behavior/bugs/8646.zig index 2e181a682e..da9359a60a 100644 --- a/test/behavior/bugs/8646.zig +++ b/test/behavior/bugs/8646.zig @@ -8,7 +8,6 @@ const array = [_][]const []const u8{ test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/empty_tuple_fields.zig b/test/behavior/empty_tuple_fields.zig index 7309dc9b3e..9f1d4dee1a 100644 --- a/test/behavior/empty_tuple_fields.zig +++ b/test/behavior/empty_tuple_fields.zig @@ -3,7 +3,6 @@ const builtin = @import("builtin"); test "empty file level struct" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = @import("empty_file_level_struct.zig"); @@ -15,7 +14,6 @@ test "empty file level struct" { test "empty file level union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = @import("empty_file_level_union.zig"); diff --git a/test/behavior/lower_strlit_to_vector.zig b/test/behavior/lower_strlit_to_vector.zig index 427379636e..948d708aa7 100644 --- a/test/behavior/lower_strlit_to_vector.zig +++ b/test/behavior/lower_strlit_to_vector.zig @@ -2,7 +2,6 @@ const std = @import("std"); const builtin = @import("builtin"); test "strlit to vector" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/math.zig b/test/behavior/math.zig index d7b8e4764b..9e3c2b02fd 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -560,7 +560,6 @@ fn testUnsignedNegationWrappingEval(x: u16) !void { test "negation wrapping" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try expectEqual(@as(u1, 1), negateWrap(u1, 1)); } diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 95b39f2170..9fb0a617a3 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -431,7 +431,6 @@ test "alignment of wrapping an optional payload" { test "Optional slice size is optimized" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO try expect(@sizeOf(?[]u8) == @sizeOf([]u8)); diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 6cc021dd1a..a7dfd46064 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -120,7 +120,6 @@ test "consistent size of packed structs" { } test "correct sizeOf and offsets in packed structs" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -188,7 +187,6 @@ test "correct sizeOf and offsets in packed structs" { } test "nested packed structs" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/packed_struct_explicit_backing_int.zig b/test/behavior/packed_struct_explicit_backing_int.zig index b5d6ed24fb..fab43816da 100644 --- a/test/behavior/packed_struct_explicit_backing_int.zig +++ b/test/behavior/packed_struct_explicit_backing_int.zig @@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian(); test "packed struct explicit backing integer" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index e5ccfec543..0532212559 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -412,7 +412,6 @@ test "@ptrToInt on null optional at comptime" { test "indexing array with sentinel returns correct type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var s: [:0]const u8 = "abc"; @@ -497,7 +496,6 @@ test "pointer to constant decl preserves alignment" { test "ptrCast comptime known slice to C pointer" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const s: [:0]const u8 = "foo"; diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 2a0944a5b6..029f6838d0 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -688,7 +688,6 @@ test "slice field ptr var" { test "global slice field access" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { @@ -733,7 +732,6 @@ test "empty slice ptr is non null" { test "slice decays to many pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var buf: [8]u8 = "abcdefg\x00".*; const p: [*:0]const u8 = buf[0..7 :0]; @@ -744,7 +742,6 @@ test "write through pointer to optional slice arg" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const S = struct { fn bar(foo: *?[]const u8) !void { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 61318ad6d2..b59615f01a 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -935,7 +935,6 @@ test "comptime struct field" { } test "tuple element initialized with fn call" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 132cef5c1e..52f5b79723 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -620,7 +620,6 @@ test "switch on error set with single else" { } test "switch capture copies its payload" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/threadlocal.zig b/test/behavior/threadlocal.zig index 1f1bc6bea4..f025e99ee7 100644 --- a/test/behavior/threadlocal.zig +++ b/test/behavior/threadlocal.zig @@ -21,7 +21,6 @@ test "thread local variable" { test "pointer to thread local array" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) { diff --git a/test/behavior/translate_c_macros.zig b/test/behavior/translate_c_macros.zig index 6d8d4eca6d..bc19cddc22 100644 --- a/test/behavior/translate_c_macros.zig +++ b/test/behavior/translate_c_macros.zig @@ -23,7 +23,6 @@ test "casting to void with a macro" { } test "initializer list expression" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -52,7 +51,6 @@ test "reference to a struct type" { test "cast negative integer to pointer" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -98,7 +96,6 @@ test "casting or calling a value with a paren-surrounded macro" { test "nested comma operator" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -109,7 +106,6 @@ test "nested comma operator" { test "cast functions" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -123,7 +119,6 @@ test "cast functions" { test "large integer macro" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -133,7 +128,6 @@ test "large integer macro" { test "string literal macro with embedded tab character" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -143,7 +137,6 @@ test "string literal macro with embedded tab character" { test "string and char literals that are not UTF-8 encoded. Issue #12784" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -188,7 +181,6 @@ test "Macro that uses division operator. Issue #13162" { test "Macro that uses remainder operator. Issue #13346" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index 3f557bc40e..1cf68a0769 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -381,7 +381,6 @@ test "tuple of struct concatenation and coercion to array" { test "nested runtime conditionals in tuple initializer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var data: u8 = 0; const x = .{ diff --git a/test/behavior/tuple_declarations.zig b/test/behavior/tuple_declarations.zig index 87d4997c8b..74ee7da1dd 100644 --- a/test/behavior/tuple_declarations.zig +++ b/test/behavior/tuple_declarations.zig @@ -7,7 +7,6 @@ const expectEqualStrings = testing.expectEqualStrings; test "tuple declaration type info" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; { const T = struct { comptime u32 align(2) = 1, []const u8 }; @@ -57,7 +56,6 @@ test "tuple declaration type info" { test "Tuple declaration usage" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const T = struct { u32, []const u8 }; var t: T = .{ 1, "foo" }; diff --git a/test/behavior/type.zig b/test/behavior/type.zig index 7f44f350d1..a12949fffd 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -200,7 +200,6 @@ test "Type.ErrorUnion" { test "Type.Opaque" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -348,7 +347,6 @@ test "Type.Struct" { } test "Type.Enum" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 495c1f3195..5a1ab7c2aa 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -568,7 +568,6 @@ test "value from struct @typeInfo default_value can be loaded at comptime" { test "@typeInfo decls and usingnamespace" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const A = struct { const x = 5; diff --git a/test/behavior/typename.zig b/test/behavior/typename.zig index 92dc428903..e8327a1981 100644 --- a/test/behavior/typename.zig +++ b/test/behavior/typename.zig @@ -64,7 +64,6 @@ test "anon field init" { } test "basic" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -228,7 +227,6 @@ test "local variable" { } test "comptime parameters not converted to anytype in function type" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig index 562e9aba20..3b716692ef 100644 --- a/test/behavior/vector.zig +++ b/test/behavior/vector.zig @@ -1267,7 +1267,6 @@ test "store to vector in slice" { test "addition of vectors represented as strings" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const V = @Vector(3, u8); const foo: V = "foo".*; From d29c674d0dfab215e230a3d31eddf7ca164491a0 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 16:04:30 -0400 Subject: [PATCH 110/216] x86_64: implement teb inline assembly for windows --- src/arch/x86_64/CodeGen.zig | 140 +++++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 48 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f6ccedb91d..a2c5b291bf 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -6265,13 +6265,23 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]); extra_i += inputs.len; - const dead = !is_volatile and self.liveness.isUnused(inst); - const result: MCValue = if (dead) .dead else result: { + var result: MCValue = .none; + if (!is_volatile and self.liveness.isUnused(inst)) result = .dead else { + var args = std.StringArrayHashMap(MCValue).init(self.gpa); + try args.ensureTotalCapacity(outputs.len + inputs.len + clobbers_len); + defer { + for (args.values()) |arg| switch (arg) { + .register => |reg| self.register_manager.unlockReg(.{ .register = reg }), + else => {}, + }; + args.deinit(); + } + if (outputs.len > 1) { return self.fail("TODO implement codegen for asm with more than 1 output", .{}); } - const output_constraint: ?[]const u8 = for (outputs) |output| { + for (outputs) |output| { if (output != .none) { return self.fail("TODO implement codegen for non-expr asm", .{}); } @@ -6282,8 +6292,21 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { // for the string, we still use the next u32 for the null terminator. extra_i += (constraint.len + name.len + (2 + 3)) / 4; - break constraint; - } else null; + const mcv: MCValue = if (mem.eql(u8, constraint, "=r")) + .{ .register = self.register_manager.tryAllocReg(inst, gp) orelse + return self.fail("ran out of registers lowering inline asm", .{}) } + else if (mem.startsWith(u8, constraint, "={") and mem.endsWith(u8, constraint, "}")) + .{ .register = parseRegName(constraint["={".len .. constraint.len - "}".len]) orelse + return self.fail("unrecognized register constraint: '{s}'", .{constraint}) } + else + return self.fail("unrecognized constraint: '{s}'", .{constraint}); + args.putAssumeCapacity(name, mcv); + switch (mcv) { + .register => |reg| _ = self.register_manager.lockRegAssumeUnused(reg), + else => {}, + } + if (output == .none) result = mcv; + } for (inputs) |input| { const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); @@ -6317,52 +6340,73 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } } - const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; - - { - var iter = std.mem.tokenize(u8, asm_source, "\n\r"); - while (iter.next()) |ins| { - if (mem.eql(u8, ins, "syscall")) { - try self.asmOpOnly(.syscall); - } else if (mem.indexOf(u8, ins, "push")) |_| { - const arg = ins[4..]; - if (mem.indexOf(u8, arg, "$")) |l| { - const n = std.fmt.parseInt(u8, ins[4 + l + 1 ..], 10) catch { - return self.fail("TODO implement more inline asm int parsing", .{}); - }; - try self.asmImmediate(.push, Immediate.u(n)); - } else if (mem.indexOf(u8, arg, "%%")) |l| { - const reg_name = ins[4 + l + 2 ..]; - const reg = parseRegName(reg_name) orelse - return self.fail("unrecognized register: '{s}'", .{reg_name}); - try self.asmRegister(.push, reg); - } else return self.fail("TODO more push operands", .{}); - } else if (mem.indexOf(u8, ins, "pop")) |_| { - const arg = ins[3..]; - if (mem.indexOf(u8, arg, "%%")) |l| { - const reg_name = ins[3 + l + 2 ..]; - const reg = parseRegName(reg_name) orelse - return self.fail("unrecognized register: '{s}'", .{reg_name}); - try self.asmRegister(.pop, reg); - } else return self.fail("TODO more pop operands", .{}); - } else { - return self.fail("TODO implement support for more x86 assembly instructions", .{}); + const asm_source = mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; + var line_it = mem.tokenize(u8, asm_source, "\n\r"); + while (line_it.next()) |line| { + var mnem_it = mem.tokenize(u8, line, " \t"); + const mnem = mnem_it.next() orelse continue; + if (mem.startsWith(u8, mnem, "#")) continue; + var arg_it = mem.tokenize(u8, mnem_it.rest(), ", "); + if (std.ascii.eqlIgnoreCase(mnem, "syscall")) { + if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) + return self.fail("Too many operands: '{s}'", .{line}); + try self.asmOpOnly(.syscall); + } else if (std.ascii.eqlIgnoreCase(mnem, "push")) { + const src = arg_it.next() orelse + return self.fail("Not enough operands: '{s}'", .{line}); + if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) + return self.fail("Too many operands: '{s}'", .{line}); + if (mem.startsWith(u8, src, "$")) { + const imm = std.fmt.parseInt(u32, src["$".len..], 0) catch + return self.fail("Invalid immediate: '{s}'", .{src}); + try self.asmImmediate(.push, Immediate.u(imm)); + } else if (mem.startsWith(u8, src, "%%")) { + const reg = parseRegName(src["%%".len..]) orelse + return self.fail("Invalid register: '{s}'", .{src}); + try self.asmRegister(.push, reg); + } else return self.fail("Unsupported operand: '{s}'", .{src}); + } else if (std.ascii.eqlIgnoreCase(mnem, "pop")) { + const dst = arg_it.next() orelse + return self.fail("Not enough operands: '{s}'", .{line}); + if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) + return self.fail("Too many operands: '{s}'", .{line}); + if (mem.startsWith(u8, dst, "%%")) { + const reg = parseRegName(dst["%%".len..]) orelse + return self.fail("Invalid register: '{s}'", .{dst}); + try self.asmRegister(.pop, reg); + } else return self.fail("Unsupported operand: '{s}'", .{dst}); + } else if (std.ascii.eqlIgnoreCase(mnem, "movq")) { + const src = arg_it.next() orelse + return self.fail("Not enough operands: '{s}'", .{line}); + const dst = arg_it.next() orelse + return self.fail("Not enough operands: '{s}'", .{line}); + if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) + return self.fail("Too many operands: '{s}'", .{line}); + if (mem.startsWith(u8, src, "%%")) { + const colon = mem.indexOfScalarPos(u8, src, "%%".len + 2, ':'); + const src_reg = parseRegName(src["%%".len .. colon orelse src.len]) orelse + return self.fail("Invalid register: '{s}'", .{src}); + if (colon) |colon_pos| { + const src_disp = std.fmt.parseInt(i32, src[colon_pos + 1 ..], 0) catch + return self.fail("Invalid immediate: '{s}'", .{src}); + if (mem.startsWith(u8, dst, "%[") and mem.endsWith(u8, dst, "]")) { + switch (args.get(dst["%[".len .. dst.len - "]".len]) orelse + return self.fail("no matching constraint for: '{s}'", .{dst})) { + .register => |dst_reg| try self.asmRegisterMemory( + .mov, + dst_reg, + Memory.sib(.qword, .{ .base = src_reg, .disp = src_disp }), + ), + else => return self.fail("Invalid constraint: '{s}'", .{dst}), + } + } else return self.fail("Unsupported operand: '{s}'", .{dst}); + } else return self.fail("Unsupported operand: '{s}'", .{src}); } + } else { + return self.fail("Unsupported instruction: '{s}'", .{mnem}); } } - - if (output_constraint) |output| { - if (output.len < 4 or output[0] != '=' or output[1] != '{' or output[output.len - 1] != '}') { - return self.fail("unrecognized asm output constraint: '{s}'", .{output}); - } - const reg_name = output[2 .. output.len - 1]; - const reg = parseRegName(reg_name) orelse - return self.fail("unrecognized register: '{s}'", .{reg_name}); - break :result .{ .register = reg }; - } else { - break :result .none; - } - }; + } simple: { var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); From a80be15cd494dbd25874db8ef63c1cbbcdfc732a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 16:21:00 -0400 Subject: [PATCH 111/216] behavior: disable multi threaded for the stage2_x86_64 windows target See #15075 for more details. --- test/tests.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/test/tests.zig b/test/tests.zig index 26e684cd0d..517d789b18 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -112,6 +112,7 @@ const test_targets = blk: { .os_tag = .windows, .abi = .gnu, }, + .single_threaded = true, // https://github.com/ziglang/zig/issues/15075 .backend = .stage2_x86_64, }, From 113f80bcf793b2841635d136e561bcc0bbe89086 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Thu, 2 Mar 2023 22:15:31 -0500 Subject: [PATCH 112/216] coff: change dynamicbase to default to true (to match lld), change it to pass the negation to lld, and add --no-dynamicbase build: expose linker_dynamicbase on CompileStep and map it to emit --no-dynamicbase --- lib/std/Build/CompileStep.zig | 5 +++++ src/link/Coff/lld.zig | 4 ++-- src/main.zig | 8 +++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/std/Build/CompileStep.zig b/lib/std/Build/CompileStep.zig index 2747f56af2..96fd9deb9c 100644 --- a/lib/std/Build/CompileStep.zig +++ b/lib/std/Build/CompileStep.zig @@ -140,6 +140,8 @@ link_function_sections: bool = false, /// exported symbols. link_gc_sections: ?bool = null, +linker_dynamicbase: ?bool = null, + linker_allow_shlib_undefined: ?bool = null, /// Permit read-only relocations in read-only segments. Disallowed by default. @@ -1474,6 +1476,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { if (self.link_gc_sections) |x| { try zig_args.append(if (x) "--gc-sections" else "--no-gc-sections"); } + if (self.linker_dynamicbase) |x| { + if (!x) try zig_args.append("--no-dynamicbase"); + } if (self.linker_allow_shlib_undefined) |x| { try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined"); } diff --git a/src/link/Coff/lld.zig b/src/link/Coff/lld.zig index c308ff5989..358c905b2c 100644 --- a/src/link/Coff/lld.zig +++ b/src/link/Coff/lld.zig @@ -223,8 +223,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod if (self.base.options.nxcompat) { try argv.append("-nxcompat"); } - if (self.base.options.dynamicbase) { - try argv.append("-dynamicbase"); + if (!self.base.options.dynamicbase) { + try argv.append("-dynamicbase:NO"); } try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); diff --git a/src/main.zig b/src/main.zig index 961d649d38..479c7e518c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -778,7 +778,7 @@ fn buildOutputType( var linker_z_max_page_size: ?u64 = null; var linker_tsaware = false; var linker_nxcompat = false; - var linker_dynamicbase = false; + var linker_dynamicbase = true; var linker_optimization: ?u8 = null; var linker_module_definition_file: ?[]const u8 = null; var test_evented_io = false; @@ -1371,6 +1371,8 @@ fn buildOutputType( linker_opt_bisect_limit = std.math.lossyCast(i32, parseIntSuffix(arg, "-fopt-bisect-limit=".len)); } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { link_eh_frame_hdr = true; + } else if (mem.eql(u8, arg, "--no-dynamicbase")) { + linker_dynamicbase = false; } else if (mem.eql(u8, arg, "--emit-relocs")) { link_emit_relocs = true; } else if (mem.eql(u8, arg, "-fallow-shlib-undefined")) { @@ -2105,8 +2107,8 @@ fn buildOutputType( linker_tsaware = true; } else if (mem.eql(u8, arg, "--nxcompat")) { linker_nxcompat = true; - } else if (mem.eql(u8, arg, "--dynamicbase")) { - linker_dynamicbase = true; + } else if (mem.eql(u8, arg, "--no-dynamicbase")) { + linker_dynamicbase = false; } else if (mem.eql(u8, arg, "--high-entropy-va")) { // This option does not do anything. } else if (mem.eql(u8, arg, "--export-all-symbols")) { From c79073c176a909abce3feba96203caef1e6d8360 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Thu, 2 Mar 2023 22:54:35 -0500 Subject: [PATCH 113/216] compilation: fixup linker_dynamicbase default in InitOptions --- src/Compilation.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 858afb6ca3..2c9b4e4063 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -575,7 +575,7 @@ pub const InitOptions = struct { linker_z_max_page_size: ?u64 = null, linker_tsaware: bool = false, linker_nxcompat: bool = false, - linker_dynamicbase: bool = false, + linker_dynamicbase: bool = true, linker_optimization: ?u8 = null, linker_compress_debug_sections: ?link.CompressDebugSections = null, linker_module_definition_file: ?[]const u8 = null, From 1b97881e38e56ae3bdfc4009265840b77fa9e325 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 25 Mar 2023 21:27:47 +0100 Subject: [PATCH 114/216] libc: update macOS libc headers --- .../aarch64-macos.11-none/arm/_limits.h | 4 - .../aarch64-macos.11-none/arm/_mcontext.h | 4 - .../aarch64-macos.11-none/arm/_param.h | 3 - .../aarch64-macos.11-none/arm/_types.h | 4 - .../include/aarch64-macos.11-none/arm/arch.h | 4 - .../aarch64-macos.11-none/arm/endian.h | 3 - .../aarch64-macos.11-none/arm/limits.h | 4 - .../include/aarch64-macos.11-none/arm/param.h | 4 - .../aarch64-macos.11-none/arm/signal.h | 4 - .../include/aarch64-macos.11-none/arm/types.h | 8 +- .../aarch64-macos.11-none/mach/arm/_structs.h | 23 +- .../aarch64-macos.11-none/mach/arm/boolean.h | 4 - .../mach/arm/exception.h | 3 - .../mach/arm/kern_return.h | 4 - .../mach/arm/processor_info.h | 4 - .../aarch64-macos.11-none/mach/arm/rpc.h | 4 - .../mach/arm/thread_state.h | 8 +- .../mach/arm/thread_status.h | 32 +- .../aarch64-macos.11-none/mach/arm/vm_param.h | 4 - .../aarch64-macos.11-none/mach/arm/vm_types.h | 25 +- lib/libc/include/any-macos-any/db.h | 219 + lib/libc/include/any-macos-any/err.h | 93 + lib/libc/include/any-macos-any/fts.h | 190 + lib/libc/include/any-macos-any/iso646.h | 52 + .../any-macos-any/libkern/OSCacheControl.h | 66 + .../include/any-macos-any/libkern/OSDebug.h | 59 + .../include/any-macos-any/libkern/OSKextLib.h | 571 ++ .../include/any-macos-any/libkern/OSReturn.h | 198 + .../libkern/OSThermalNotification.h | 135 + lib/libc/include/any-macos-any/stddef.h | 90 + .../any-macos-any/sys/_types/_offsetof.h | 30 + .../any-macos-any/sys/_types/_ptrdiff_t.h | 33 + lib/libc/include/any-macos-any/vis.h | 138 + .../include/any-macos.11-any/AssertMacros.h | 1441 ++++ .../any-macos.11-any/AvailabilityInternal.h | 10 +- .../any-macos.11-any/AvailabilityMacros.h | 4015 ++++++++++ .../any-macos.11-any/AvailabilityVersions.h | 24 - .../any-macos.11-any/TargetConditionals.h | 12 +- lib/libc/include/any-macos.11-any/assert.h | 111 + .../any-macos.11-any/device/device_types.h | 118 + .../include/any-macos.11-any/dispatch/base.h | 306 + .../include/any-macos.11-any/dispatch/queue.h | 4 +- lib/libc/include/any-macos.11-any/execinfo.h | 63 + .../include/any-macos.11-any/gethostuuid.h | 42 + .../any-macos.11-any/libkern/OSDebug.h | 69 + .../any-macos.11-any/libkern/OSKextLib.h | 572 ++ lib/libc/include/any-macos.11-any/libproc.h | 187 + .../include/any-macos.11-any/mach-o/loader.h | 4 - .../include/any-macos.11-any/mach/clock.h | 245 + .../any-macos.11-any/mach/clock_priv.h | 199 + .../any-macos.11-any/mach/exception_types.h | 206 + .../include/any-macos.11-any/mach/host_priv.h | 1163 +++ .../any-macos.11-any/mach/host_security.h | 221 + .../any-macos.11-any/mach/kern_return.h | 342 + .../include/any-macos.11-any/mach/lock_set.h | 350 + lib/libc/include/any-macos.11-any/mach/mach.h | 245 + .../include/any-macos.11-any/mach/mach_host.h | 1295 ++++ .../include/any-macos.11-any/mach/mach_init.h | 2 + .../include/any-macos.11-any/mach/mach_port.h | 1808 +++++ .../any-macos.11-any/mach/mach_types.h | 5 - .../mach/mach_voucher_types.h | 245 + .../include/any-macos.11-any/mach/machine.h | 409 + .../mach/machine/thread_state.h | 40 + .../include/any-macos.11-any/mach/message.h | 908 +++ lib/libc/include/any-macos.11-any/mach/mig.h | 180 + lib/libc/include/any-macos.11-any/mach/port.h | 445 ++ .../include/any-macos.11-any/mach/processor.h | 360 + .../any-macos.11-any/mach/processor_set.h | 585 ++ .../any-macos.11-any/mach/sync_policy.h | 49 + lib/libc/include/any-macos.11-any/mach/task.h | 154 +- .../include/any-macos.11-any/mach/task_info.h | 10 - .../any-macos.11-any/mach/task_inspect.h | 54 + .../mach/task_special_ports.h | 135 + .../any-macos.11-any/mach/thread_act.h | 1435 ++++ .../any-macos.11-any/mach/thread_policy.h | 266 + .../any-macos.11-any/mach/thread_state.h | 63 + .../include/any-macos.11-any/mach/vm_map.h | 1503 ++++ .../include/any-macos.11-any/mach/vm_prot.h | 153 + .../any-macos.11-any/mach/vm_statistics.h | 552 ++ .../include/any-macos.11-any/mach/vm_types.h | 97 + .../mach_debug/mach_debug_types.h | 95 + .../any-macos.11-any/machine/_mcontext.h | 34 + .../include/any-macos.11-any/machine/_param.h | 34 + .../include/any-macos.11-any/machine/limits.h | 11 + .../include/any-macos.11-any/malloc/malloc.h | 314 + lib/libc/include/any-macos.11-any/net/if.h | 13 +- .../include/any-macos.11-any/net/if_var.h | 120 +- .../include/any-macos.11-any/net/net_kev.h | 98 + .../include/any-macos.11-any/netinet6/in6.h | 681 ++ .../any-macos.11-any/objc/NSObjCRuntime.h | 33 + .../include/any-macos.11-any/objc/message.h | 388 + .../include/any-macos.11-any/objc/objc-api.h | 304 + .../include/any-macos.11-any/objc/runtime.h | 263 + lib/libc/include/any-macos.11-any/os/base.h | 322 + lib/libc/include/any-macos.11-any/pthread.h | 592 ++ lib/libc/include/any-macos.11-any/simd/base.h | 122 + .../include/any-macos.11-any/simd/common.h | 4458 +++++++++++ .../any-macos.11-any/simd/conversion.h | 1966 +++++ lib/libc/include/any-macos.11-any/simd/math.h | 5380 +++++++++++++ .../include/any-macos.11-any/simd/matrix.h | 1786 +++++ .../any-macos.11-any/simd/matrix_types.h | 264 + .../any-macos.11-any/simd/quaternion.h | 1194 +++ .../any-macos.11-any/simd/vector_make.h | 6768 +++++++++++++++++ lib/libc/include/any-macos.11-any/stdio.h | 410 + lib/libc/include/any-macos.11-any/stdlib.h | 373 + .../any-macos.11-any/sys/_symbol_aliasing.h | 30 - .../any-macos.11-any/sys/_types/_uintptr_t.h | 31 + lib/libc/include/any-macos.11-any/sys/attr.h | 7 +- lib/libc/include/any-macos.11-any/sys/cdefs.h | 22 +- lib/libc/include/any-macos.11-any/sys/event.h | 5 +- lib/libc/include/any-macos.11-any/sys/fcntl.h | 13 +- lib/libc/include/any-macos.11-any/sys/ioctl.h | 110 + lib/libc/include/any-macos.11-any/sys/mount.h | 2 +- .../include/any-macos.11-any/sys/proc_info.h | 11 +- .../include/any-macos.11-any/sys/random.h | 40 + .../include/any-macos.11-any/sys/resource.h | 520 ++ .../include/any-macos.11-any/sys/socket.h | 741 ++ .../include/any-macos.11-any/sys/sockio.h | 180 + .../include/any-macos.11-any/sys/sysctl.h | 26 +- .../include/any-macos.11-any/sys/ttycom.h | 173 + lib/libc/include/any-macos.11-any/unistd.h | 787 ++ lib/libc/include/any-macos.11-any/uuid/uuid.h | 79 + .../include/any-macos.11-any/xpc/activity.h | 446 ++ .../any-macos.11-any/xpc/availability.h | 124 + lib/libc/include/any-macos.11-any/xpc/base.h | 213 + .../include/any-macos.11-any/xpc/connection.h | 748 ++ .../AvailabilityMacros.h | 0 .../dispatch/base.h | 0 .../libproc.h | 0 .../mach/clock.h | 0 .../mach/clock_priv.h | 0 .../mach/exception_types.h | 0 .../mach/host_priv.h | 0 .../mach/host_security.h | 0 .../mach/lock_set.h | 0 .../mach/mach.h | 0 .../mach/mach_host.h | 0 .../mach/mach_port.h | 0 .../mach/mach_voucher_types.h | 0 .../mach/machine.h | 0 .../mach/message.h | 0 .../mach/port.h | 0 .../mach/processor.h | 0 .../mach/processor_set.h | 0 .../mach/thread_act.h | 0 .../mach/thread_policy.h | 0 .../mach/vm_map.h | 0 .../mach/vm_prot.h | 0 .../mach/vm_statistics.h | 0 .../mach/vm_types.h | 0 .../mach_debug/mach_debug_types.h | 0 .../malloc/malloc.h | 0 .../netinet6/in6.h | 0 .../objc/NSObjCRuntime.h | 0 .../objc/message.h | 0 .../objc/objc-api.h | 0 .../os/base.h | 0 .../pthread.h | 0 .../simd/base.h | 0 .../simd/math.h | 0 .../stdio.h | 0 .../stdlib.h | 0 .../sys/resource.h | 0 .../sys/socket.h | 0 .../xpc/base.h | 0 .../xpc/connection.h | 0 .../any-macos.13-any/AvailabilityInternal.h | 8 +- .../any-macos.13-any/AvailabilityVersions.h | 4 + lib/libc/include/any-macos.13-any/net/if.h | 2 +- .../any-macos.13-any/sys/_symbol_aliasing.h | 12 + .../any-macos.13-any/sys/constrained_ctypes.h | 106 +- lib/libc/include/any-macos.13-any/vis.h | 143 + .../x86_64-macos.11-none/i386/_limits.h | 4 - .../x86_64-macos.11-none/i386/_mcontext.h | 4 - .../x86_64-macos.11-none/i386/_param.h | 3 - .../x86_64-macos.11-none/i386/_types.h | 4 - .../x86_64-macos.11-none/i386/eflags.h | 4 - .../x86_64-macos.11-none/i386/endian.h | 3 - .../x86_64-macos.11-none/i386/limits.h | 4 - .../include/x86_64-macos.11-none/i386/param.h | 4 - .../x86_64-macos.11-none/i386/signal.h | 4 - .../include/x86_64-macos.11-none/i386/types.h | 8 +- .../x86_64-macos.11-none/mach/i386/_structs.h | 4 - .../x86_64-macos.11-none/mach/i386/boolean.h | 4 - .../mach/i386/exception.h | 4 - .../x86_64-macos.11-none/mach/i386/fp_reg.h | 4 - .../mach/i386/kern_return.h | 4 - .../mach/i386/processor_info.h | 4 - .../x86_64-macos.11-none/mach/i386/rpc.h | 4 - .../mach/i386/thread_state.h | 6 +- .../mach/i386/thread_status.h | 6 +- .../x86_64-macos.11-none/mach/i386/vm_param.h | 10 +- .../x86_64-macos.11-none/mach/i386/vm_types.h | 17 +- 193 files changed, 52831 insertions(+), 613 deletions(-) create mode 100644 lib/libc/include/any-macos-any/db.h create mode 100644 lib/libc/include/any-macos-any/err.h create mode 100644 lib/libc/include/any-macos-any/fts.h create mode 100644 lib/libc/include/any-macos-any/iso646.h create mode 100644 lib/libc/include/any-macos-any/libkern/OSCacheControl.h create mode 100644 lib/libc/include/any-macos-any/libkern/OSDebug.h create mode 100644 lib/libc/include/any-macos-any/libkern/OSKextLib.h create mode 100644 lib/libc/include/any-macos-any/libkern/OSReturn.h create mode 100644 lib/libc/include/any-macos-any/libkern/OSThermalNotification.h create mode 100644 lib/libc/include/any-macos-any/stddef.h create mode 100644 lib/libc/include/any-macos-any/sys/_types/_offsetof.h create mode 100644 lib/libc/include/any-macos-any/sys/_types/_ptrdiff_t.h create mode 100644 lib/libc/include/any-macos-any/vis.h create mode 100644 lib/libc/include/any-macos.11-any/AssertMacros.h create mode 100644 lib/libc/include/any-macos.11-any/AvailabilityMacros.h create mode 100644 lib/libc/include/any-macos.11-any/assert.h create mode 100644 lib/libc/include/any-macos.11-any/device/device_types.h create mode 100644 lib/libc/include/any-macos.11-any/dispatch/base.h create mode 100644 lib/libc/include/any-macos.11-any/execinfo.h create mode 100644 lib/libc/include/any-macos.11-any/gethostuuid.h create mode 100644 lib/libc/include/any-macos.11-any/libkern/OSDebug.h create mode 100644 lib/libc/include/any-macos.11-any/libkern/OSKextLib.h create mode 100644 lib/libc/include/any-macos.11-any/libproc.h create mode 100644 lib/libc/include/any-macos.11-any/mach/clock.h create mode 100644 lib/libc/include/any-macos.11-any/mach/clock_priv.h create mode 100644 lib/libc/include/any-macos.11-any/mach/exception_types.h create mode 100644 lib/libc/include/any-macos.11-any/mach/host_priv.h create mode 100644 lib/libc/include/any-macos.11-any/mach/host_security.h create mode 100644 lib/libc/include/any-macos.11-any/mach/kern_return.h create mode 100644 lib/libc/include/any-macos.11-any/mach/lock_set.h create mode 100644 lib/libc/include/any-macos.11-any/mach/mach.h create mode 100644 lib/libc/include/any-macos.11-any/mach/mach_host.h create mode 100644 lib/libc/include/any-macos.11-any/mach/mach_port.h create mode 100644 lib/libc/include/any-macos.11-any/mach/mach_voucher_types.h create mode 100644 lib/libc/include/any-macos.11-any/mach/machine.h create mode 100644 lib/libc/include/any-macos.11-any/mach/machine/thread_state.h create mode 100644 lib/libc/include/any-macos.11-any/mach/message.h create mode 100644 lib/libc/include/any-macos.11-any/mach/mig.h create mode 100644 lib/libc/include/any-macos.11-any/mach/port.h create mode 100644 lib/libc/include/any-macos.11-any/mach/processor.h create mode 100644 lib/libc/include/any-macos.11-any/mach/processor_set.h create mode 100644 lib/libc/include/any-macos.11-any/mach/sync_policy.h create mode 100644 lib/libc/include/any-macos.11-any/mach/task_inspect.h create mode 100644 lib/libc/include/any-macos.11-any/mach/task_special_ports.h create mode 100644 lib/libc/include/any-macos.11-any/mach/thread_act.h create mode 100644 lib/libc/include/any-macos.11-any/mach/thread_policy.h create mode 100644 lib/libc/include/any-macos.11-any/mach/thread_state.h create mode 100644 lib/libc/include/any-macos.11-any/mach/vm_map.h create mode 100644 lib/libc/include/any-macos.11-any/mach/vm_prot.h create mode 100644 lib/libc/include/any-macos.11-any/mach/vm_statistics.h create mode 100644 lib/libc/include/any-macos.11-any/mach/vm_types.h create mode 100644 lib/libc/include/any-macos.11-any/mach_debug/mach_debug_types.h create mode 100644 lib/libc/include/any-macos.11-any/machine/_mcontext.h create mode 100644 lib/libc/include/any-macos.11-any/machine/_param.h create mode 100644 lib/libc/include/any-macos.11-any/machine/limits.h create mode 100644 lib/libc/include/any-macos.11-any/malloc/malloc.h create mode 100644 lib/libc/include/any-macos.11-any/net/net_kev.h create mode 100644 lib/libc/include/any-macos.11-any/netinet6/in6.h create mode 100644 lib/libc/include/any-macos.11-any/objc/NSObjCRuntime.h create mode 100644 lib/libc/include/any-macos.11-any/objc/message.h create mode 100644 lib/libc/include/any-macos.11-any/objc/objc-api.h create mode 100644 lib/libc/include/any-macos.11-any/os/base.h create mode 100644 lib/libc/include/any-macos.11-any/pthread.h create mode 100644 lib/libc/include/any-macos.11-any/simd/base.h create mode 100644 lib/libc/include/any-macos.11-any/simd/common.h create mode 100644 lib/libc/include/any-macos.11-any/simd/conversion.h create mode 100644 lib/libc/include/any-macos.11-any/simd/math.h create mode 100644 lib/libc/include/any-macos.11-any/simd/matrix.h create mode 100644 lib/libc/include/any-macos.11-any/simd/matrix_types.h create mode 100644 lib/libc/include/any-macos.11-any/simd/quaternion.h create mode 100644 lib/libc/include/any-macos.11-any/simd/vector_make.h create mode 100644 lib/libc/include/any-macos.11-any/stdio.h create mode 100644 lib/libc/include/any-macos.11-any/stdlib.h create mode 100644 lib/libc/include/any-macos.11-any/sys/_types/_uintptr_t.h create mode 100644 lib/libc/include/any-macos.11-any/sys/ioctl.h create mode 100644 lib/libc/include/any-macos.11-any/sys/random.h create mode 100644 lib/libc/include/any-macos.11-any/sys/resource.h create mode 100644 lib/libc/include/any-macos.11-any/sys/socket.h create mode 100644 lib/libc/include/any-macos.11-any/sys/sockio.h create mode 100644 lib/libc/include/any-macos.11-any/sys/ttycom.h create mode 100644 lib/libc/include/any-macos.11-any/unistd.h create mode 100644 lib/libc/include/any-macos.11-any/uuid/uuid.h create mode 100644 lib/libc/include/any-macos.11-any/xpc/activity.h create mode 100644 lib/libc/include/any-macos.11-any/xpc/availability.h create mode 100644 lib/libc/include/any-macos.11-any/xpc/base.h create mode 100644 lib/libc/include/any-macos.11-any/xpc/connection.h rename lib/libc/include/{any-macos-any => any-macos.12-any}/AvailabilityMacros.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/dispatch/base.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/libproc.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/clock.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/clock_priv.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/exception_types.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/host_priv.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/host_security.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/lock_set.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/mach.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/mach_host.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/mach_port.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/mach_voucher_types.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/machine.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/message.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/port.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/processor.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/processor_set.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/thread_act.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/thread_policy.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/vm_map.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/vm_prot.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/vm_statistics.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach/vm_types.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/mach_debug/mach_debug_types.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/malloc/malloc.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/netinet6/in6.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/objc/NSObjCRuntime.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/objc/message.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/objc/objc-api.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/os/base.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/pthread.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/simd/base.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/simd/math.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/stdio.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/stdlib.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/sys/resource.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/sys/socket.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/xpc/base.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/xpc/connection.h (100%) create mode 100644 lib/libc/include/any-macos.13-any/vis.h diff --git a/lib/libc/include/aarch64-macos.11-none/arm/_limits.h b/lib/libc/include/aarch64-macos.11-none/arm/_limits.h index 8cb2759402..dd9eb5c2be 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/_limits.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/_limits.h @@ -4,10 +4,6 @@ #ifndef _ARM__LIMITS_H_ #define _ARM__LIMITS_H_ -#if defined (__arm__) || defined (__arm64__) - #define __DARWIN_CLK_TCK 100 /* ticks per second */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _ARM__LIMITS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/_mcontext.h b/lib/libc/include/aarch64-macos.11-none/arm/_mcontext.h index 26b83ce221..72253cfbac 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/_mcontext.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/_mcontext.h @@ -29,8 +29,6 @@ #ifndef __ARM_MCONTEXT_H_ #define __ARM_MCONTEXT_H_ -#if defined (__arm__) || defined (__arm64__) - #include /* __DARWIN_UNIX03 */ #include #include @@ -90,6 +88,4 @@ typedef _STRUCT_MCONTEXT32 *mcontext_t; #endif #endif /* _MCONTEXT_T */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* __ARM_MCONTEXT_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/_param.h b/lib/libc/include/aarch64-macos.11-none/arm/_param.h index 10b9edf2f3..81c5bf53cf 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/_param.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/_param.h @@ -5,8 +5,6 @@ #ifndef _ARM__PARAM_H_ #define _ARM__PARAM_H_ -#if defined (__arm__) || defined (__arm64__) - #include /* @@ -20,6 +18,5 @@ #define __DARWIN_ALIGNBYTES32 (sizeof(__uint32_t) - 1) #define __DARWIN_ALIGN32(p) ((__darwin_size_t)((__darwin_size_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32) -#endif /* defined (__arm__) || defined (__arm64__) */ #endif /* _ARM__PARAM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/_types.h b/lib/libc/include/aarch64-macos.11-none/arm/_types.h index 403ec44048..d6c4de8fac 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/_types.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/_types.h @@ -4,8 +4,6 @@ #ifndef _BSD_ARM__TYPES_H_ #define _BSD_ARM__TYPES_H_ -#if defined (__arm__) || defined (__arm64__) - /* * This header file contains integer types. It's intended to also contain * flotaing point and other arithmetic types, as needed, later. @@ -97,6 +95,4 @@ typedef __uint32_t __darwin_socklen_t; /* socklen_t (duh) */ typedef long __darwin_ssize_t; /* byte count or error */ typedef long __darwin_time_t; /* time() */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _BSD_ARM__TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/arch.h b/lib/libc/include/aarch64-macos.11-none/arm/arch.h index b8b25e55d3..e93e87bf06 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/arch.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/arch.h @@ -28,8 +28,6 @@ #ifndef _ARM_ARCH_H #define _ARM_ARCH_H -#if defined (__arm__) || defined (__arm64__) - /* Collect the __ARM_ARCH_*__ compiler flags into something easier to use. */ #if defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7S__) || defined (__ARM_ARCH_7F__) || defined (__ARM_ARCH_7K__) #define _ARM_ARCH_7 @@ -66,6 +64,4 @@ #define _ARM_ARCH_4 #endif -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/endian.h b/lib/libc/include/aarch64-macos.11-none/arm/endian.h index 851f2eafe2..d05874ecf4 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/endian.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/endian.h @@ -42,8 +42,6 @@ #ifndef _ARM__ENDIAN_H_ #define _ARM__ENDIAN_H_ -#if defined (__arm__) || defined (__arm64__) - #include /* * Define _NOQUAD if the compiler does NOT support 64-bit integers. @@ -77,5 +75,4 @@ #include #endif /* defined(KERNEL) || (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ -#endif /* defined (__arm__) || defined (__arm64__) */ #endif /* !_ARM__ENDIAN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/limits.h b/lib/libc/include/aarch64-macos.11-none/arm/limits.h index 21de9a758b..f889c48b6a 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/limits.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/limits.h @@ -39,8 +39,6 @@ #ifndef _ARM_LIMITS_H_ #define _ARM_LIMITS_H_ -#if defined (__arm__) || defined (__arm64__) - #include #include @@ -109,6 +107,4 @@ #endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ #endif /* !_ANSI_SOURCE */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _ARM_LIMITS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/param.h b/lib/libc/include/aarch64-macos.11-none/arm/param.h index f36fa322cb..e70f68f9c3 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/param.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/param.h @@ -48,8 +48,6 @@ #ifndef _ARM_PARAM_H_ #define _ARM_PARAM_H_ -#if defined (__arm__) || defined (__arm64__) - #include /* @@ -146,6 +144,4 @@ #define DELAY(n) { int N = (n); while (--N > 0); } #endif /* defined(KERNEL) || defined(STANDALONE) */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _ARM_PARAM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/signal.h b/lib/libc/include/aarch64-macos.11-none/arm/signal.h index 4a8b96b383..80d2564826 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/signal.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/signal.h @@ -9,14 +9,10 @@ #ifndef _ARM_SIGNAL_ #define _ARM_SIGNAL_ 1 -#if defined (__arm__) || defined (__arm64__) - #include #ifndef _ANSI_SOURCE typedef int sig_atomic_t; #endif /* ! _ANSI_SOURCE */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _ARM_SIGNAL_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/arm/types.h b/lib/libc/include/aarch64-macos.11-none/arm/types.h index 6cc1f453c9..9a6c23bb9a 100644 --- a/lib/libc/include/aarch64-macos.11-none/arm/types.h +++ b/lib/libc/include/aarch64-macos.11-none/arm/types.h @@ -39,12 +39,9 @@ * @(#)types.h 8.3 (Berkeley) 1/5/94 */ -#ifndef _ARM_MACHTYPES_H_ -#define _ARM_MACHTYPES_H_ +#ifndef _MACHTYPES_H_ #define _MACHTYPES_H_ -#if defined (__arm__) || defined (__arm64__) - #ifndef __ASSEMBLER__ #include #include @@ -107,5 +104,4 @@ typedef u_int64_t syscall_arg_t; #endif #endif /* __ASSEMBLER__ */ -#endif /* defined (__arm__) || defined (__arm64__) */ -#endif /* _ARM_MACHTYPES_H_ */ \ No newline at end of file +#endif /* _MACHTYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/_structs.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/_structs.h index da0ec8b687..ddee2f7341 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/_structs.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/_structs.h @@ -31,8 +31,6 @@ #ifndef _MACH_ARM__STRUCTS_H_ #define _MACH_ARM__STRUCTS_H_ -#if defined (__arm__) || defined (__arm64__) - #include /* __DARWIN_UNIX03 */ #include /* __uint32_t */ @@ -509,6 +507,25 @@ _STRUCT_ARM_NEON_STATE #endif /* __DARWIN_UNIX03 */ +#if __DARWIN_UNIX03 +#define _STRUCT_ARM_AMX_STATE_V1 struct __darwin_arm_amx_state_v1 +_STRUCT_ARM_AMX_STATE_V1 +{ + __uint8_t __x[8][64]; /* 8 64-byte registers */ + __uint8_t __y[8][64]; /* 8 64-byte registers */ + __uint8_t __z[64][64]; /* 64 64-byte registers in an M-by-N matrix */ + __uint64_t __amx_state_t_el1; /* AMX_STATE_T_EL1 value */ +} __attribute__((aligned(64))); +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_ARM_AMX_STATE_V1 struct arm_amx_state_v1 +_STRUCT_ARM_AMX_STATE_V1 +{ + __uint8_t x[8][64]; /* 8 64-byte registers */ + __uint8_t y[8][64]; /* 8 64-byte registers */ + __uint8_t z[64][64]; /* 64 64-byte registers in an M-by-N matrix */ + __uint64_t amx_state_t_el1; /* AMX_STATE_T_EL1 value. */ +} __attribute__((aligned(64))); +#endif /* __DARWIN_UNIX03 */ #define _STRUCT_ARM_PAGEIN_STATE struct __arm_pagein_state _STRUCT_ARM_PAGEIN_STATE @@ -625,6 +642,4 @@ _STRUCT_ARM_CPMU_STATE64 }; #endif /* !__DARWIN_UNIX03 */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM__STRUCTS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/boolean.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/boolean.h index 9cdf7c237e..703153e4e6 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/boolean.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/boolean.h @@ -65,10 +65,6 @@ #ifndef _MACH_ARM_BOOLEAN_H_ #define _MACH_ARM_BOOLEAN_H_ -#if defined (__arm__) || defined (__arm64__) - typedef int boolean_t; -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM_BOOLEAN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/exception.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/exception.h index c27dec1b56..cf804261a9 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/exception.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/exception.h @@ -29,8 +29,6 @@ #ifndef _MACH_ARM_EXCEPTION_H_ #define _MACH_ARM_EXCEPTION_H_ -#if defined (__arm__) || defined (__arm64__) - #define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ #define EXC_MASK_MACHINE 0 @@ -77,6 +75,5 @@ #define EXC_ARM_BREAKPOINT 1 /* breakpoint trap */ -#endif /* defined (__arm__) || defined (__arm64__) */ #endif /* _MACH_ARM_EXCEPTION_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/kern_return.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/kern_return.h index bfa07951b3..0c23b0f973 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/kern_return.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/kern_return.h @@ -67,12 +67,8 @@ #ifndef _MACH_ARM_KERN_RETURN_H_ #define _MACH_ARM_KERN_RETURN_H_ -#if defined (__arm__) || defined (__arm64__) - #ifndef ASSEMBLER typedef int kern_return_t; #endif /* ASSEMBLER */ -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM_KERN_RETURN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/processor_info.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/processor_info.h index a302fbfcd3..cc2cfadeb4 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/processor_info.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/processor_info.h @@ -29,8 +29,6 @@ #ifndef _MACH_ARM_PROCESSOR_INFO_H_ #define _MACH_ARM_PROCESSOR_INFO_H_ -#if defined (__arm__) || defined (__arm64__) - #define PROCESSOR_CPU_STAT 0x10000003 /* Low-level CPU statistics */ #define PROCESSOR_CPU_STAT64 0x10000004 /* Low-level CPU statistics, in full 64-bit */ @@ -71,6 +69,4 @@ typedef struct processor_cpu_stat64 *processor_cpu_stat64_t; #define PROCESSOR_CPU_STAT64_COUNT ((mach_msg_type_number_t) \ (sizeof(processor_cpu_stat64_data_t) / sizeof(integer_t))) -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM_PROCESSOR_INFO_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/rpc.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/rpc.h index cb100ece01..3543cdf1ad 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/rpc.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/rpc.h @@ -32,8 +32,4 @@ #ifndef _MACH_ARM_RPC_H_ #define _MACH_ARM_RPC_H_ -#if defined (__arm__) || defined (__arm64__) - -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM_RPC_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_state.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_state.h index d72a3c2013..75c28e6692 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_state.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_state.h @@ -32,11 +32,13 @@ #ifndef _MACH_ARM_THREAD_STATE_H_ #define _MACH_ARM_THREAD_STATE_H_ -#if defined (__arm__) || defined (__arm64__) - /* Size of maximum exported thread state in words */ #define ARM_THREAD_STATE_MAX (1296) /* Size of biggest state possible */ -#endif /* defined (__arm__) || defined (__arm64__) */ +#if defined (__arm__) || defined(__arm64__) +#define THREAD_STATE_MAX ARM_THREAD_STATE_MAX +#else +#error Unsupported arch +#endif #endif /* _MACH_ARM_THREAD_STATE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_status.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_status.h index 849eca5900..f8d0ccb037 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_status.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/thread_status.h @@ -33,12 +33,10 @@ #ifndef _ARM_THREAD_STATUS_H_ #define _ARM_THREAD_STATUS_H_ -#if defined (__arm__) || defined (__arm64__) - #include -#include #include #include +#include /* * Support for determining the state of a thread @@ -69,12 +67,13 @@ #define ARM_CPMU_STATE64 18 +/* API */ +#define ARM_AMX_STATE 24 +#define ARM_AMX_STATE_V1 25 +#define ARM_STATE_FLAVOR_IS_OTHER_VALID(_flavor_) \ + ((_flavor_) == ARM_AMX_STATE_V1) #define ARM_PAGEIN_STATE 27 -#ifndef ARM_STATE_FLAVOR_IS_OTHER_VALID -#define ARM_STATE_FLAVOR_IS_OTHER_VALID(_flavor_) 0 -#endif - #define VALID_THREAD_STATE_FLAVOR(x) \ ((x == ARM_THREAD_STATE) || \ (x == ARM_VFP_STATE) || \ @@ -171,6 +170,7 @@ typedef _STRUCT_ARM_NEON_STATE arm_neon_state_t; typedef _STRUCT_ARM_NEON_STATE arm_neon_state32_t; typedef _STRUCT_ARM_NEON_STATE64 arm_neon_state64_t; +typedef _STRUCT_ARM_AMX_STATE_V1 arm_amx_state_v1_t; typedef _STRUCT_ARM_EXCEPTION_STATE arm_exception_state_t; typedef _STRUCT_ARM_EXCEPTION_STATE arm_exception_state32_t; @@ -224,12 +224,26 @@ typedef _STRUCT_ARM_LEGACY_DEBUG_STATE arm_debug_state_t; #define MACHINE_THREAD_STATE_COUNT ARM_UNIFIED_THREAD_STATE_COUNT +struct arm_amx_state { + arm_state_hdr_t ash; + union { + arm_amx_state_v1_t as_v1; + } uas; +}; +#define as_v1 uas.as_v1 +typedef struct arm_amx_state arm_amx_state_t; + +#define ARM_AMX_STATE_V1_COUNT ((mach_msg_type_number_t) \ + (sizeof(arm_amx_state_v1_t)/sizeof(unsigned int))) + +#define ARM_AMX_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(arm_amx_state_t)/sizeof(unsigned int))) + + /* * Largest state on this machine: */ #define THREAD_MACHINE_STATE_MAX THREAD_STATE_MAX -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _ARM_THREAD_STATUS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_param.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_param.h index acb1392418..1738a03517 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_param.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_param.h @@ -36,8 +36,6 @@ #ifndef _MACH_ARM_VM_PARAM_H_ #define _MACH_ARM_VM_PARAM_H_ -#if defined (__arm__) || defined (__arm64__) - #if !defined (KERNEL) && !defined (__ASSEMBLER__) #include @@ -106,6 +104,4 @@ #define SWI_SYSCALL 0x80 -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM_VM_PARAM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_types.h b/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_types.h index 396923d4c2..6fcf262c24 100644 --- a/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_types.h +++ b/lib/libc/include/aarch64-macos.11-none/mach/arm/vm_types.h @@ -67,14 +67,11 @@ #ifndef _MACH_ARM_VM_TYPES_H_ #define _MACH_ARM_VM_TYPES_H_ -#if defined (__arm__) || defined (__arm64__) - #ifndef ASSEMBLER #include #include #include -#include /* * natural_t and integer_t are Mach's legacy types for machine- @@ -101,18 +98,18 @@ typedef int integer_t; * e.g. an offset into a virtual memory space. */ #ifdef __LP64__ -typedef uintptr_t vm_offset_t __kernel_ptr_semantics; +typedef uintptr_t vm_offset_t; typedef uintptr_t vm_size_t; -typedef uint64_t mach_vm_address_t __kernel_ptr_semantics; -typedef uint64_t mach_vm_offset_t __kernel_ptr_semantics; +typedef uint64_t mach_vm_address_t; +typedef uint64_t mach_vm_offset_t; typedef uint64_t mach_vm_size_t; -typedef uint64_t vm_map_offset_t __kernel_ptr_semantics; -typedef uint64_t vm_map_address_t __kernel_ptr_semantics; +typedef uint64_t vm_map_offset_t; +typedef uint64_t vm_map_address_t; typedef uint64_t vm_map_size_t; #else -typedef natural_t vm_offset_t __kernel_ptr_semantics; +typedef natural_t vm_offset_t; /* * A vm_size_t is the proper type for e.g. * expressing the difference between two @@ -132,13 +129,13 @@ typedef uint32_t mach_vm_address_t; typedef uint32_t mach_vm_offset_t; typedef uint32_t mach_vm_size_t; #else -typedef uint64_t mach_vm_address_t __kernel_ptr_semantics; -typedef uint64_t mach_vm_offset_t __kernel_ptr_semantics; +typedef uint64_t mach_vm_address_t; +typedef uint64_t mach_vm_offset_t; typedef uint64_t mach_vm_size_t; #endif -typedef uint32_t vm_map_offset_t __kernel_ptr_semantics; -typedef uint32_t vm_map_address_t __kernel_ptr_semantics; +typedef uint32_t vm_map_offset_t; +typedef uint32_t vm_map_address_t; typedef uint32_t vm_map_size_t; #endif /* __LP64__ */ @@ -157,6 +154,4 @@ typedef vm_offset_t mach_port_context_t; */ #define MACH_MSG_TYPE_INTEGER_T MACH_MSG_TYPE_INTEGER_32 -#endif /* defined (__arm__) || defined (__arm64__) */ - #endif /* _MACH_ARM_VM_TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/db.h b/lib/libc/include/any-macos-any/db.h new file mode 100644 index 0000000000..53ea611101 --- /dev/null +++ b/lib/libc/include/any-macos-any/db.h @@ -0,0 +1,219 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)db.h 8.7 (Berkeley) 6/16/94 + * $FreeBSD: src/include/db.h,v 1.5 2002/03/26 01:35:05 bde Exp $ + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#include +#include + +#include + +#define RET_ERROR -1 /* Return values. */ +#define RET_SUCCESS 0 +#define RET_SPECIAL 1 + +#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ +typedef u_int32_t pgno_t; +#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ +typedef u_int16_t indx_t; +#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ +typedef u_int32_t recno_t; + +/* Key/data structure -- a Data-Base Thang. */ +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT; + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; + +/* + * !!! + * The following flags are included in the dbopen(3) call as part of the + * open(2) flags. In order to avoid conflicts with the open flags, start + * at the top of the 16 or 32-bit number space and work our way down. If + * the open flags were significantly expanded in the future, it could be + * a problem. Wish I'd left another flags word in the dbopen call. + * + * !!! + * None of this stuff is implemented yet. The only reason that it's here + * is so that the access methods can skip copying the key/data pair when + * the DB_LOCK flag isn't set. + */ +#if UINT_MAX > 65535 +#define DB_LOCK 0x20000000 /* Do locking. */ +#define DB_SHMEM 0x40000000 /* Use shared memory. */ +#define DB_TXN 0x80000000 /* Do transactions. */ +#else +#define DB_LOCK 0x2000 /* Do locking. */ +#define DB_SHMEM 0x4000 /* Use shared memory. */ +#define DB_TXN 0x8000 /* Do transactions. */ +#endif + +/* Access method description structure. */ +typedef struct __db { + DBTYPE type; /* Underlying db type. */ + int (*close)(struct __db *); + int (*del)(const struct __db *, const DBT *, unsigned int); + int (*get)(const struct __db *, const DBT *, DBT *, unsigned int); + int (*put)(const struct __db *, DBT *, const DBT *, unsigned int); + int (*seq)(const struct __db *, DBT *, DBT *, unsigned int); + int (*sync)(const struct __db *, unsigned int); + void *internal; /* Access method private. */ + int (*fd)(const struct __db *); +} DB; + +#define BTREEMAGIC 0x053162 +#define BTREEVERSION 3 + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + unsigned long flags; + unsigned int cachesize; /* bytes to cache */ + int maxkeypage; /* maximum keys per page */ + int minkeypage; /* minimum keys per page */ + unsigned int psize; /* page size */ + int (*compare) /* comparison function */ + (const DBT *, const DBT *); + size_t (*prefix) /* prefix function */ + (const DBT *, const DBT *); + int lorder; /* byte order */ +} BTREEINFO; + +#define HASHMAGIC 0x061561 +#define HASHVERSION 2 + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + unsigned int bsize; /* bucket size */ + unsigned int ffactor; /* fill factor */ + unsigned int nelem; /* number of elements */ + unsigned int cachesize; /* bytes to cache */ + u_int32_t /* hash function */ + (*hash)(const void *, size_t); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + unsigned long flags; + unsigned int cachesize; /* bytes to cache */ + unsigned int psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + unsigned char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; + +#ifdef __DBINTERFACE_PRIVATE +/* + * Little endian <==> big endian 32-bit swap macros. + * M_32_SWAP swap a memory location + * P_32_SWAP swap a referenced memory location + * P_32_COPY swap from one location to another + */ +#define M_32_SWAP(a) { \ + u_int32_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[3]; \ + ((char *)&a)[1] = ((char *)&_tmp)[2]; \ + ((char *)&a)[2] = ((char *)&_tmp)[1]; \ + ((char *)&a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_SWAP(a) { \ + u_int32_t _tmp = *(u_int32_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[3]; \ + ((char *)a)[1] = ((char *)&_tmp)[2]; \ + ((char *)a)[2] = ((char *)&_tmp)[1]; \ + ((char *)a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[3]; \ + ((char *)&(b))[1] = ((char *)&(a))[2]; \ + ((char *)&(b))[2] = ((char *)&(a))[1]; \ + ((char *)&(b))[3] = ((char *)&(a))[0]; \ +} + +/* + * Little endian <==> big endian 16-bit swap macros. + * M_16_SWAP swap a memory location + * P_16_SWAP swap a referenced memory location + * P_16_COPY swap from one location to another + */ +#define M_16_SWAP(a) { \ + u_int16_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[1]; \ + ((char *)&a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_SWAP(a) { \ + u_int16_t _tmp = *(u_int16_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[1]; \ + ((char *)a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[1]; \ + ((char *)&(b))[1] = ((char *)&(a))[0]; \ +} +#endif + +__BEGIN_DECLS +DB *dbopen(const char *, int, int, DBTYPE, const void *); + +#ifdef __DBINTERFACE_PRIVATE +DB *__bt_open(const char *, int, int, const BTREEINFO *, int); +DB *__hash_open(const char *, int, int, const HASHINFO *, int); +DB *__rec_open(const char *, int, int, const RECNOINFO *, int); +void __dbpanic(DB *dbp); +#endif +__END_DECLS +#endif /* !_DB_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/err.h b/lib/libc/include/any-macos-any/err.h new file mode 100644 index 0000000000..8ce50ded57 --- /dev/null +++ b/lib/libc/include/any-macos-any/err.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2000, 2003, 2004, 2008 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)err.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _ERR_H_ +#define _ERR_H_ + +/* + * Don't use va_list in the err/warn prototypes. Va_list is typedef'd in two + * places ( and ), so if we include one + * of them here we may collide with the utility's includes. It's unreasonable + * for utilities to have to include one of them to include err.h, so we get + * __darwin_va_list from and use it. + */ +#include +#include <_types.h> +#include + +__BEGIN_DECLS +void err(int, const char *, ...) __cold __dead2 __printflike(2, 3); +void verr(int, const char *, __darwin_va_list) __cold __dead2 __printflike(2, 0); +void errc(int, int, const char *, ...) __cold __dead2 __printflike(3, 4); +void verrc(int, int, const char *, __darwin_va_list) __cold __dead2 __printflike(3, 0); +void errx(int, const char *, ...) __cold __dead2 __printflike(2, 3); +void verrx(int, const char *, __darwin_va_list) __cold __dead2 __printflike(2, 0); +void warn(const char *, ...) __cold __printflike(1, 2); +void vwarn(const char *, __darwin_va_list) __cold __printflike(1, 0); +void warnc(int, const char *, ...) __cold __printflike(2, 3); +void vwarnc(int, const char *, __darwin_va_list) __cold __printflike(2, 0); +void warnx(const char *, ...) __cold __printflike(1, 2); +void vwarnx(const char *, __darwin_va_list) __cold __printflike(1, 0); +void err_set_file(void *); +void err_set_exit(void (* _Nullable)(int)); +#ifdef __BLOCKS__ +void err_set_exit_b(void (^ _Nullable)(int)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ + +__END_DECLS + +#endif /* !_ERR_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/fts.h b/lib/libc/include/any-macos-any/fts.h new file mode 100644 index 0000000000..ef48eda68b --- /dev/null +++ b/lib/libc/include/any-macos-any/fts.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2000, 2003-2006, 2008, 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)fts.h 8.3 (Berkeley) 8/14/94 + */ + +#ifndef _FTS_H_ +#define _FTS_H_ + +#include +#include +#include +#include + +#include + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wstrict-prototypes" + +typedef struct { + struct _ftsent *fts_cur; /* current node */ + struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ + dev_t fts_dev; /* starting device # */ + char *fts_path; /* path for this descent */ + int fts_rfd; /* fd for root */ + int fts_pathlen; /* sizeof(path) */ + int fts_nitems; /* elements in the sort array */ +#ifdef __BLOCKS__ + union { +#endif /* __BLOCKS__ */ + int (*fts_compar)(); /* compare function */ +#ifdef __BLOCKS__ + int (^fts_compar_b)(); /* compare block */ + }; +#endif /* __BLOCKS__ */ + +#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */ +#define FTS_LOGICAL 0x002 /* logical walk */ +#define FTS_NOCHDIR 0x004 /* don't change directories */ +#define FTS_NOSTAT 0x008 /* don't get stat info */ +#define FTS_PHYSICAL 0x010 /* physical walk */ +#define FTS_SEEDOT 0x020 /* return dot and dot-dot */ +#define FTS_XDEV 0x040 /* don't cross devices */ +#define FTS_WHITEOUT 0x080 /* (no longer supported) return whiteout information */ +#define FTS_COMFOLLOWDIR 0x400 /* (non-std) follow command line symlinks for directories only */ +#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090) || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 70000) +#define FTS_OPTIONMASK 0x4ff /* valid user option mask */ +#else +#define FTS_NOSTAT_TYPE 0x800 /* (non-std) no stat, but use d_type in struct dirent when available */ +#define FTS_OPTIONMASK 0xcff /* valid user option mask */ +#endif + +#define FTS_NAMEONLY 0x100 /* (private) child names only */ +#define FTS_STOP 0x200 /* (private) unrecoverable error */ +#ifdef __BLOCKS__ +#define FTS_BLOCK_COMPAR 0x80000000 /* fts_compar is a block */ +#endif /* __BLOCKS__ */ + int fts_options; /* fts_open options, global flags */ +} FTS; + +typedef struct _ftsent { + struct _ftsent *fts_cycle; /* cycle node */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file in directory */ + long fts_number; /* local numeric value */ + void *fts_pointer; /* local address value */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + int fts_errno; /* errno for this node */ + int fts_symfd; /* fd for symlink or chdir */ + unsigned short fts_pathlen; /* strlen(fts_path) */ + unsigned short fts_namelen; /* strlen(fts_name) */ + + ino_t fts_ino; /* inode */ + dev_t fts_dev; /* device */ + nlink_t fts_nlink; /* link count */ + +#define FTS_ROOTPARENTLEVEL -1 +#define FTS_ROOTLEVEL 0 +#define FTS_MAXLEVEL 0x7fffffff + short fts_level; /* depth (-1 to N) */ + +#define FTS_D 1 /* preorder directory */ +#define FTS_DC 2 /* directory that causes cycles */ +#define FTS_DEFAULT 3 /* none of the above */ +#define FTS_DNR 4 /* unreadable directory */ +#define FTS_DOT 5 /* dot or dot-dot */ +#define FTS_DP 6 /* postorder directory */ +#define FTS_ERR 7 /* error; errno is set */ +#define FTS_F 8 /* regular file */ +#define FTS_INIT 9 /* initialized only */ +#define FTS_NS 10 /* stat(2) failed */ +#define FTS_NSOK 11 /* no stat(2) requested */ +#define FTS_SL 12 /* symbolic link */ +#define FTS_SLNONE 13 /* symbolic link without target */ +#define FTS_W 14 /* whiteout object */ + unsigned short fts_info; /* user flags for FTSENT structure */ + +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ +#define FTS_ISW 0x04 /* this is a whiteout object */ +#define FTS_CHDIRFD 0x08 /* indicates the fts_symfd field was set for chdir */ + unsigned short fts_flags; /* private flags for FTSENT structure */ + +#define FTS_AGAIN 1 /* read node again */ +#define FTS_FOLLOW 2 /* follow symbolic link */ +#define FTS_NOINSTR 3 /* no instructions */ +#define FTS_SKIP 4 /* discard node */ + unsigned short fts_instr; /* fts_set() instructions */ + + struct stat *fts_statp; /* stat(2) information */ + char fts_name[1]; /* file name */ +} FTSENT; + +#include +#include + +__BEGIN_DECLS +FTSENT *fts_children(FTS *, int) __DARWIN_INODE64(fts_children); +int fts_close(FTS *) __DARWIN_INODE64(fts_close); +FTS *fts_open(char * const *, int, + int (*)(const FTSENT **, const FTSENT **)) __DARWIN_INODE64(fts_open); +#ifdef __BLOCKS__ +#if __has_attribute(noescape) +#define __fts_noescape __attribute__((__noescape__)) +#else +#define __fts_noescape +#endif +FTS *fts_open_b(char * const *, int, + int (^)(const FTSENT **, const FTSENT **) __fts_noescape) + __DARWIN_INODE64(fts_open_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ +FTSENT *fts_read(FTS *) __DARWIN_INODE64(fts_read); +int fts_set(FTS *, FTSENT *, int) __DARWIN_INODE64(fts_set); +__END_DECLS + +#pragma clang diagnostic pop +#endif /* !_FTS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/iso646.h b/lib/libc/include/any-macos-any/iso646.h new file mode 100644 index 0000000000..8bde15b8c1 --- /dev/null +++ b/lib/libc/include/any-macos-any/iso646.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1998 Alex Nash + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/iso646.h,v 1.4 2002/09/18 22:23:59 mike Exp $ + */ + +#ifndef _ISO646_H_ +#define _ISO646_H_ + +#include + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + +#ifndef __cplusplus +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= +#endif /* ! __cplusplus */ + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +#endif /* !_ISO646_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/libkern/OSCacheControl.h b/lib/libc/include/any-macos-any/libkern/OSCacheControl.h new file mode 100644 index 0000000000..aff4af84ae --- /dev/null +++ b/lib/libc/include/any-macos-any/libkern/OSCacheControl.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OS_CACHE_CONTROL_H_ +#define _OS_CACHE_CONTROL_H_ + +#include +#include +#include +#include + +__BEGIN_DECLS + + +/* Functions performed by sys_cache_control(): */ + +/* Prepare memory for execution. This should be called + * after writing machine instructions to memory, before + * executing them. It syncs the dcache and icache. + * On IA32 processors this function is a NOP, because + * no synchronization is required. + */ +#define kCacheFunctionPrepareForExecution 1 + +/* Flush data cache(s). This ensures that cached data + * makes it all the way out to DRAM, and then removes + * copies of the data from all processor caches. + * It can be useful when dealing with cache incoherent + * devices or DMA. + */ +#define kCacheFunctionFlushDcache 2 + + +/* perform one of the above cache functions: */ +int sys_cache_control( int function, void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +/* equivalent to sys_cache_control(kCacheFunctionPrepareForExecution): */ +void sys_icache_invalidate( void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +/* equivalent to sys_cache_control(kCacheFunctionFlushDcache): */ +void sys_dcache_flush( void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + + +__END_DECLS + +#endif /* _OS_CACHE_CONTROL_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/libkern/OSDebug.h b/lib/libc/include/any-macos-any/libkern/OSDebug.h new file mode 100644 index 0000000000..e0eb5d7c0b --- /dev/null +++ b/lib/libc/include/any-macos-any/libkern/OSDebug.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * HISTORY + * + */ + +#ifndef _OS_OSDEBBUG_H +#define _OS_OSDEBBUG_H + +#include +#include + +__BEGIN_DECLS + +/* Report a message with a 4 entry backtrace - very slow */ +extern void OSReportWithBacktrace(const char *str, ...) __printflike(1, 2); +extern unsigned OSBacktrace(void **bt, unsigned maxAddrs); + +/* Simple dump of 20 backtrace entries */ +extern void OSPrintBacktrace(void); + +/*! @function OSKernelStackRemaining + * @abstract Returns bytes available below the current stack frame. + * @discussion Returns bytes available below the current stack frame. Safe for interrupt or thread context. + * @result Approximate byte count available. */ + +vm_offset_t OSKernelStackRemaining( void ); + +__END_DECLS + +#endif /* !_OS_OSDEBBUG_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/libkern/OSKextLib.h b/lib/libc/include/any-macos-any/libkern/OSKextLib.h new file mode 100644 index 0000000000..d7e73577e9 --- /dev/null +++ b/lib/libc/include/any-macos-any/libkern/OSKextLib.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _LIBKERN_OSKEXTLIB_H +#define _LIBKERN_OSKEXTLIB_H + +#include +__BEGIN_DECLS + +#include +#include +#include +#include + +#include + +/*! + * @header + * + * Declares functions, basic return values, and other constants + * related to kernel extensions (kexts). + */ + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark OSReturn Values for Kernel Extensions +/********************************************************************/ +#endif +/*! + * @group OSReturn Values for Kernel Extensions + * Many kext-related functions return these values, + * as well as those defined under + * @link //apple_ref/c/tdef/OSReturn OSReturn@/link + * and other variants of kern_return_t. + */ + + +#define sub_libkern_kext err_sub(2) +#define libkern_kext_err(code) (sys_libkern|sub_libkern_kext|(code)) + + +/*! + * @define kOSKextReturnInternalError + * @abstract An internal error in the kext library. + * Contrast with @link //apple_ref/c/econst/OSReturnError + * OSReturnError@/link. + */ +#define kOSKextReturnInternalError libkern_kext_err(0x1) + +/*! + * @define kOSKextReturnNoMemory + * @abstract Memory allocation failed. + */ +#define kOSKextReturnNoMemory libkern_kext_err(0x2) + +/*! + * @define kOSKextReturnNoResources + * @abstract Some resource other than memory (such as available load tags) + * is exhausted. + */ +#define kOSKextReturnNoResources libkern_kext_err(0x3) + +/*! + * @define kOSKextReturnNotPrivileged + * @abstract The caller lacks privileges to perform the requested operation. + */ +#define kOSKextReturnNotPrivileged libkern_kext_err(0x4) + +/*! + * @define kOSKextReturnInvalidArgument + * @abstract Invalid argument. + */ +#define kOSKextReturnInvalidArgument libkern_kext_err(0x5) + +/*! + * @define kOSKextReturnNotFound + * @abstract Search item not found. + */ +#define kOSKextReturnNotFound libkern_kext_err(0x6) + +/*! + * @define kOSKextReturnBadData + * @abstract Malformed data (not used for XML). + */ +#define kOSKextReturnBadData libkern_kext_err(0x7) + +/*! + * @define kOSKextReturnSerialization + * @abstract Error converting or (un)serializing URL, string, or XML. + */ +#define kOSKextReturnSerialization libkern_kext_err(0x8) + +/*! + * @define kOSKextReturnUnsupported + * @abstract Operation is no longer or not yet supported. + */ +#define kOSKextReturnUnsupported libkern_kext_err(0x9) + +/*! + * @define kOSKextReturnDisabled + * @abstract Operation is currently disabled. + */ +#define kOSKextReturnDisabled libkern_kext_err(0xa) + +/*! + * @define kOSKextReturnNotAKext + * @abstract Bundle is not a kernel extension. + */ +#define kOSKextReturnNotAKext libkern_kext_err(0xb) + +/*! + * @define kOSKextReturnValidation + * @abstract Validation failures encountered; check diagnostics for details. + */ +#define kOSKextReturnValidation libkern_kext_err(0xc) + +/*! + * @define kOSKextReturnAuthentication + * @abstract Authetication failures encountered; check diagnostics for details. + */ +#define kOSKextReturnAuthentication libkern_kext_err(0xd) + +/*! + * @define kOSKextReturnDependencies + * @abstract Dependency resolution failures encountered; check diagnostics for details. + */ +#define kOSKextReturnDependencies libkern_kext_err(0xe) + +/*! + * @define kOSKextReturnArchNotFound + * @abstract Kext does not contain code for the requested architecture. + */ +#define kOSKextReturnArchNotFound libkern_kext_err(0xf) + +/*! + * @define kOSKextReturnCache + * @abstract An error occurred processing a system kext cache. + */ +#define kOSKextReturnCache libkern_kext_err(0x10) + +/*! + * @define kOSKextReturnDeferred + * @abstract Operation has been posted asynchronously to user space (kernel only). + */ +#define kOSKextReturnDeferred libkern_kext_err(0x11) + +/*! + * @define kOSKextReturnBootLevel + * @abstract Kext not loadable or operation not allowed at current boot level. + */ +#define kOSKextReturnBootLevel libkern_kext_err(0x12) + +/*! + * @define kOSKextReturnNotLoadable + * @abstract Kext cannot be loaded; check diagnostics for details. + */ +#define kOSKextReturnNotLoadable libkern_kext_err(0x13) + +/*! + * @define kOSKextReturnLoadedVersionDiffers + * @abstract A different version (or executable UUID, or executable by checksum) + * of the requested kext is already loaded. + */ +#define kOSKextReturnLoadedVersionDiffers libkern_kext_err(0x14) + +/*! + * @define kOSKextReturnDependencyLoadError + * @abstract A load error occurred on a dependency of the kext being loaded. + */ +#define kOSKextReturnDependencyLoadError libkern_kext_err(0x15) + +/*! + * @define kOSKextReturnLinkError + * @abstract A link failure occured with this kext or a dependency. + */ +#define kOSKextReturnLinkError libkern_kext_err(0x16) + +/*! + * @define kOSKextReturnStartStopError + * @abstract The kext start or stop routine returned an error. + */ +#define kOSKextReturnStartStopError libkern_kext_err(0x17) + +/*! + * @define kOSKextReturnInUse + * @abstract The kext is currently in use or has outstanding references, + * and cannot be unloaded. + */ +#define kOSKextReturnInUse libkern_kext_err(0x18) + +/*! + * @define kOSKextReturnTimeout + * @abstract A kext request has timed out. + */ +#define kOSKextReturnTimeout libkern_kext_err(0x19) + +/*! + * @define kOSKextReturnStopping + * @abstract The kext is in the process of stopping; requests cannot be made. + */ +#define kOSKextReturnStopping libkern_kext_err(0x1a) + +/*! + * @define kOSKextReturnSystemPolicy + * @abstract The kext was prevented from loading due to system policy. + */ +#define kOSKextReturnSystemPolicy libkern_kext_err(0x1b) + +/*! + * @define kOSKextReturnKCLoadFailure + * @abstract Loading of the System KC failed + */ +#define kOSKextReturnKCLoadFailure libkern_kext_err(0x1c) + +/*! + * @define kOSKextReturnKCLoadFailureSystemKC + * @abstract Loading of the System KC failed + * + * This a sub-code of kOSKextReturnKCLoadFailure. It can be OR'd together + * with: kOSKextReturnKCLoadFailureAuxKC + * + * If both the System and Aux KCs fail to load, then the error code will be: + * libkern_kext_err(0x1f) + */ +#define kOSKextReturnKCLoadFailureSystemKC libkern_kext_err(0x1d) + +/*! + * @define kOSKextReturnKCLoadFailureAuxKC + * @abstract Loading of the Aux KC failed + * + * This a sub-code of kOSKextReturnKCLoadFailure. It can be OR'd together + * with: kOSKextReturnKCLoadFailureSystemKC + * + * If both the System and Aux KCs fail to load, then the error code will be: + * libkern_kext_err(0x1f) + */ +#define kOSKextReturnKCLoadFailureAuxKC libkern_kext_err(0x1e) + +/* next available error is: libkern_kext_err(0x20) */ + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark Kext/OSBundle Property List Keys +/********************************************************************/ +#endif +/*! + * @group Kext Property List Keys + * These constants cover CFBundle properties defined for kernel extensions. + * Because they are used in the kernel, if you want to use one with + * CFBundle APIs you'll need to wrap it in a CFSTR() macro. + */ + + +/*! + * @define kOSBundleCompatibleVersionKey + * @abstract A string giving the backwards-compatible version of a library kext + * in extended Mac OS 'vers' format (####.##.##s{1-255} where 's' + * is a build stage 'd', 'a', 'b', 'f' or 'fc'). + */ +#define kOSBundleCompatibleVersionKey "OSBundleCompatibleVersion" + +/*! + * @define kOSBundleEnableKextLoggingKey + * @abstract Set to true to have the kernel kext logging spec applied + * to the kext. + * See @link //apple_ref/c/econst/OSKextLogSpec + * OSKextLogSpec@/link. + */ +#define kOSBundleEnableKextLoggingKey "OSBundleEnableKextLogging" + +/*! + * @define kOSBundleIsInterfaceKey + * @abstract A boolean value indicating whether the kext executable + * contains only symbol references. + */ +#define kOSBundleIsInterfaceKey "OSBundleIsInterface" + +/*! + * @define kOSBundleLibrariesKey + * @abstract A dictionary listing link dependencies for this kext. + * Keys are bundle identifiers, values are version strings. + */ +#define kOSBundleLibrariesKey "OSBundleLibraries" + +/*! + * @define kOSBundleRequiredKey + * @abstract A string indicating in which kinds of startup this kext + * may need to load during early startup (before + * @link //apple_ref/doc/man/8/kextd kextcache(8)@/link). + * @discussion + * The value is one of: + *
    + *
  • @link kOSBundleRequiredRoot "OSBundleRequiredRoot"@/link
  • + *
  • @link kOSBundleRequiredLocalRoot "OSBundleRequiredLocalRoot"@/link
  • + *
  • @link kOSBundleRequiredNetworkRoot "OSBundleRequiredNetworkRoot"@/link
  • + *
  • @link kOSBundleRequiredSafeBoot "OSBundleRequiredSafeBoot"@/link
  • + *
  • @link kOSBundleRequiredConsole "OSBundleRequiredConsole"@/link
  • + *
+ * + * Use this property judiciously. + * Every kext that declares a value other than "OSBundleRequiredSafeBoot" + * increases startup time, as the booter must read it into memory, + * or startup kext caches must include it. + */ +#define kOSBundleRequiredKey "OSBundleRequired" + +/*! + * @define kOSBundleRequireExplicitLoadKey + * @abstract A boolean value indicating whether the kext requires an + * explicit kextload in order to start/match. + */ +#define kOSBundleRequireExplicitLoadKey "OSBundleRequireExplicitLoad" + +/*! + * @define kOSBundleAllowUserLoadKey + * @abstract A boolean value indicating whether + * @link //apple_ref/doc/man/8/kextd kextcache(8)@/link + * will honor a non-root process's request to load a kext. + * @discussion + * See @link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithURL + * KextManagerLoadKextWithURL@/link + * and @link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithIdentifier + * KextManagerLoadKextWithIdentifier@/link. + */ +#define kOSBundleAllowUserLoadKey "OSBundleAllowUserLoad" + +/*! + * @define kOSBundleAllowUserTerminateKey + * @abstract A boolean value indicating whether the kextunload tool + * is allowed to issue IOService terminate to classes defined in this kext. + * @discussion A boolean value indicating whether the kextunload tool + * is allowed to issue IOService terminate to classes defined in this kext. + */ +#define kOSBundleAllowUserTerminateKey "OSBundleAllowUserTerminate" + +/*! + * @define kOSKernelResourceKey + * @abstract A boolean value indicating whether the kext represents a built-in + * component of the kernel. + */ +#define kOSKernelResourceKey "OSKernelResource" + +/*! + * @define kOSKextVariantOverrideKey + * @abstract A dictionary with target names as key and a target-specific variant + * name as value. + */ +#define kOSKextVariantOverrideKey "OSKextVariantOverride" + +/*! + * @define kIOKitPersonalitiesKey + * @abstract A dictionary of dictionaries used in matching for I/O Kit drivers. + */ +#define kIOKitPersonalitiesKey "IOKitPersonalities" + +/* + * @define kIOPersonalityPublisherKey + * @abstract Used in personalities sent to the I/O Kit, + * contains the CFBundleIdentifier of the kext + * that the personality originated in. + */ +#define kIOPersonalityPublisherKey "IOPersonalityPublisher" + +#if CONFIG_KEC_FIPS +/* + * @define kAppleTextHashesKey + * @abstract A dictionary conataining hashes for corecrypto kext. + */ +#define kAppleTextHashesKey "AppleTextHashes" +#endif + +/*! + * @define kOSMutableSegmentCopy + * @abstract A boolean value indicating whether the kext requires a copy of + * its mutable segments to be kept in memory, and then reset when the kext + * unloads. This should be used with caution as it will increase the + * amount of memory used by the kext. + */ +#define kOSMutableSegmentCopy "OSMutableSegmentCopy" + + +#if PRAGMA_MARK +/********************************************************************/ +#pragma mark Kext/OSBundle Property Deprecated Keys +/********************************************************************/ +#endif +/* + * @define kOSBundleDebugLevelKey + * @abstract + * Deprecated (used on some releases of Mac OS X prior to 10.6 Snow Leopard). + * Value is an integer from 1-6, corresponding to the verbose levels + * of kext tools on those releases. + * On 10.6 Snow Leopard, use @link OSKextEnableKextLogging + * OSKextEnableKextLogging@/link. + */ +#define kOSBundleDebugLevelKey "OSBundleDebugLevel" + +/*! + * @define kOSBundleSharedExecutableIdentifierKey + * @abstract Deprecated (used on some releases of Mac OS X + * prior to 10.6 Snow Leopard). + * Value is the bundle identifier of the pseudokext + * that contains an executable shared by this kext. + */ +#define kOSBundleSharedExecutableIdentifierKey "OSBundleSharedExecutableIdentifier" + + +#if PRAGMA_MARK +/********************************************************************/ +#pragma mark Kext/OSBundle Property List Values +/********************************************************************/ +#endif + +/*! + * @group Kext Property List Values + * These constants encompass established values + * for kernel extension bundle properties. + */ + +/*! + * @define kOSKextKernelIdentifier + * @abstract + * This is the CFBundleIdentifier user for the kernel itself. + */ +#define kOSKextKernelIdentifier "__kernel__" + +/*! + * @define kOSKextBundlePackageTypeKext + * @abstract + * The bundle type value for Kernel Extensions. + */ +#define kOSKextBundlePackageTypeKext "KEXT" + +/*! + * @define kOSKextBundlePackageTypeDriverKit + * @abstract + * The bundle type value for Driver Extensions. + */ +#define kOSKextBundlePackageTypeDriverKit "DEXT" + +/*! + * @define kOSBundleRequiredRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * whether starting from a local or a network volume. + */ +#define kOSBundleRequiredRoot "Root" + +/*! + * @define kOSBundleRequiredLocalRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * when starting from a local disk. + */ +#define kOSBundleRequiredLocalRoot "Local-Root" + +/*! + * @define kOSBundleRequiredNetworkRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * when starting over a network connection. + */ +#define kOSBundleRequiredNetworkRoot "Network-Root" + +/*! + * @define kOSBundleRequiredSafeBoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext can be loaded during a safe startup. + * This value does not normally cause the kext to be read by the booter + * or included in startup kext caches. + */ +#define kOSBundleRequiredSafeBoot "Safe Boot" + +/*! + * @define kOSBundleRequiredConsole + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed for console access + * (specifically in a single-user startup when + * @link //apple_ref/doc/man/8/kextd kextd(8)@/link. + * does not run) + * and should be loaded during early startup. + */ +#define kOSBundleRequiredConsole "Console" + +/*! + * @define kOSBundleRequiredDriverKit + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the driver extension's (DriverKit driver's) + * personalities must be present in the kernel at early boot (specifically + * before @link //apple_ref/doc/man/8/kextd kextd(8)@/link starts) + * in order to compete with kexts built into the prelinkedkernel. Note that + * kextd is still required to launch the user space driver binary. The IOKit + * matching will happen during early boot, and the actual driver launch + * will happen after kextd starts. + */ +#define kOSBundleRequiredDriverKit "DriverKit" + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark Kext Information +/********************************************************************/ +#endif +/*! + * @group Kext Information + * Types, constants, and macros providing a kext with information + * about itself. + */ + +/*! + * @typedef OSKextLoadTag + * + * @abstract + * A unique identifier assigned to a loaded instanace of a kext. + * + * @discussion + * If a kext is unloaded and later reloaded, the new instance + * has a different load tag. + * + * A kext can get its own load tag in the kmod_info_t + * structure passed into its module start routine, as the + * id field (cast to this type). + */ +typedef uint32_t OSKextLoadTag; + +/*! + * @define kOSKextInvalidLoadTag + * + * @abstract + * A load tag value that will never be used for a loaded kext; + * indicates kext not found. + */ +#define kOSKextInvalidLoadTag ((OSKextLoadTag)(-1)) + + +__END_DECLS + +#endif /* _LIBKERN_OSKEXTLIB_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/libkern/OSReturn.h b/lib/libc/include/any-macos-any/libkern/OSReturn.h new file mode 100644 index 0000000000..e357300e89 --- /dev/null +++ b/lib/libc/include/any-macos-any/libkern/OSReturn.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2000 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1998 Apple Inc. All rights reserved. + * + * HISTORY + * + */ + +/* + * Core OSReturn values. + */ + +#ifndef __LIBKERN_OSRETURN_H +#define __LIBKERN_OSRETURN_H + +#include + +__BEGIN_DECLS + +#include + + +/*! + * @header + * + * Declares functions, basic return values, and other constants + * related to kernel extensions (kexts). + */ + +#if PRAGMA_MARK +#pragma mark Core OSReturn Values for Libkern +#endif +/********************************************************************* +* Core OSReturn Values for Libkern +*********************************************************************/ +/*! + * @group Core OSReturn Values for Libkern + * Some kext and I/O Kit functions can return these values, + * as well as other values of + * kern_return_t. + * + * Many of these return values represent internal errors + * in the Libkern C++ run-time typing information system + * based on @link //apple_ref/doc/class/OSMetaClass OSMetaClass@/link; + * you are unlikely to ever see them. + * + */ + + +/*! + * @typedef OSReturn + * @abstract The return type for many Libkern functions. + */ +typedef kern_return_t OSReturn; + +#ifndef sys_libkern +#define sys_libkern err_system(0x37) +#endif /* sys_libkern */ + +#define sub_libkern_common err_sub(0) +#define sub_libkern_metaclass err_sub(1) +#define sub_libkern_reserved err_sub(-1) + +#define libkern_common_err(return ) (sys_libkern|sub_libkern_common|(return)) +#define libkern_metaclass_err(return ) (sys_libkern|sub_libkern_metaclass|(return)) + +/* See OSKextLib.h for these + * #define sub_libkern_kext err_sub(2) + * #define libkern_kext_err(code) (sys_libkern|sub_libkern_kext|(code)) + */ + +/*! + * @define kOSReturnSuccess + * @abstract Operation successful. + * Equal to @link //apple_ref/c/econst/KERN_SUCCESS + * KERN_SUCCESS@/link. + */ +#define kOSReturnSuccess KERN_SUCCESS + +/*! + * @define kOSReturnError + * @abstract Unspecified Libkern error. + * Not equal to + * @link //apple_ref/c/econst/KERN_FAILURE + * KERN_FAILURE@/link. + */ +#define kOSReturnError libkern_common_err(1) + +/*! + * @define kOSMetaClassInternal + * @abstract Internal OSMetaClass run-time error. + */ +#define kOSMetaClassInternal libkern_metaclass_err(1) + +/*! + * @define kOSMetaClassHasInstances + * @abstract A kext cannot be unloaded because there are instances + * derived from Libkern C++ classes that it defines. + */ +#define kOSMetaClassHasInstances libkern_metaclass_err(2) + +/*! + * @define kOSMetaClassNoInit + * @abstract Internal error: The Libkern C++ class registration system + * was not properly initialized during kext loading. + */ +#define kOSMetaClassNoInit libkern_metaclass_err(3) +// OSMetaClass::preModLoad wasn't called, runtime internal error + +/*! + * @define kOSMetaClassNoTempData + * @abstract Internal error: An allocation failure occurred + * registering Libkern C++ classes during kext loading. + */ +#define kOSMetaClassNoTempData libkern_metaclass_err(4) +// Allocation failure internal data + +/*! + * @define kOSMetaClassNoDicts + * @abstract Internal error: An allocation failure occurred + * registering Libkern C++ classes during kext loading. + */ +#define kOSMetaClassNoDicts libkern_metaclass_err(5) +// Allocation failure for Metaclass internal dictionaries + +/*! + * @define kOSMetaClassNoKModSet + * @abstract Internal error: An allocation failure occurred + * registering Libkern C++ classes during kext loading. + */ +#define kOSMetaClassNoKModSet libkern_metaclass_err(6) +// Allocation failure for internal kmodule set + +/*! + * @define kOSMetaClassNoInsKModSet + * @abstract Internal error: An error occurred registering + * a specific Libkern C++ class during kext loading. + */ +#define kOSMetaClassNoInsKModSet libkern_metaclass_err(7) +// Can't insert the KMod set into the module dictionary + +/*! + * @define kOSMetaClassNoSuper + * @abstract Internal error: No superclass can be found + * for a specific Libkern C++ class during kext loading. + */ +#define kOSMetaClassNoSuper libkern_metaclass_err(8) + +/*! + * @define kOSMetaClassInstNoSuper + * @abstract Internal error: No superclass can be found when constructing + * an instance of a Libkern C++ class. + */ +#define kOSMetaClassInstNoSuper libkern_metaclass_err(9) + +/*! + * @define kOSMetaClassDuplicateClass + * @abstract A duplicate Libkern C++ classname was encountered + * during kext loading. + */ +#define kOSMetaClassDuplicateClass libkern_metaclass_err(10) + +/*! + * @define kOSMetaClassNoKext + * @abstract Internal error: The kext for a Libkern C++ class + * can't be found during kext loading. + */ +#define kOSMetaClassNoKext libkern_metaclass_err(11) + +__END_DECLS + +#endif /* ! __LIBKERN_OSRETURN_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/libkern/OSThermalNotification.h b/lib/libc/include/any-macos-any/libkern/OSThermalNotification.h new file mode 100644 index 0000000000..ca533a0204 --- /dev/null +++ b/lib/libc/include/any-macos-any/libkern/OSThermalNotification.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSTHERMALNOTIFICATION_H_ +#define _OSTHERMALNOTIFICATION_H_ + +#include +#include + +/* +** OSThermalNotification.h +** +** Notification mechanism to alert registered tasks when device thermal conditions +** reach certain thresholds. Notifications are triggered in both directions +** so clients can manage their memory usage more and less aggressively. +** +*/ + +__BEGIN_DECLS + +/* Define pressure levels usable by OSThermalPressureLevel */ +typedef enum { +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + kOSThermalPressureLevelNominal = 0, + kOSThermalPressureLevelModerate, + kOSThermalPressureLevelHeavy, + kOSThermalPressureLevelTrapping, + kOSThermalPressureLevelSleeping +#else + kOSThermalPressureLevelNominal = 0, + kOSThermalPressureLevelLight = 10, + kOSThermalPressureLevelModerate = 20, + kOSThermalPressureLevelHeavy = 30, + kOSThermalPressureLevelTrapping = 40, + kOSThermalPressureLevelSleeping = 50 +#endif +} OSThermalPressureLevel; + +/* + ** External notify(3) string for thermal pressure level notification + */ +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_0) +extern const char * const kOSThermalNotificationPressureLevelName; + + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0 + +typedef enum { + OSThermalNotificationLevelAny = -1, + OSThermalNotificationLevelNormal = 0, +} OSThermalNotificationLevel; + +extern OSThermalNotificationLevel _OSThermalNotificationLevelForBehavior(int) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_4_2); +extern void _OSThermalNotificationSetLevelForBehavior(int, int) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_4_2); + +enum { + kOSThermalMitigationNone, + kOSThermalMitigation70PercentTorch, + kOSThermalMitigation70PercentBacklight, + kOSThermalMitigation50PercentTorch, + kOSThermalMitigation50PercentBacklight, + kOSThermalMitigationDisableTorch, + kOSThermalMitigation25PercentBacklight, + kOSThermalMitigationDisableMapsHalo, + kOSThermalMitigationAppTerminate, + kOSThermalMitigationDeviceRestart, + kOSThermalMitigationThermalTableReady, + kOSThermalMitigationCount +}; + +#define OSThermalNotificationLevel70PercentTorch _OSThermalNotificationLevelForBehavior(kOSThermalMitigation70PercentTorch) +#define OSThermalNotificationLevel70PercentBacklight _OSThermalNotificationLevelForBehavior(kOSThermalMitigation70PercentBacklight) +#define OSThermalNotificationLevel50PercentTorch _OSThermalNotificationLevelForBehavior(kOSThermalMitigation50PercentTorch) +#define OSThermalNotificationLevel50PercentBacklight _OSThermalNotificationLevelForBehavior(kOSThermalMitigation50PercentBacklight) +#define OSThermalNotificationLevelDisableTorch _OSThermalNotificationLevelForBehavior(kOSThermalMitigationDisableTorch) +#define OSThermalNotificationLevel25PercentBacklight _OSThermalNotificationLevelForBehavior(kOSThermalMitigation25PercentBacklight) +#define OSThermalNotificationLevelDisableMapsHalo _OSThermalNotificationLevelForBehavior(kOSThermalMitigationDisableMapsHalo) +#define OSThermalNotificationLevelAppTerminate _OSThermalNotificationLevelForBehavior(kOSThermalMitigationAppTerminate) +#define OSThermalNotificationLevelDeviceRestart _OSThermalNotificationLevelForBehavior(kOSThermalMitigationDeviceRestart) + +/* Backwards compatibility */ +#define OSThermalNotificationLevelWarning OSThermalNotificationLevel70PercentBacklight +#define OSThermalNotificationLevelUrgent OSThermalNotificationLevelAppTerminate +#define OSThermalNotificationLevelCritical OSThermalNotificationLevelDeviceRestart + +/* +** Simple polling interface to detect current thermal level +*/ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0) +extern OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void); + +/* +** External notify(3) string for manual notification setup +*/ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0) +extern const char * const kOSThermalNotificationName; + +/* +** External notify(3) string for alerting user of a thermal condition +*/ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0) +extern const char * const kOSThermalNotificationAlert; + +/* +** External notify(3) string for notifying system the options taken to resolve thermal condition +*/ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0) +extern const char * const kOSThermalNotificationDecision; + +#endif // __IPHONE_OS_VERSION_MIN_REQUIRED + +__END_DECLS + +#endif /* _OSTHERMALNOTIFICATION_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/stddef.h b/lib/libc/include/any-macos-any/stddef.h new file mode 100644 index 0000000000..eedc6f46a0 --- /dev/null +++ b/lib/libc/include/any-macos-any/stddef.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2000-2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* $OpenBSD: stddef.h,v 1.2 1997/09/21 10:45:52 niklas Exp $ */ +/* $NetBSD: stddef.h,v 1.4 1994/10/26 00:56:26 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)stddef.h 5.5 (Berkeley) 4/3/91 + */ + +#ifndef __STDDEF_H__ +#define __STDDEF_H__ + +#include <_types.h> + +#include +#include +#include +#include + +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#include +#endif /* __STDC_WANT_LIB_EXT1__ >= 1 */ + +/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: + * _GCC_SIZE_T */ +#include + +#include + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +#include +#endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) \ + || (defined(__cplusplus) && __cplusplus >= 201103L) +typedef long double max_align_t; +#endif + +#endif /* __STDDEF_H__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/sys/_types/_offsetof.h b/lib/libc/include/any-macos-any/sys/_types/_offsetof.h new file mode 100644 index 0000000000..05c5381d1d --- /dev/null +++ b/lib/libc/include/any-macos-any/sys/_types/_offsetof.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2003-2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef offsetof +#define offsetof(type, field) __offsetof(type, field) +#endif /* offsetof */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/sys/_types/_ptrdiff_t.h b/lib/libc/include/any-macos-any/sys/_types/_ptrdiff_t.h new file mode 100644 index 0000000000..096dfd5cf1 --- /dev/null +++ b/lib/libc/include/any-macos-any/sys/_types/_ptrdiff_t.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +#include /* __darwin_ptrdiff_t */ +typedef __darwin_ptrdiff_t ptrdiff_t; +#endif /* _PTRDIFF_T */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/vis.h b/lib/libc/include/any-macos-any/vis.h new file mode 100644 index 0000000000..6e06eb4e56 --- /dev/null +++ b/lib/libc/include/any-macos-any/vis.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* $NetBSD: vis.h,v 1.21 2013/02/20 17:01:15 christos Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)vis.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _VIS_H_ +#define _VIS_H_ + +#include <_types.h> +#include + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x0001 /* use octal \ddd format */ +#define VIS_CSTYLE 0x0002 /* use \[nrft0..] where appropiate */ + +/* + * to alter set of characters encoded (default is to encode all + * non-graphic except space, tab, and newline). + */ +#define VIS_SP 0x0004 /* also encode space */ +#define VIS_TAB 0x0008 /* also encode tab */ +#define VIS_NL 0x0010 /* also encode newline */ +#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x0020 /* only encode "unsafe" characters */ + +/* + * other + */ +#define VIS_NOSLASH 0x0040 /* inhibit printing '\' */ +#define VIS_HTTP1808 0x0080 /* http-style escape % hex hex */ +#define VIS_HTTPSTYLE 0x0080 /* http-style escape % hex hex */ +#define VIS_GLOB 0x0100 /* encode glob(3) magic characters */ +#define VIS_MIMESTYLE 0x0200 /* mime-style escape = HEX HEX */ +#define VIS_HTTP1866 0x0400 /* http-style &#num; or &string; */ +#define VIS_NOESCAPE 0x0800 /* don't decode `\' */ +#define _VIS_END 0x1000 /* for unvis */ + +/* + * unvis return codes + */ +#define UNVIS_VALID 1 /* character valid */ +#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ +#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ +#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ +#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ + +/* + * unvis flags + */ +#define UNVIS_END _VIS_END /* no more characters */ + +#include + +__BEGIN_DECLS +char *vis(char *, int, int, int); +char *nvis(char *, size_t, int, int, int); + +char *svis(char *, int, int, int, const char *); +char *snvis(char *, size_t, int, int, int, const char *); + +int strvis(char *, const char *, int); +int strnvis(char *, size_t, const char *, int); + +int strsvis(char *, const char *, int, const char *); +int strsnvis(char *, size_t, const char *, int, const char *); + +int strvisx(char *, const char *, size_t, int); +int strnvisx(char *, size_t, const char *, size_t, int); +int strenvisx(char *, size_t, const char *, size_t, int, int *); + +int strsvisx(char *, const char *, size_t, int, const char *); +int strsnvisx(char *, size_t, const char *, size_t, int, const char *); +int strsenvisx(char *, size_t, const char *, size_t , int, const char *, + int *); + +int strunvis(char *, const char *); +int strnunvis(char *, size_t, const char *); + +int strunvisx(char *, const char *, int); +int strnunvisx(char *, size_t, const char *, int); + +int unvis(char *, int, int *, int); +__END_DECLS + +#endif /* !_VIS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/AssertMacros.h b/lib/libc/include/any-macos.11-any/AssertMacros.h new file mode 100644 index 0000000000..7dc2e589af --- /dev/null +++ b/lib/libc/include/any-macos.11-any/AssertMacros.h @@ -0,0 +1,1441 @@ +/* + * Copyright (c) 2002-2017 by Apple Inc.. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +/* + File: AssertMacros.h + + Contains: This file defines structured error handling and assertion macros for + programming in C. Originally used in QuickDraw GX and later enhanced. + These macros are used throughout Apple's software. + + New code may not want to begin adopting these macros and instead use + existing language functionality. + + See "Living In an Exceptional World" by Sean Parent + (develop, The Apple Technical Journal, Issue 11, August/September 1992) + or + + for the methodology behind these error handling and assertion macros. + + Bugs?: For bug reports, consult the following page on + the World Wide Web: + + http://developer.apple.com/bugreporter/ +*/ +#ifndef __ASSERTMACROS__ +#define __ASSERTMACROS__ + +#ifdef DEBUG_ASSERT_CONFIG_INCLUDE + #include DEBUG_ASSERT_CONFIG_INCLUDE +#endif + +/* + * Macro overview: + * + * check(assertion) + * In production builds, pre-processed away + * In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE + * + * verify(assertion) + * In production builds, evaluates assertion and does nothing + * In debug builds, if assertion evaluates to false, calls DEBUG_ASSERT_MESSAGE + * + * require(assertion, exceptionLabel) + * In production builds, if the assertion expression evaluates to false, goto exceptionLabel + * In debug builds, if the assertion expression evaluates to false, calls DEBUG_ASSERT_MESSAGE + * and jumps to exceptionLabel + * + * In addition the following suffixes are available: + * + * _noerr Adds "!= 0" to assertion. Useful for asserting and OSStatus or OSErr is noErr (zero) + * _action Adds statement to be executued if assertion fails + * _quiet Suppress call to DEBUG_ASSERT_MESSAGE + * _string Allows you to add explanitory message to DEBUG_ASSERT_MESSAGE + * + * For instance, require_noerr_string(resultCode, label, msg) will do nothing if + * resultCode is zero, otherwise it will call DEBUG_ASSERT_MESSAGE with msg + * and jump to label. + * + * Configuration: + * + * By default all macros generate "production code" (i.e non-debug). If + * DEBUG_ASSERT_PRODUCTION_CODE is defined to zero or DEBUG is defined to non-zero + * while this header is included, the macros will generated debug code. + * + * If DEBUG_ASSERT_COMPONENT_NAME_STRING is defined, all debug messages will + * be prefixed with it. + * + * By default, all messages write to stderr. If you would like to write a custom + * error message formater, defined DEBUG_ASSERT_MESSAGE to your function name. + * + * Each individual macro will only be defined if it is not already defined, so + * you can redefine their behavior singly by providing your own definition before + * this file is included. + * + * If you define __ASSERTMACROS__ before this file is included, then nothing in + * this file will take effect. + * + * Prior to Mac OS X 10.6 the macro names used in this file conflicted with some + * user code, including libraries in boost and the proposed C++ standards efforts, + * and there was no way for a client of this header to resolve this conflict. Because + * of this, most of the macros have been changed so that they are prefixed with + * __ and contain at least one capital letter, which should alleviate the current + * and future conflicts. However, to allow current sources to continue to compile, + * compatibility macros are defined at the end with the old names. A tops script + * at the end of this file will convert all of the old macro names used in a directory + * to the new names. Clients are recommended to migrate over to these new macros as + * they update their sources because a future release of Mac OS X will remove the + * old macro definitions ( without the double-underscore prefix ). Clients who + * want to compile without the old macro definitions can define the macro + * __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES to 0 before this file is + * included. + */ + + +/* + * Before including this file, #define DEBUG_ASSERT_COMPONENT_NAME_STRING to + * a C-string containing the name of your client. This string will be passed to + * the DEBUG_ASSERT_MESSAGE macro for inclusion in any assertion messages. + * + * If you do not define DEBUG_ASSERT_COMPONENT_NAME_STRING, the default + * DEBUG_ASSERT_COMPONENT_NAME_STRING value, an empty string, will be used by + * the assertion macros. + */ +#ifndef DEBUG_ASSERT_COMPONENT_NAME_STRING + #define DEBUG_ASSERT_COMPONENT_NAME_STRING "" +#endif + + +/* + * To activate the additional assertion code and messages for non-production builds, + * #define DEBUG_ASSERT_PRODUCTION_CODE to zero before including this file. + * + * If you do not define DEBUG_ASSERT_PRODUCTION_CODE, the default value 1 will be used + * (production code = no assertion code and no messages). + */ +#ifndef DEBUG_ASSERT_PRODUCTION_CODE + #define DEBUG_ASSERT_PRODUCTION_CODE !DEBUG +#endif + + +/* + * DEBUG_ASSERT_MESSAGE(component, assertion, label, error, file, line, errorCode) + * + * Summary: + * All assertion messages are routed through this macro. If you wish to use your + * own routine to display assertion messages, you can override DEBUG_ASSERT_MESSAGE + * by #defining DEBUG_ASSERT_MESSAGE before including this file. + * + * Parameters: + * + * componentNameString: + * A pointer to a string constant containing the name of the + * component this code is part of. This must be a string constant + * (and not a string variable or NULL) because the preprocessor + * concatenates it with other string constants. + * + * assertionString: + * A pointer to a string constant containing the assertion. + * This must be a string constant (and not a string variable or + * NULL) because the Preprocessor concatenates it with other + * string constants. + * + * exceptionLabelString: + * A pointer to a string containing the exceptionLabel, or NULL. + * + * errorString: + * A pointer to the error string, or NULL. DEBUG_ASSERT_MESSAGE macros + * must not attempt to concatenate this string with constant + * character strings. + * + * fileName: + * A pointer to the fileName or pathname (generated by the + * preprocessor __FILE__ identifier), or NULL. + * + * lineNumber: + * The line number in the file (generated by the preprocessor + * __LINE__ identifier), or 0 (zero). + * + * errorCode: + * A value associated with the assertion, or 0. + * + * Here is an example of a DEBUG_ASSERT_MESSAGE macro and a routine which displays + * assertion messsages: + * + * #define DEBUG_ASSERT_COMPONENT_NAME_STRING "MyCoolProgram" + * + * #define DEBUG_ASSERT_MESSAGE(componentNameString, assertionString, \ + * exceptionLabelString, errorString, fileName, lineNumber, errorCode) \ + * MyProgramDebugAssert(componentNameString, assertionString, \ + * exceptionLabelString, errorString, fileName, lineNumber, errorCode) + * + * static void + * MyProgramDebugAssert(const char *componentNameString, const char *assertionString, + * const char *exceptionLabelString, const char *errorString, + * const char *fileName, long lineNumber, int errorCode) + * { + * if ( (assertionString != NULL) && (*assertionString != '\0') ) + * fprintf(stderr, "Assertion failed: %s: %s\n", componentNameString, assertionString); + * else + * fprintf(stderr, "Check failed: %s:\n", componentNameString); + * if ( exceptionLabelString != NULL ) + * fprintf(stderr, " %s\n", exceptionLabelString); + * if ( errorString != NULL ) + * fprintf(stderr, " %s\n", errorString); + * if ( fileName != NULL ) + * fprintf(stderr, " file: %s\n", fileName); + * if ( lineNumber != 0 ) + * fprintf(stderr, " line: %ld\n", lineNumber); + * if ( errorCode != 0 ) + * fprintf(stderr, " error: %d\n", errorCode); + * } + * + * If you do not define DEBUG_ASSERT_MESSAGE, a simple printf to stderr will be used. + */ +#ifndef DEBUG_ASSERT_MESSAGE + #ifdef KERNEL + #include + #define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \ + printf( "AssertMacros: %s, %s file: %s, line: %d, value: %ld\n", assertion, (message!=0) ? message : "", file, line, (long) (value)); + #else + #include + #define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \ + fprintf(stderr, "AssertMacros: %s, %s file: %s, line: %d, value: %ld\n", assertion, (message!=0) ? message : "", file, line, (long) (value)); + #endif +#endif + + + + + +/* + * __Debug_String(message) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * message: + * The C string to display. + * + */ +#ifndef __Debug_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Debug_String(message) + #else + #define __Debug_String(message) \ + do \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + "", \ + 0, \ + message, \ + __FILE__, \ + __LINE__, \ + 0); \ + } while ( 0 ) + #endif +#endif + +/* + * __Check(assertion) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + */ +#ifndef __Check + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Check(assertion) + #else + #define __Check(assertion) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, 0, 0, __FILE__, __LINE__, 0 ); \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nCheck + #define __nCheck(assertion) __Check(!(assertion)) +#endif + +/* + * __Check_String(assertion, message) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * message: + * The C string to display. + */ +#ifndef __Check_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Check_String(assertion, message) + #else + #define __Check_String(assertion, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, 0, message, __FILE__, __LINE__, 0 ); \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nCheck_String + #define __nCheck_String(assertion, message) __Check_String(!(assertion), message) +#endif + +/* + * __Check_noErr(errorCode) + * + * Summary: + * Production builds: does nothing and produces no code. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The errorCode expression to compare with 0. + */ +#ifndef __Check_noErr + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Check_noErr(errorCode) + #else + #define __Check_noErr(errorCode) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", 0, 0, __FILE__, __LINE__, evalOnceErrorCode ); \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Check_noErr_String(errorCode, message) + * + * Summary: + * Production builds: check_noerr_string() does nothing and produces + * no code. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The errorCode expression to compare to 0. + * + * message: + * The C string to display. + */ +#ifndef __Check_noErr_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Check_noErr_String(errorCode, message) + #else + #define __Check_noErr_String(errorCode, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", 0, message, __FILE__, __LINE__, evalOnceErrorCode ); \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Verify(assertion) + * + * Summary: + * Production builds: evaluate the assertion expression, but ignore + * the result. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + */ +#ifndef __Verify + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Verify(assertion) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + } \ + } while ( 0 ) + #else + #define __Verify(assertion) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, 0, 0, __FILE__, __LINE__, 0 ); \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nVerify + #define __nVerify(assertion) __Verify(!(assertion)) +#endif + +/* + * __Verify_String(assertion, message) + * + * Summary: + * Production builds: evaluate the assertion expression, but ignore + * the result. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * message: + * The C string to display. + */ +#ifndef __Verify_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Verify_String(assertion, message) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + } \ + } while ( 0 ) + #else + #define __Verify_String(assertion, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, 0, message, __FILE__, __LINE__, 0 ); \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nVerify_String + #define __nVerify_String(assertion, message) __Verify_String(!(assertion), message) +#endif + +/* + * __Verify_noErr(errorCode) + * + * Summary: + * Production builds: evaluate the errorCode expression, but ignore + * the result. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + */ +#ifndef __Verify_noErr + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Verify_noErr(errorCode) \ + do \ + { \ + if ( 0 != (errorCode) ) \ + { \ + } \ + } while ( 0 ) + #else + #define __Verify_noErr(errorCode) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", 0, 0, __FILE__, __LINE__, evalOnceErrorCode ); \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Verify_noErr_String(errorCode, message) + * + * Summary: + * Production builds: evaluate the errorCode expression, but ignore + * the result. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * message: + * The C string to display. + */ +#ifndef __Verify_noErr_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Verify_noErr_String(errorCode, message) \ + do \ + { \ + if ( 0 != (errorCode) ) \ + { \ + } \ + } while ( 0 ) + #else + #define __Verify_noErr_String(errorCode, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", 0, message, __FILE__, __LINE__, evalOnceErrorCode ); \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Verify_noErr_Action(errorCode, action) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block). + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE and then execute the action statement or compound + * statement (block). + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * action: + * The statement or compound statement (block). + */ +#ifndef __Verify_noErr_Action + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Verify_noErr_Action(errorCode, action) \ + if ( 0 != (errorCode) ) { \ + action; \ + } \ + else do {} while (0) + #else + #define __Verify_noErr_Action(errorCode, action) \ + do { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", 0, 0, __FILE__, __LINE__, evalOnceErrorCode ); \ + action; \ + } \ + } while (0) + #endif +#endif + +/* + * __Verify_Action(assertion, action) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * then execute the action statement or compound statement (block). + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE and then execute the action statement or compound + * statement (block). + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * action: + * The statement or compound statement (block). + */ +#ifndef __Verify_Action + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Verify_Action(assertion, action) \ + if ( __builtin_expect(!(assertion), 0) ) { \ + action; \ + } \ + else do {} while (0) + #else + #define __Verify_Action(assertion, action) \ + if ( __builtin_expect(!(assertion), 0) ) { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, 0, 0, __FILE__, __LINE__, 0 ); \ + action; \ + } \ + else do {} while (0) + #endif +#endif + +/* + * __Require(assertion, exceptionLabel) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + */ +#ifndef __Require + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nRequire + #define __nRequire(assertion, exceptionLabel) __Require(!(assertion), exceptionLabel) +#endif + +/* + * __Require_Action(assertion, exceptionLabel, action) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * execute the action statement or compound statement (block) and then + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound + * statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#ifndef __Require_Action + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_Action(assertion, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_Action(assertion, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nRequire_Action + #define __nRequire_Action(assertion, exceptionLabel, action) \ + __Require_Action(!(assertion), exceptionLabel, action) +#endif + +/* + * __Require_Quiet(assertion, exceptionLabel) + * + * Summary: + * If the assertion expression evaluates to false, goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + */ +#ifndef __Require_Quiet + #define __Require_Quiet(assertion, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +#ifndef __nRequire_Quiet + #define __nRequire_Quiet(assertion, exceptionLabel) __Require_Quiet(!(assertion), exceptionLabel) +#endif + +/* + * __Require_Action_Quiet(assertion, exceptionLabel, action) + * + * Summary: + * If the assertion expression evaluates to false, execute the action + * statement or compound statement (block), and goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#ifndef __Require_Action_Quiet + #define __Require_Action_Quiet(assertion, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +#ifndef __nRequire_Action_Quiet + #define __nRequire_Action_Quiet(assertion, exceptionLabel, action) \ + __Require_Action_Quiet(!(assertion), exceptionLabel, action) +#endif + +/* + * __Require_String(assertion, exceptionLabel, message) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * message: + * The C string to display. + */ +#ifndef __Require_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_String(assertion, exceptionLabel, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_String(assertion, exceptionLabel, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, #exceptionLabel, message, __FILE__, __LINE__, 0); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nRequire_String + #define __nRequire_String(assertion, exceptionLabel, string) \ + __Require_String(!(assertion), exceptionLabel, string) +#endif + +/* + * __Require_Action_String(assertion, exceptionLabel, action, message) + * + * Summary: + * Production builds: if the assertion expression evaluates to false, + * execute the action statement or compound statement (block), and then + * goto exceptionLabel. + * + * Non-production builds: if the assertion expression evaluates to false, + * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound + * statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * assertion: + * The assertion expression. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + * + * message: + * The C string to display. + */ +#ifndef __Require_Action_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_Action_String(assertion, exceptionLabel, action, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_Action_String(assertion, exceptionLabel, action, message) \ + do \ + { \ + if ( __builtin_expect(!(assertion), 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #assertion, #exceptionLabel, message, __FILE__, __LINE__, 0); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +#ifndef __nRequire_Action_String + #define __nRequire_Action_String(assertion, exceptionLabel, action, message) \ + __Require_Action_String(!(assertion), exceptionLabel, action, message) +#endif + +/* + * __Require_noErr(errorCode, exceptionLabel) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + */ +#ifndef __Require_noErr + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_noErr(errorCode, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_noErr(errorCode, exceptionLabel) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", #exceptionLabel, 0, __FILE__, __LINE__, evalOnceErrorCode); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Require_noErr_Action(errorCode, exceptionLabel, action) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block) and + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE, execute the action statement or + * compound statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#ifndef __Require_noErr_Action + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_noErr_Action(errorCode, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_noErr_Action(errorCode, exceptionLabel, action) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", #exceptionLabel, 0, __FILE__, __LINE__, evalOnceErrorCode); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Require_noErr_Quiet(errorCode, exceptionLabel) + * + * Summary: + * If the errorCode expression does not equal 0 (noErr), + * goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + */ +#ifndef __Require_noErr_Quiet + #define __Require_noErr_Quiet(errorCode, exceptionLabel) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +/* + * __Require_noErr_Action_Quiet(errorCode, exceptionLabel, action) + * + * Summary: + * If the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block) and + * goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + */ +#ifndef __Require_noErr_Action_Quiet + #define __Require_noErr_Action_Quiet(errorCode, exceptionLabel, action) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) +#endif + +/* + * __Require_noErr_String(errorCode, exceptionLabel, message) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE, and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * message: + * The C string to display. + */ +#ifndef __Require_noErr_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_noErr_String(errorCode, exceptionLabel, message) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_noErr_String(errorCode, exceptionLabel, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", #exceptionLabel, message, __FILE__, __LINE__, evalOnceErrorCode); \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Require_noErr_Action_String(errorCode, exceptionLabel, action, message) + * + * Summary: + * Production builds: if the errorCode expression does not equal 0 (noErr), + * execute the action statement or compound statement (block) and + * goto exceptionLabel. + * + * Non-production builds: if the errorCode expression does not equal 0 (noErr), + * call DEBUG_ASSERT_MESSAGE, execute the action statement or compound + * statement (block), and then goto exceptionLabel. + * + * Parameters: + * + * errorCode: + * The expression to compare to 0. + * + * exceptionLabel: + * The label. + * + * action: + * The statement or compound statement (block). + * + * message: + * The C string to display. + */ +#ifndef __Require_noErr_Action_String + #if DEBUG_ASSERT_PRODUCTION_CODE + #define __Require_noErr_Action_String(errorCode, exceptionLabel, action, message) \ + do \ + { \ + if ( __builtin_expect(0 != (errorCode), 0) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #else + #define __Require_noErr_Action_String(errorCode, exceptionLabel, action, message) \ + do \ + { \ + long evalOnceErrorCode = (errorCode); \ + if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ + { \ + DEBUG_ASSERT_MESSAGE( \ + DEBUG_ASSERT_COMPONENT_NAME_STRING, \ + #errorCode " == 0 ", #exceptionLabel, message, __FILE__, __LINE__, evalOnceErrorCode); \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + #endif +#endif + +/* + * __Check_Compile_Time(expr) + * + * Summary: + * any build: if the expression is not true, generated a compile time error. + * + * Parameters: + * + * expr: + * The compile time expression that should evaluate to non-zero. + * + * Discussion: + * This declares an array with a size that is determined by a compile-time expression. + * If false, it declares a negatively sized array, which generates a compile-time error. + * + * Examples: + * __Check_Compile_Time( sizeof( int ) == 4 ); + * __Check_Compile_Time( offsetof( MyStruct, myField ) == 4 ); + * __Check_Compile_Time( ( kMyBufferSize % 512 ) == 0 ); + * + * Note: This only works with compile-time expressions. + * Note: This only works in places where extern declarations are allowed (e.g. global scope). + */ +#ifndef __Check_Compile_Time + #ifdef __GNUC__ + #if (__cplusplus >= 201103L) + #define __Check_Compile_Time( expr ) static_assert( expr , "__Check_Compile_Time") + #elif (__STDC_VERSION__ >= 201112L) + #define __Check_Compile_Time( expr ) _Static_assert( expr , "__Check_Compile_Time") + #else + #define __Check_Compile_Time( expr ) \ + extern int compile_time_assert_failed[ ( expr ) ? 1 : -1 ] __attribute__( ( unused ) ) + #endif + #else + #define __Check_Compile_Time( expr ) \ + extern int compile_time_assert_failed[ ( expr ) ? 1 : -1 ] + #endif +#endif + +/* + * For time immemorial, Mac OS X has defined version of most of these macros without the __ prefix, which + * could collide with similarly named functions or macros in user code, including new functionality in + * Boost and the C++ standard library. + * + * macOS High Sierra and iOS 11 will now require that clients move to the new macros as defined above. + * + * If you would like to enable the macros for use within your own project, you can define the + * __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES macro via an Xcode Build Configuration. + * See "Add a build configuration (xcconfig) file" in Xcode Help. + * + * To aid users of these macros in converting their sources, the following tops script will convert usages + * of the old macros into the new equivalents. To do so, in Terminal go into the directory containing the + * sources to be converted and run this command. + * + find -E . -regex '.*\.(c|cc|cp|cpp|m|mm|h)' -print0 | xargs -0 tops -verbose \ + replace "check()" with "__Check()" \ + replace "check_noerr()" with "__Check_noErr()" \ + replace "check_noerr_string()" with "__Check_noErr_String()" \ + replace "check_string()" with "__Check_String()" \ + replace "require()" with "__Require()" \ + replace "require_action()" with "__Require_Action()" \ + replace "require_action_string()" with "__Require_Action_String()" \ + replace "require_noerr()" with "__Require_noErr()" \ + replace "require_noerr_action()" with "__Require_noErr_Action()" \ + replace "require_noerr_action_string()" with "__Require_noErr_Action_String()" \ + replace "require_noerr_string()" with "__Require_noErr_String()" \ + replace "require_string()" with "__Require_String()" \ + replace "verify()" with "__Verify()" \ + replace "verify_action()" with "__Verify_Action()" \ + replace "verify_noerr()" with "__Verify_noErr()" \ + replace "verify_noerr_action()" with "__Verify_noErr_Action()" \ + replace "verify_noerr_string()" with "__Verify_noErr_String()" \ + replace "verify_string()" with "__Verify_String()" \ + replace "ncheck()" with "__nCheck()" \ + replace "ncheck_string()" with "__nCheck_String()" \ + replace "nrequire()" with "__nRequire()" \ + replace "nrequire_action()" with "__nRequire_Action()" \ + replace "nrequire_action_quiet()" with "__nRequire_Action_Quiet()" \ + replace "nrequire_action_string()" with "__nRequire_Action_String()" \ + replace "nrequire_quiet()" with "__nRequire_Quiet()" \ + replace "nrequire_string()" with "__nRequire_String()" \ + replace "nverify()" with "__nVerify()" \ + replace "nverify_string()" with "__nVerify_String()" \ + replace "require_action_quiet()" with "__Require_Action_Quiet()" \ + replace "require_noerr_action_quiet()" with "__Require_noErr_Action_Quiet()" \ + replace "require_noerr_quiet()" with "__Require_noErr_Quiet()" \ + replace "require_quiet()" with "__Require_Quiet()" \ + replace "check_compile_time()" with "__Check_Compile_Time()" \ + replace "debug_string()" with "__Debug_String()" + * + */ + +#ifndef __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES + #if __has_include() + #include + #else + /* In macOS High Sierra and iOS 11, if we haven't set this yet, it now defaults to off. */ + #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 + #endif +#endif + +#if __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES + + #ifndef check + #define check(assertion) __Check(assertion) + #endif + + #ifndef check_noerr + #define check_noerr(errorCode) __Check_noErr(errorCode) + #endif + + #ifndef check_noerr_string + #define check_noerr_string(errorCode, message) __Check_noErr_String(errorCode, message) + #endif + + #ifndef check_string + #define check_string(assertion, message) __Check_String(assertion, message) + #endif + + #ifndef require + #define require(assertion, exceptionLabel) __Require(assertion, exceptionLabel) + #endif + + #ifndef require_action + #define require_action(assertion, exceptionLabel, action) __Require_Action(assertion, exceptionLabel, action) + #endif + + #ifndef require_action_string + #define require_action_string(assertion, exceptionLabel, action, message) __Require_Action_String(assertion, exceptionLabel, action, message) + #endif + + #ifndef require_noerr + #define require_noerr(errorCode, exceptionLabel) __Require_noErr(errorCode, exceptionLabel) + #endif + + #ifndef require_noerr_action + #define require_noerr_action(errorCode, exceptionLabel, action) __Require_noErr_Action(errorCode, exceptionLabel, action) + #endif + + #ifndef require_noerr_action_string + #define require_noerr_action_string(errorCode, exceptionLabel, action, message) __Require_noErr_Action_String(errorCode, exceptionLabel, action, message) + #endif + + #ifndef require_noerr_string + #define require_noerr_string(errorCode, exceptionLabel, message) __Require_noErr_String(errorCode, exceptionLabel, message) + #endif + + #ifndef require_string + #define require_string(assertion, exceptionLabel, message) __Require_String(assertion, exceptionLabel, message) + #endif + + #ifndef verify + #define verify(assertion) __Verify(assertion) + #endif + + #ifndef verify_action + #define verify_action(assertion, action) __Verify_Action(assertion, action) + #endif + + #ifndef verify_noerr + #define verify_noerr(errorCode) __Verify_noErr(errorCode) + #endif + + #ifndef verify_noerr_action + #define verify_noerr_action(errorCode, action) __Verify_noErr_Action(errorCode, action) + #endif + + #ifndef verify_noerr_string + #define verify_noerr_string(errorCode, message) __Verify_noErr_String(errorCode, message) + #endif + + #ifndef verify_string + #define verify_string(assertion, message) __Verify_String(assertion, message) + #endif + + #ifndef ncheck + #define ncheck(assertion) __nCheck(assertion) + #endif + + #ifndef ncheck_string + #define ncheck_string(assertion, message) __nCheck_String(assertion, message) + #endif + + #ifndef nrequire + #define nrequire(assertion, exceptionLabel) __nRequire(assertion, exceptionLabel) + #endif + + #ifndef nrequire_action + #define nrequire_action(assertion, exceptionLabel, action) __nRequire_Action(assertion, exceptionLabel, action) + #endif + + #ifndef nrequire_action_quiet + #define nrequire_action_quiet(assertion, exceptionLabel, action) __nRequire_Action_Quiet(assertion, exceptionLabel, action) + #endif + + #ifndef nrequire_action_string + #define nrequire_action_string(assertion, exceptionLabel, action, message) __nRequire_Action_String(assertion, exceptionLabel, action, message) + #endif + + #ifndef nrequire_quiet + #define nrequire_quiet(assertion, exceptionLabel) __nRequire_Quiet(assertion, exceptionLabel) + #endif + + #ifndef nrequire_string + #define nrequire_string(assertion, exceptionLabel, string) __nRequire_String(assertion, exceptionLabel, string) + #endif + + #ifndef nverify + #define nverify(assertion) __nVerify(assertion) + #endif + + #ifndef nverify_string + #define nverify_string(assertion, message) __nVerify_String(assertion, message) + #endif + + #ifndef require_action_quiet + #define require_action_quiet(assertion, exceptionLabel, action) __Require_Action_Quiet(assertion, exceptionLabel, action) + #endif + + #ifndef require_noerr_action_quiet + #define require_noerr_action_quiet(errorCode, exceptionLabel, action) __Require_noErr_Action_Quiet(errorCode, exceptionLabel, action) + #endif + + #ifndef require_noerr_quiet + #define require_noerr_quiet(errorCode, exceptionLabel) __Require_noErr_Quiet(errorCode, exceptionLabel) + #endif + + #ifndef require_quiet + #define require_quiet(assertion, exceptionLabel) __Require_Quiet(assertion, exceptionLabel) + #endif + + #ifndef check_compile_time + #define check_compile_time( expr ) __Check_Compile_Time( expr ) + #endif + + #ifndef debug_string + #define debug_string(message) __Debug_String(message) + #endif + +#endif /* ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES */ + + +#endif /* __ASSERTMACROS__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/AvailabilityInternal.h b/lib/libc/include/any-macos.11-any/AvailabilityInternal.h index 3eb79b6084..6a35a16782 100644 --- a/lib/libc/include/any-macos.11-any/AvailabilityInternal.h +++ b/lib/libc/include/any-macos.11-any/AvailabilityInternal.h @@ -55,7 +55,7 @@ #ifdef __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ /* compiler sets __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ when -mtvos-version-min is used */ #define __TV_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ - #define __TV_OS_VERSION_MAX_ALLOWED __TVOS_15_2 + #define __TV_OS_VERSION_MAX_ALLOWED __TVOS_14_5 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 90000 #endif @@ -65,7 +65,7 @@ #ifdef __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ /* compiler sets __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ when -mwatchos-version-min is used */ #define __WATCH_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ - #define __WATCH_OS_VERSION_MAX_ALLOWED __WATCHOS_8_3 + #define __WATCH_OS_VERSION_MAX_ALLOWED __WATCHOS_7_4 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 90000 #endif @@ -75,7 +75,7 @@ #ifdef __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ #define __BRIDGE_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ - #define __BRIDGE_OS_VERSION_MAX_ALLOWED 60100 + #define __BRIDGE_OS_VERSION_MAX_ALLOWED 50300 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 110000 #endif @@ -90,14 +90,14 @@ #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED /* make sure a default max version is set */ #ifndef __MAC_OS_X_VERSION_MAX_ALLOWED - #define __MAC_OS_X_VERSION_MAX_ALLOWED __MAC_12_1 + #define __MAC_OS_X_VERSION_MAX_ALLOWED __MAC_11_3 #endif #endif /* __MAC_OS_X_VERSION_MIN_REQUIRED */ #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED /* make sure a default max version is set */ #ifndef __IPHONE_OS_VERSION_MAX_ALLOWED - #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_15_2 + #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_14_5 #endif /* make sure a valid min is set */ #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_2_0 diff --git a/lib/libc/include/any-macos.11-any/AvailabilityMacros.h b/lib/libc/include/any-macos.11-any/AvailabilityMacros.h new file mode 100644 index 0000000000..74537c5bd8 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/AvailabilityMacros.h @@ -0,0 +1,4015 @@ +/* + * Copyright (c) 2001-2010 by Apple Inc.. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + File: AvailabilityMacros.h + + More Info: See the SDK Compatibility Guide + + Contains: Autoconfiguration of AVAILABLE_ macros for Mac OS X + + This header enables a developer to specify build time + constraints on what Mac OS X versions the resulting + application will be run. There are two bounds a developer + can specify: + + MAC_OS_X_VERSION_MIN_REQUIRED + MAC_OS_X_VERSION_MAX_ALLOWED + + The lower bound controls which calls to OS functions will + be weak-importing (allowed to be unresolved at launch time). + The upper bound controls which OS functionality, if used, + will result in a compiler error because that functionality is + not available on any OS in the specifed range. + + For example, suppose an application is compiled with: + + MAC_OS_X_VERSION_MIN_REQUIRED = MAC_OS_X_VERSION_10_2 + MAC_OS_X_VERSION_MAX_ALLOWED = MAC_OS_X_VERSION_10_3 + + and an OS header contains: + + extern void funcA(void) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER; + extern void funcB(void) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2; + extern void funcC(void) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3; + extern void funcD(void) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER; + extern void funcE(void) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER; + extern void funcF(void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER; + extern void funcG(void) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; + + typedef long TypeA DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER; + typedef long TypeB DEPRECATED_IN_MAC_OS_X_VERSION_10_1_AND_LATER; + typedef long TypeC DEPRECATED_IN_MAC_OS_X_VERSION_10_2_AND_LATER; + typedef long TypeD DEPRECATED_IN_MAC_OS_X_VERSION_10_3_AND_LATER; + typedef long TypeE DEPRECATED_IN_MAC_OS_X_VERSION_10_4_AND_LATER; + + Any application code which uses these declarations will get the following: + + compile link run + ------- ------ ------- + funcA: normal normal normal + funcB: warning normal normal + funcC: normal normal normal + funcD: normal normal normal + funcE: normal normal normal + funcF: normal weak on 10.3 normal, on 10.2 (&funcF == NULL) + funcG: error error n/a + typeA: warning + typeB: warning + typeC: warning + typeD: normal + typeE: normal + + +*/ +#ifndef __AVAILABILITYMACROS__ +#define __AVAILABILITYMACROS__ + +/* + * Set up standard Mac OS X versions + */ +#define MAC_OS_X_VERSION_10_0 1000 +#define MAC_OS_X_VERSION_10_1 1010 +#define MAC_OS_X_VERSION_10_2 1020 +#define MAC_OS_X_VERSION_10_3 1030 +#define MAC_OS_X_VERSION_10_4 1040 +#define MAC_OS_X_VERSION_10_5 1050 +#define MAC_OS_X_VERSION_10_6 1060 +#define MAC_OS_X_VERSION_10_7 1070 +#define MAC_OS_X_VERSION_10_8 1080 +#define MAC_OS_X_VERSION_10_9 1090 +#define MAC_OS_X_VERSION_10_10 101000 +#define MAC_OS_X_VERSION_10_10_2 101002 +#define MAC_OS_X_VERSION_10_10_3 101003 +#define MAC_OS_X_VERSION_10_11 101100 +#define MAC_OS_X_VERSION_10_11_2 101102 +#define MAC_OS_X_VERSION_10_11_3 101103 +#define MAC_OS_X_VERSION_10_11_4 101104 +#define MAC_OS_X_VERSION_10_12 101200 +#define MAC_OS_X_VERSION_10_12_1 101201 +#define MAC_OS_X_VERSION_10_12_2 101202 +#define MAC_OS_X_VERSION_10_12_4 101204 +#define MAC_OS_X_VERSION_10_13 101300 +#define MAC_OS_X_VERSION_10_13_1 101301 +#define MAC_OS_X_VERSION_10_13_2 101302 +#define MAC_OS_X_VERSION_10_13_4 101304 +#define MAC_OS_X_VERSION_10_14 101400 +#define MAC_OS_X_VERSION_10_14_1 101401 +#define MAC_OS_X_VERSION_10_14_4 101404 +#define MAC_OS_X_VERSION_10_15 101500 +#define MAC_OS_VERSION_11_0 110000 +#define MAC_OS_VERSION_11_1 110100 +#define MAC_OS_VERSION_11_3 110300 + +/* + * If min OS not specified, assume 10.4 for intel + * Note: compiler driver may set _ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED_ based on MACOSX_DEPLOYMENT_TARGET environment variable + */ +#ifndef MAC_OS_X_VERSION_MIN_REQUIRED + #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ + #if (__i386__ || __x86_64__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < MAC_OS_X_VERSION_10_4) + #warning Building for Intel with Mac OS X Deployment Target < 10.4 is invalid. + #endif + #define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ + #else + #if __i386__ || __x86_64__ + #define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_4 + #elif __arm__ || __arm64__ + #define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_5 + #else + #define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_1 + #endif + #endif +#endif + +/* + * if max OS not specified, assume larger of (10.15, min) + */ +#ifndef MAC_OS_X_VERSION_MAX_ALLOWED + #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_VERSION_11_3 + #define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_MIN_REQUIRED + #else + #define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_VERSION_11_3 + #endif +#endif + +/* + * Error on bad values + */ +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_MIN_REQUIRED + #error MAC_OS_X_VERSION_MAX_ALLOWED must be >= MAC_OS_X_VERSION_MIN_REQUIRED +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_0 + #error MAC_OS_X_VERSION_MIN_REQUIRED must be >= MAC_OS_X_VERSION_10_0 +#endif + +/* + * only certain compilers support __attribute__((weak_import)) + */ +#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1020) + #define WEAK_IMPORT_ATTRIBUTE __attribute__((weak_import)) +#elif defined(__MWERKS__) && (__MWERKS__ >= 0x3205) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1020) && !defined(__INTEL__) + #define WEAK_IMPORT_ATTRIBUTE __attribute__((weak_import)) +#else + #define WEAK_IMPORT_ATTRIBUTE +#endif + +/* + * only certain compilers support __attribute__((deprecated)) + */ +#if defined(__has_feature) && defined(__has_attribute) + #if __has_attribute(deprecated) + #define DEPRECATED_ATTRIBUTE __attribute__((deprecated)) + #if __has_feature(attribute_deprecated_with_message) + #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated(s))) + #else + #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated)) + #endif + #else + #define DEPRECATED_ATTRIBUTE + #define DEPRECATED_MSG_ATTRIBUTE(s) + #endif +#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) + #define DEPRECATED_ATTRIBUTE __attribute__((deprecated)) + #if (__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) + #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated(s))) + #else + #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated)) + #endif +#else + #define DEPRECATED_ATTRIBUTE + #define DEPRECATED_MSG_ATTRIBUTE(s) +#endif + +/* + * only certain compilers support __attribute__((unavailable)) + */ +#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) + #define UNAVAILABLE_ATTRIBUTE __attribute__((unavailable)) +#else + #define UNAVAILABLE_ATTRIBUTE +#endif + + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER + * + * Used on functions introduced in Mac OS X 10.0 + */ +#define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED + * + * Used on functions introduced in Mac OS X 10.0, + * and deprecated in Mac OS X 10.0 + */ +#define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER + * + * Used on types deprecated in Mac OS X 10.0 + */ +#define DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER DEPRECATED_ATTRIBUTE + +#ifndef __AVAILABILITY_MACROS_USES_AVAILABILITY + #ifdef __has_attribute + #if __has_attribute(availability) + #include + #define __AVAILABILITY_MACROS_USES_AVAILABILITY 1 + #endif + #endif +#endif + +#if TARGET_OS_OSX +#define __IPHONE_COMPAT_VERSION __IPHONE_NA +#elif TARGET_OS_MACCATALYST +#define __IPHONE_COMPAT_VERSION __IPHONE_NA +#else +#define __IPHONE_COMPAT_VERSION __IPHONE_4_0 +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.1, + * and deprecated in Mac OS X 10.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_1 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_1 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.2, + * and deprecated in Mac OS X 10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.3, + * and deprecated in Mac OS X 10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.4, + * and deprecated in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.5, + * and deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.6, + * and deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.7, + * and deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_13 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.13 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY +#define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_13 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_13, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 +#define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_13 DEPRECATED_ATTRIBUTE +#else +#define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_13 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.8, + * and deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.9, + * and deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.10, + * and deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_10_2, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.10.2, + * and deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_2 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_10_3, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.10.3, + * and deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_10_3 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.11, + * and deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_11_2, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.11.2, + * and deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.11.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_11_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_2 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_11_3, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.11.3, + * and deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_3, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 + * + * Used on declarations introduced in Mac OS X 10.11.2, + * but later deprecated in Mac OS X 10.11.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_11_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_3 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_3 AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_11_4, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.11.4, + * and deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_4, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.11.2, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 + * + * Used on declarations introduced in Mac OS X 10.11.3, + * but later deprecated in Mac OS X 10.11.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_3, __MAC_10_11_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_11_4 AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.12, + * and deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.11.2, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.11.3, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_3, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 + * + * Used on declarations introduced in Mac OS X 10.11.4, + * but later deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_4, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12 AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_12_1, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.12.1, + * and deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12_1, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.11.2, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.11.3, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_3, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.11.4, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_4, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 + * + * Used on declarations introduced in Mac OS X 10.12, + * but later deprecated in Mac OS X 10.12.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_12_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_1 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_1 AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_12_2, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.12.2, + * and deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12_2, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.11.2, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.11.3, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_3, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.11.4, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_4, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.12, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 + * + * Used on declarations introduced in Mac OS X 10.12.1, + * but later deprecated in Mac OS X 10.12.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12_1, __MAC_10_12_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_2 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_2 AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_12_4, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER_BUT_DEPRECATED + * + * Used on declarations introduced in Mac OS X 10.12.4, + * and deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER_BUT_DEPRECATED __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12_4, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER_BUT_DEPRECATED DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER_BUT_DEPRECATED AVAILABLE_MAC_OS_X_VERSION_10_12_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.0, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.1, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.2, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.3, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.4, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.5, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.6, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.7, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.8, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_8, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.9, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_9, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.10, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.10.2, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_2, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_10_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.10.3, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10_3, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_10_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.11, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.11.2, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_2, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_11_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.11.3, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_3, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_11_3_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.11.4, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_11_4, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_11_4_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.12, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.12.1, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12_1, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_12_1_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 + * + * Used on declarations introduced in Mac OS X 10.12.2, + * but later deprecated in Mac OS X 10.12.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12_2, __MAC_10_12_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12_4 + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 DEPRECATED_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_12_4 AVAILABLE_MAC_OS_X_VERSION_10_12_2_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.13 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13 + #define AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_13 + #define AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_14_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.14 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_14_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_14, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_14 + #define AVAILABLE_MAC_OS_X_VERSION_10_14_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_14 + #define AVAILABLE_MAC_OS_X_VERSION_10_14_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_14_AND_LATER +#endif + +/* + * AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER + * + * Used on declarations introduced in Mac OS X 10.15 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER __OSX_AVAILABLE_STARTING(__MAC_10_15, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_15 + #define AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER UNAVAILABLE_ATTRIBUTE +#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_15 + #define AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER WEAK_IMPORT_ATTRIBUTE +#else + #define AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_1_AND_LATER + * + * Used on types deprecated in Mac OS X 10.1 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_1_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_1, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_1 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_1_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_1_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_2_AND_LATER + * + * Used on types deprecated in Mac OS X 10.2 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_2_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_2, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_2_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_2_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_3_AND_LATER + * + * Used on types deprecated in Mac OS X 10.3 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_3_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_3, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_3_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_3_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_4_AND_LATER + * + * Used on types deprecated in Mac OS X 10.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_4_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_4_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_4_AND_LATER +#endif + + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER + * + * Used on types deprecated in Mac OS X 10.5 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_5, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_6_AND_LATER + * + * Used on types deprecated in Mac OS X 10.6 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_6_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_6_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_6_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER + * + * Used on types deprecated in Mac OS X 10.7 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_7, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER + * + * Used on types deprecated in Mac OS X 10.8 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_8, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_8_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_9_AND_LATER + * + * Used on types deprecated in Mac OS X 10.9 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_9_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_9, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_9_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_9_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_10_AND_LATER + * + * Used on types deprecated in Mac OS X 10.10 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_10_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_10, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_10_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_10_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_11_AND_LATER + * + * Used on types deprecated in Mac OS X 10.11 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_11_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_11, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_11_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_11_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_12_AND_LATER + * + * Used on types deprecated in Mac OS X 10.12 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_12_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_12, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_12_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_12_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_13_AND_LATER + * + * Used on types deprecated in Mac OS X 10.13 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_13_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_13, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_13_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_13_AND_LATER +#endif + +/* + * DEPRECATED_IN_MAC_OS_X_VERSION_10_14_4_AND_LATER + * + * Used on types deprecated in Mac OS X 10.14.4 + */ +#if __AVAILABILITY_MACROS_USES_AVAILABILITY + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_14_4_AND_LATER __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_14_4, __IPHONE_COMPAT_VERSION, __IPHONE_COMPAT_VERSION) +#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14_4 + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_14_4_AND_LATER DEPRECATED_ATTRIBUTE +#else + #define DEPRECATED_IN_MAC_OS_X_VERSION_10_14_4_AND_LATER +#endif + +#endif /* __AVAILABILITYMACROS__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/AvailabilityVersions.h b/lib/libc/include/any-macos.11-any/AvailabilityVersions.h index ed0bdfc91e..591e541d7f 100644 --- a/lib/libc/include/any-macos.11-any/AvailabilityVersions.h +++ b/lib/libc/include/any-macos.11-any/AvailabilityVersions.h @@ -60,11 +60,6 @@ #define __MAC_11_0 110000 #define __MAC_11_1 110100 #define __MAC_11_3 110300 -#define __MAC_11_4 110400 -#define __MAC_11_5 110500 -#define __MAC_11_6 110600 -#define __MAC_12_0 120000 -#define __MAC_12_1 120100 /* __MAC_NA is not defined to a value but is used as a token by macros to indicate that the API is unavailable */ #define __IPHONE_2_0 20000 @@ -119,12 +114,6 @@ #define __IPHONE_14_2 140200 #define __IPHONE_14_3 140300 #define __IPHONE_14_5 140500 -#define __IPHONE_14_6 140600 -#define __IPHONE_14_7 140700 -#define __IPHONE_14_8 140800 -#define __IPHONE_15_0 150000 -#define __IPHONE_15_1 150100 -#define __IPHONE_15_2 150200 /* __IPHONE_NA is not defined to a value but is used as a token by macros to indicate that the API is unavailable */ #define __TVOS_9_0 90000 @@ -153,11 +142,6 @@ #define __TVOS_14_2 140200 #define __TVOS_14_3 140300 #define __TVOS_14_5 140500 -#define __TVOS_14_6 140600 -#define __TVOS_14_7 140700 -#define __TVOS_15_0 150000 -#define __TVOS_15_1 150100 -#define __TVOS_15_2 150200 #define __WATCHOS_1_0 10000 #define __WATCHOS_2_0 20000 @@ -183,12 +167,6 @@ #define __WATCHOS_7_2 70200 #define __WATCHOS_7_3 70300 #define __WATCHOS_7_4 70400 -#define __WATCHOS_7_5 70500 -#define __WATCHOS_7_6 70600 -#define __WATCHOS_8_0 80000 -#define __WATCHOS_8_1 80100 -#define __WATCHOS_8_3 80300 - /* * Set up standard Mac OS X versions @@ -229,12 +207,10 @@ #define MAC_OS_X_VERSION_10_15_1 101501 #define MAC_OS_X_VERSION_10_16 101600 #define MAC_OS_VERSION_11_0 110000 -#define MAC_OS_VERSION_12_0 120000 #endif /* #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) */ #define __DRIVERKIT_19_0 190000 #define __DRIVERKIT_20_0 200000 -#define __DRIVERKIT_21_0 210000 #endif /* __AVAILABILITY_VERSIONS__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/TargetConditionals.h b/lib/libc/include/any-macos.11-any/TargetConditionals.h index 677604297d..e0a993f0ec 100644 --- a/lib/libc/include/any-macos.11-any/TargetConditionals.h +++ b/lib/libc/include/any-macos.11-any/TargetConditionals.h @@ -61,10 +61,8 @@ * The IOS/TV/WATCH conditionals are mutually exclusive. * * - * TARGET_OS_WIN32 - Generated code will run under WIN32 API - * TARGET_OS_WINDOWS - Generated code will run under Windows + * TARGET_OS_WIN32 - Generated code will run under 32-bit Windows * TARGET_OS_UNIX - Generated code will run under some Unix (not OSX) - * TARGET_OS_LINUX - Generated code will run under Linux * TARGET_OS_MAC - Generated code will run under Mac OS X variant * TARGET_OS_OSX - Generated code will run under OS X devices * TARGET_OS_IPHONE - Generated code for firmware, devices, or simulator @@ -180,7 +178,7 @@ /* -target=x86_64-apple-driverkit19.0 */ /* -target=arm64-apple-driverkit19.0 */ /* -target=arm64e-apple-driverkit19.0 */ - #if __is_target_vendor(apple) && __is_target_os(driverkit) + #if (__is_target_arch(x86_64) || __is_target_arch(arm64) || __is_target_arch(arm64e)) && __is_target_vendor(apple) && __is_target_os(driverkit) #define TARGET_OS_OSX 0 #define TARGET_OS_IPHONE 0 #define TARGET_OS_IOS 0 @@ -216,9 +214,7 @@ #if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) ) #define TARGET_OS_MAC 1 #define TARGET_OS_WIN32 0 - #define TARGET_OS_WINDOWS 0 #define TARGET_OS_UNIX 0 - #define TARGET_OS_LINUX 0 #if !DYNAMIC_TARGETS_ENABLED #define TARGET_OS_OSX 1 @@ -359,9 +355,7 @@ #elif defined(__MWERKS__) #define TARGET_OS_MAC 1 #define TARGET_OS_WIN32 0 - #define TARGET_OS_WINDOWS 0 #define TARGET_OS_UNIX 0 - #define TARGET_OS_LINUX 0 #define TARGET_OS_EMBEDDED 0 #if defined(__POWERPC__) #define TARGET_CPU_PPC 1 @@ -487,9 +481,7 @@ #endif #define TARGET_OS_MAC 1 #define TARGET_OS_WIN32 0 - #define TARGET_OS_WINDOWS 0 #define TARGET_OS_UNIX 0 - #define TARGET_OS_LINUX 0 #define TARGET_OS_EMBEDDED 0 #if TARGET_CPU_PPC || TARGET_CPU_PPC64 #define TARGET_RT_BIG_ENDIAN 1 diff --git a/lib/libc/include/any-macos.11-any/assert.h b/lib/libc/include/any-macos.11-any/assert.h new file mode 100644 index 0000000000..e08d52cb28 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/assert.h @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)assert.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: src/include/assert.h,v 1.4 2002/03/23 17:24:53 imp Exp $ + */ + +#include +#ifdef __cplusplus +#include +#endif /* __cplusplus */ + +/* + * Unlike other ANSI header files, may usefully be included + * multiple times, with and without NDEBUG defined. + */ + +#undef assert +#undef __assert + +#ifdef NDEBUG +#define assert(e) ((void)0) +#else + +#ifndef __GNUC__ + +__BEGIN_DECLS +#ifndef __cplusplus +void abort(void) __dead2 __cold; +#endif /* !__cplusplus */ +int printf(const char * __restrict, ...); +__END_DECLS + +#define assert(e) \ + ((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__))) +#define __assert(e, file, line) \ + ((void)printf ("%s:%d: failed assertion `%s'\n", file, line, e), abort()) + +#else /* __GNUC__ */ + +__BEGIN_DECLS +void __assert_rtn(const char *, const char *, int, const char *) __dead2 __cold __disable_tail_calls; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070) +void __eprintf(const char *, const char *, unsigned, const char *) __dead2 __cold; +#endif +__END_DECLS + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070) +#define __assert(e, file, line) \ + __eprintf ("%s:%d: failed assertion `%s'\n", file, line, e) +#else +/* 8462256: modified __assert_rtn() replaces deprecated __eprintf() */ +#define __assert(e, file, line) \ + __assert_rtn ((const char *)-1L, file, line, e) +#endif + +#if __DARWIN_UNIX03 +#define assert(e) \ + (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0) +#else /* !__DARWIN_UNIX03 */ +#define assert(e) \ + (__builtin_expect(!(e), 0) ? __assert (#e, __FILE__, __LINE__) : (void)0) +#endif /* __DARWIN_UNIX03 */ + +#endif /* __GNUC__ */ +#endif /* NDEBUG */ + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifndef __cplusplus +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define static_assert _Static_assert +#endif /* __STDC_VERSION__ */ +#endif /* !__cplusplus */ + +#endif /* _ASSERT_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/device/device_types.h b/lib/libc/include/any-macos.11-any/device/device_types.h new file mode 100644 index 0000000000..2878666853 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/device/device_types.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Author: David B. Golub, Carnegie Mellon University + * Date: 3/89 + */ + +#ifndef DEVICE_TYPES_H +#define DEVICE_TYPES_H + +/* + * Types for device interface. + */ +#include +#include +#include +#include + + + +/* + * IO buffer - out-of-line array of characters. + */ +typedef char * io_buf_ptr_t; + +/* + * Some types for IOKit. + */ + +#ifdef IOKIT + +/* must match device_types.defs */ +typedef char io_name_t[128]; +typedef char io_string_t[512]; +typedef char io_string_inband_t[4096]; +typedef char io_struct_inband_t[4096]; + +#if __LP64__ +typedef uint64_t io_user_scalar_t; +typedef uint64_t io_user_reference_t; +typedef io_user_scalar_t io_scalar_inband_t[16]; +typedef io_user_reference_t io_async_ref_t[8]; +typedef io_user_scalar_t io_scalar_inband64_t[16]; +typedef io_user_reference_t io_async_ref64_t[8]; +#else +typedef int io_user_scalar_t; +typedef natural_t io_user_reference_t; +typedef io_user_scalar_t io_scalar_inband_t[16]; +typedef io_user_reference_t io_async_ref_t[8]; +typedef uint64_t io_scalar_inband64_t[16]; +typedef uint64_t io_async_ref64_t[8]; +#endif // __LP64__ + + +#ifndef __IOKIT_PORTS_DEFINED__ +#define __IOKIT_PORTS_DEFINED__ +typedef mach_port_t io_object_t; +#endif /* __IOKIT_PORTS_DEFINED__ */ + + +#endif /* IOKIT */ + +#endif /* DEVICE_TYPES_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/dispatch/base.h b/lib/libc/include/any-macos.11-any/dispatch/base.h new file mode 100644 index 0000000000..86ed15d144 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/dispatch/base.h @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __DISPATCH_BASE__ +#define __DISPATCH_BASE__ + +#ifndef __DISPATCH_INDIRECT__ +#error "Please #include instead of this file directly." +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif +#ifndef __has_include +#define __has_include(x) 0 +#endif +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif +#ifndef __has_extension +#define __has_extension(x) 0 +#endif + +#if __GNUC__ +#define DISPATCH_NORETURN __attribute__((__noreturn__)) +#define DISPATCH_NOTHROW __attribute__((__nothrow__)) +#define DISPATCH_NONNULL1 __attribute__((__nonnull__(1))) +#define DISPATCH_NONNULL2 __attribute__((__nonnull__(2))) +#define DISPATCH_NONNULL3 __attribute__((__nonnull__(3))) +#define DISPATCH_NONNULL4 __attribute__((__nonnull__(4))) +#define DISPATCH_NONNULL5 __attribute__((__nonnull__(5))) +#define DISPATCH_NONNULL6 __attribute__((__nonnull__(6))) +#define DISPATCH_NONNULL7 __attribute__((__nonnull__(7))) +#if __clang__ && __clang_major__ < 3 +// rdar://problem/6857843 +#define DISPATCH_NONNULL_ALL +#else +#define DISPATCH_NONNULL_ALL __attribute__((__nonnull__)) +#endif +#define DISPATCH_SENTINEL __attribute__((__sentinel__)) +#define DISPATCH_PURE __attribute__((__pure__)) +#define DISPATCH_CONST __attribute__((__const__)) +#define DISPATCH_WARN_RESULT __attribute__((__warn_unused_result__)) +#define DISPATCH_MALLOC __attribute__((__malloc__)) +#define DISPATCH_ALWAYS_INLINE __attribute__((__always_inline__)) +#define DISPATCH_UNAVAILABLE __attribute__((__unavailable__)) +#define DISPATCH_UNAVAILABLE_MSG(msg) __attribute__((__unavailable__(msg))) +#elif defined(_MSC_VER) +#define DISPATCH_NORETURN __declspec(noreturn) +#define DISPATCH_NOTHROW __declspec(nothrow) +#define DISPATCH_NONNULL1 +#define DISPATCH_NONNULL2 +#define DISPATCH_NONNULL3 +#define DISPATCH_NONNULL4 +#define DISPATCH_NONNULL5 +#define DISPATCH_NONNULL6 +#define DISPATCH_NONNULL7 +#define DISPATCH_NONNULL_ALL +#define DISPATCH_SENTINEL +#define DISPATCH_PURE +#define DISPATCH_CONST +#if (_MSC_VER >= 1700) +#define DISPATCH_WARN_RESULT _Check_return_ +#else +#define DISPATCH_WARN_RESULT +#endif +#define DISPATCH_MALLOC +#define DISPATCH_ALWAYS_INLINE __forceinline +#define DISPATCH_UNAVAILABLE +#define DISPATCH_UNAVAILABLE_MSG(msg) +#else +/*! @parseOnly */ +#define DISPATCH_NORETURN +/*! @parseOnly */ +#define DISPATCH_NOTHROW +/*! @parseOnly */ +#define DISPATCH_NONNULL1 +/*! @parseOnly */ +#define DISPATCH_NONNULL2 +/*! @parseOnly */ +#define DISPATCH_NONNULL3 +/*! @parseOnly */ +#define DISPATCH_NONNULL4 +/*! @parseOnly */ +#define DISPATCH_NONNULL5 +/*! @parseOnly */ +#define DISPATCH_NONNULL6 +/*! @parseOnly */ +#define DISPATCH_NONNULL7 +/*! @parseOnly */ +#define DISPATCH_NONNULL_ALL +/*! @parseOnly */ +#define DISPATCH_SENTINEL +/*! @parseOnly */ +#define DISPATCH_PURE +/*! @parseOnly */ +#define DISPATCH_CONST +/*! @parseOnly */ +#define DISPATCH_WARN_RESULT +/*! @parseOnly */ +#define DISPATCH_MALLOC +/*! @parseOnly */ +#define DISPATCH_ALWAYS_INLINE +/*! @parseOnly */ +#define DISPATCH_UNAVAILABLE +/*! @parseOnly */ +#define DISPATCH_UNAVAILABLE_MSG(msg) +#endif + +#define DISPATCH_LINUX_UNAVAILABLE() + +#ifdef __FreeBSD__ +#define DISPATCH_FREEBSD_UNAVAILABLE() \ + DISPATCH_UNAVAILABLE_MSG( \ + "This interface is unavailable on FreeBSD systems") +#else +#define DISPATCH_FREEBSD_UNAVAILABLE() +#endif + +#ifndef DISPATCH_ALIAS_V2 +#if TARGET_OS_MAC +#define DISPATCH_ALIAS_V2(sym) __asm__("_" #sym "$V2") +#else +#define DISPATCH_ALIAS_V2(sym) +#endif +#endif + +#if defined(_WIN32) +#if defined(__cplusplus) +#define DISPATCH_EXPORT extern "C" __declspec(dllimport) +#else +#define DISPATCH_EXPORT extern __declspec(dllimport) +#endif +#elif __GNUC__ +#define DISPATCH_EXPORT extern __attribute__((visibility("default"))) +#else +#define DISPATCH_EXPORT extern +#endif + +#if __GNUC__ +#define DISPATCH_INLINE static __inline__ +#else +#define DISPATCH_INLINE static inline +#endif + +#if __GNUC__ +#define DISPATCH_EXPECT(x, v) __builtin_expect((x), (v)) +#define dispatch_compiler_barrier() __asm__ __volatile__("" ::: "memory") +#else +#define DISPATCH_EXPECT(x, v) (x) +#define dispatch_compiler_barrier() do { } while (0) +#endif + +#if __has_attribute(not_tail_called) +#define DISPATCH_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) +#else +#define DISPATCH_NOT_TAIL_CALLED +#endif + +#if __has_builtin(__builtin_assume) +#define DISPATCH_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr) +#else +#define DISPATCH_COMPILER_CAN_ASSUME(expr) ((void)(expr)) +#endif + +#if __has_attribute(noescape) +#define DISPATCH_NOESCAPE __attribute__((__noescape__)) +#else +#define DISPATCH_NOESCAPE +#endif + +#if __has_attribute(cold) +#define DISPATCH_COLD __attribute__((__cold__)) +#else +#define DISPATCH_COLD +#endif + +#if __has_feature(assume_nonnull) +#define DISPATCH_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +#define DISPATCH_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +#else +#define DISPATCH_ASSUME_NONNULL_BEGIN +#define DISPATCH_ASSUME_NONNULL_END +#endif + +#if !__has_feature(nullability) +#ifndef _Nullable +#define _Nullable +#endif +#ifndef _Nonnull +#define _Nonnull +#endif +#ifndef _Null_unspecified +#define _Null_unspecified +#endif +#endif + +#ifndef DISPATCH_RETURNS_RETAINED_BLOCK +#if __has_attribute(ns_returns_retained) +#define DISPATCH_RETURNS_RETAINED_BLOCK __attribute__((__ns_returns_retained__)) +#else +#define DISPATCH_RETURNS_RETAINED_BLOCK +#endif +#endif + +#if __has_attribute(enum_extensibility) +#define __DISPATCH_ENUM_ATTR __attribute__((__enum_extensibility__(open))) +#define __DISPATCH_ENUM_ATTR_CLOSED __attribute__((__enum_extensibility__(closed))) +#else +#define __DISPATCH_ENUM_ATTR +#define __DISPATCH_ENUM_ATTR_CLOSED +#endif // __has_attribute(enum_extensibility) + +#if __has_attribute(flag_enum) +#define __DISPATCH_OPTIONS_ATTR __attribute__((__flag_enum__)) +#else +#define __DISPATCH_OPTIONS_ATTR +#endif // __has_attribute(flag_enum) + + +#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) || \ + __has_extension(cxx_fixed_enum) || defined(_WIN32) +#define DISPATCH_ENUM(name, type, ...) \ + typedef enum : type { __VA_ARGS__ } __DISPATCH_ENUM_ATTR name##_t +#define DISPATCH_OPTIONS(name, type, ...) \ + typedef enum : type { __VA_ARGS__ } __DISPATCH_OPTIONS_ATTR __DISPATCH_ENUM_ATTR name##_t +#else +#define DISPATCH_ENUM(name, type, ...) \ + enum { __VA_ARGS__ } __DISPATCH_ENUM_ATTR; typedef type name##_t +#define DISPATCH_OPTIONS(name, type, ...) \ + enum { __VA_ARGS__ } __DISPATCH_OPTIONS_ATTR __DISPATCH_ENUM_ATTR; typedef type name##_t +#endif // __has_feature(objc_fixed_enum) ... + + + +#if __has_feature(enumerator_attributes) +#define DISPATCH_ENUM_API_AVAILABLE(...) API_AVAILABLE(__VA_ARGS__) +#define DISPATCH_ENUM_API_DEPRECATED(...) API_DEPRECATED(__VA_ARGS__) +#define DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT(...) \ + API_DEPRECATED_WITH_REPLACEMENT(__VA_ARGS__) +#else +#define DISPATCH_ENUM_API_AVAILABLE(...) +#define DISPATCH_ENUM_API_DEPRECATED(...) +#define DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT(...) +#endif + +#ifdef __swift__ +#define DISPATCH_SWIFT3_OVERLAY 1 +#else // __swift__ +#define DISPATCH_SWIFT3_OVERLAY 0 +#endif // __swift__ + +#if __has_feature(attribute_availability_swift) +#define DISPATCH_SWIFT_UNAVAILABLE(_msg) \ + __attribute__((__availability__(swift, unavailable, message=_msg))) +#else +#define DISPATCH_SWIFT_UNAVAILABLE(_msg) +#endif + +#if DISPATCH_SWIFT3_OVERLAY +#define DISPATCH_SWIFT3_UNAVAILABLE(_msg) DISPATCH_SWIFT_UNAVAILABLE(_msg) +#else +#define DISPATCH_SWIFT3_UNAVAILABLE(_msg) +#endif + +#if __has_attribute(swift_private) +#define DISPATCH_REFINED_FOR_SWIFT __attribute__((__swift_private__)) +#else +#define DISPATCH_REFINED_FOR_SWIFT +#endif + +#if __has_attribute(swift_name) +#define DISPATCH_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) +#else +#define DISPATCH_SWIFT_NAME(_name) +#endif + +#ifndef __cplusplus +#define DISPATCH_TRANSPARENT_UNION __attribute__((__transparent_union__)) +#else +#define DISPATCH_TRANSPARENT_UNION +#endif + +typedef void (*dispatch_function_t)(void *_Nullable); + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/dispatch/queue.h b/lib/libc/include/any-macos.11-any/dispatch/queue.h index 8d08a30458..f4f8ab673e 100644 --- a/lib/libc/include/any-macos.11-any/dispatch/queue.h +++ b/lib/libc/include/any-macos.11-any/dispatch/queue.h @@ -480,7 +480,7 @@ DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW void dispatch_apply(size_t iterations, dispatch_queue_t DISPATCH_APPLY_QUEUE_ARG_NULLABILITY queue, - DISPATCH_NOESCAPE void (^block)(size_t iteration)); + DISPATCH_NOESCAPE void (^block)(size_t)); #endif /*! @@ -515,7 +515,7 @@ DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_NOTHROW void dispatch_apply_f(size_t iterations, dispatch_queue_t DISPATCH_APPLY_QUEUE_ARG_NULLABILITY queue, - void *_Nullable context, void (*work)(void *_Nullable context, size_t iteration)); + void *_Nullable context, void (*work)(void *_Nullable, size_t)); /*! * @function dispatch_get_current_queue diff --git a/lib/libc/include/any-macos.11-any/execinfo.h b/lib/libc/include/any-macos.11-any/execinfo.h new file mode 100644 index 0000000000..65d9d20486 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/execinfo.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef _EXECINFO_H_ +#define _EXECINFO_H_ 1 + +#include +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +int backtrace(void**,int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +API_AVAILABLE(macosx(10.14), ios(12.0), tvos(12.0), watchos(5.0)) +OS_EXPORT +int backtrace_from_fp(void *startfp, void **array, int size); + +char** backtrace_symbols(void* const*,int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +void backtrace_symbols_fd(void* const*,int,int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +struct image_offset { + /* + * The UUID of the image. + */ + uuid_t uuid; + + /* + * The offset is relative to the __TEXT section of the image. + */ + uint32_t offset; +}; + +API_AVAILABLE(macosx(10.14), ios(12.0), tvos(12.0), watchos(5.0)) +OS_EXPORT +void backtrace_image_offsets(void* const* array, + struct image_offset *image_offsets, int size); + +__END_DECLS + +#endif /* !_EXECINFO_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/gethostuuid.h b/lib/libc/include/any-macos.11-any/gethostuuid.h new file mode 100644 index 0000000000..cc7f473118 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/gethostuuid.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef __GETHOSTUUID_H +#define __GETHOSTUUID_H + +#include +#include +#include + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0) +int gethostuuid(uuid_t, const struct timespec *) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0, "gethostuuid() is no longer supported"); +#else +int gethostuuid(uuid_t, const struct timespec *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); +#endif + +#endif /* __GETHOSTUUID_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/libkern/OSDebug.h b/lib/libc/include/any-macos.11-any/libkern/OSDebug.h new file mode 100644 index 0000000000..a465b46326 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/libkern/OSDebug.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * HISTORY + * + */ + +#ifndef _OS_OSDEBBUG_H +#define _OS_OSDEBBUG_H + +#include +#include + +__BEGIN_DECLS + +extern int log_leaks; + +/* Use kernel_debug() to log a backtrace */ +extern void trace_backtrace(unsigned int debugid, unsigned int debugid2, unsigned long size, unsigned long data); +/* Report a message with a 4 entry backtrace - very slow */ +extern void OSReportWithBacktrace(const char *str, ...); +extern unsigned OSBacktrace(void **bt, unsigned maxAddrs); + +/* Simple dump of 20 backtrace entries */ +extern void OSPrintBacktrace(void); + +/*! @function OSKernelStackRemaining + * @abstract Returns bytes available below the current stack frame. + * @discussion Returns bytes available below the current stack frame. Safe for interrupt or thread context. + * @result Approximate byte count available. */ + +vm_offset_t OSKernelStackRemaining( void ); + +__END_DECLS + +#define TRACE_MACHLEAKS(a, b, c, d) \ +do { \ + if (__builtin_expect(!!log_leaks, 0)) \ + trace_backtrace(a,b,c,d); \ +} while(0) + +#endif /* !_OS_OSDEBBUG_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/libkern/OSKextLib.h b/lib/libc/include/any-macos.11-any/libkern/OSKextLib.h new file mode 100644 index 0000000000..7b2e1c2da2 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/libkern/OSKextLib.h @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _LIBKERN_OSKEXTLIB_H +#define _LIBKERN_OSKEXTLIB_H + +#include +__BEGIN_DECLS + +#include +#include +#include +#include + +#include +#include + +/*! + * @header + * + * Declares functions, basic return values, and other constants + * related to kernel extensions (kexts). + */ + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark OSReturn Values for Kernel Extensions +/********************************************************************/ +#endif +/*! + * @group OSReturn Values for Kernel Extensions + * Many kext-related functions return these values, + * as well as those defined under + * @link //apple_ref/c/tdef/OSReturn OSReturn@/link + * and other variants of kern_return_t. + */ + + +#define sub_libkern_kext err_sub(2) +#define libkern_kext_err(code) (sys_libkern|sub_libkern_kext|(code)) + + +/*! + * @define kOSKextReturnInternalError + * @abstract An internal error in the kext library. + * Contrast with @link //apple_ref/c/econst/OSReturnError + * OSReturnError@/link. + */ +#define kOSKextReturnInternalError libkern_kext_err(0x1) + +/*! + * @define kOSKextReturnNoMemory + * @abstract Memory allocation failed. + */ +#define kOSKextReturnNoMemory libkern_kext_err(0x2) + +/*! + * @define kOSKextReturnNoResources + * @abstract Some resource other than memory (such as available load tags) + * is exhausted. + */ +#define kOSKextReturnNoResources libkern_kext_err(0x3) + +/*! + * @define kOSKextReturnNotPrivileged + * @abstract The caller lacks privileges to perform the requested operation. + */ +#define kOSKextReturnNotPrivileged libkern_kext_err(0x4) + +/*! + * @define kOSKextReturnInvalidArgument + * @abstract Invalid argument. + */ +#define kOSKextReturnInvalidArgument libkern_kext_err(0x5) + +/*! + * @define kOSKextReturnNotFound + * @abstract Search item not found. + */ +#define kOSKextReturnNotFound libkern_kext_err(0x6) + +/*! + * @define kOSKextReturnBadData + * @abstract Malformed data (not used for XML). + */ +#define kOSKextReturnBadData libkern_kext_err(0x7) + +/*! + * @define kOSKextReturnSerialization + * @abstract Error converting or (un)serializing URL, string, or XML. + */ +#define kOSKextReturnSerialization libkern_kext_err(0x8) + +/*! + * @define kOSKextReturnUnsupported + * @abstract Operation is no longer or not yet supported. + */ +#define kOSKextReturnUnsupported libkern_kext_err(0x9) + +/*! + * @define kOSKextReturnDisabled + * @abstract Operation is currently disabled. + */ +#define kOSKextReturnDisabled libkern_kext_err(0xa) + +/*! + * @define kOSKextReturnNotAKext + * @abstract Bundle is not a kernel extension. + */ +#define kOSKextReturnNotAKext libkern_kext_err(0xb) + +/*! + * @define kOSKextReturnValidation + * @abstract Validation failures encountered; check diagnostics for details. + */ +#define kOSKextReturnValidation libkern_kext_err(0xc) + +/*! + * @define kOSKextReturnAuthentication + * @abstract Authetication failures encountered; check diagnostics for details. + */ +#define kOSKextReturnAuthentication libkern_kext_err(0xd) + +/*! + * @define kOSKextReturnDependencies + * @abstract Dependency resolution failures encountered; check diagnostics for details. + */ +#define kOSKextReturnDependencies libkern_kext_err(0xe) + +/*! + * @define kOSKextReturnArchNotFound + * @abstract Kext does not contain code for the requested architecture. + */ +#define kOSKextReturnArchNotFound libkern_kext_err(0xf) + +/*! + * @define kOSKextReturnCache + * @abstract An error occurred processing a system kext cache. + */ +#define kOSKextReturnCache libkern_kext_err(0x10) + +/*! + * @define kOSKextReturnDeferred + * @abstract Operation has been posted asynchronously to user space (kernel only). + */ +#define kOSKextReturnDeferred libkern_kext_err(0x11) + +/*! + * @define kOSKextReturnBootLevel + * @abstract Kext not loadable or operation not allowed at current boot level. + */ +#define kOSKextReturnBootLevel libkern_kext_err(0x12) + +/*! + * @define kOSKextReturnNotLoadable + * @abstract Kext cannot be loaded; check diagnostics for details. + */ +#define kOSKextReturnNotLoadable libkern_kext_err(0x13) + +/*! + * @define kOSKextReturnLoadedVersionDiffers + * @abstract A different version (or executable UUID, or executable by checksum) + * of the requested kext is already loaded. + */ +#define kOSKextReturnLoadedVersionDiffers libkern_kext_err(0x14) + +/*! + * @define kOSKextReturnDependencyLoadError + * @abstract A load error occurred on a dependency of the kext being loaded. + */ +#define kOSKextReturnDependencyLoadError libkern_kext_err(0x15) + +/*! + * @define kOSKextReturnLinkError + * @abstract A link failure occured with this kext or a dependency. + */ +#define kOSKextReturnLinkError libkern_kext_err(0x16) + +/*! + * @define kOSKextReturnStartStopError + * @abstract The kext start or stop routine returned an error. + */ +#define kOSKextReturnStartStopError libkern_kext_err(0x17) + +/*! + * @define kOSKextReturnInUse + * @abstract The kext is currently in use or has outstanding references, + * and cannot be unloaded. + */ +#define kOSKextReturnInUse libkern_kext_err(0x18) + +/*! + * @define kOSKextReturnTimeout + * @abstract A kext request has timed out. + */ +#define kOSKextReturnTimeout libkern_kext_err(0x19) + +/*! + * @define kOSKextReturnStopping + * @abstract The kext is in the process of stopping; requests cannot be made. + */ +#define kOSKextReturnStopping libkern_kext_err(0x1a) + +/*! + * @define kOSKextReturnSystemPolicy + * @abstract The kext was prevented from loading due to system policy. + */ +#define kOSKextReturnSystemPolicy libkern_kext_err(0x1b) + +/*! + * @define kOSKextReturnKCLoadFailure + * @abstract Loading of the System KC failed + */ +#define kOSKextReturnKCLoadFailure libkern_kext_err(0x1c) + +/*! + * @define kOSKextReturnKCLoadFailureSystemKC + * @abstract Loading of the System KC failed + * + * This a sub-code of kOSKextReturnKCLoadFailure. It can be OR'd together + * with: kOSKextReturnKCLoadFailureAuxKC + * + * If both the System and Aux KCs fail to load, then the error code will be: + * libkern_kext_err(0x1f) + */ +#define kOSKextReturnKCLoadFailureSystemKC libkern_kext_err(0x1d) + +/*! + * @define kOSKextReturnKCLoadFailureAuxKC + * @abstract Loading of the Aux KC failed + * + * This a sub-code of kOSKextReturnKCLoadFailure. It can be OR'd together + * with: kOSKextReturnKCLoadFailureSystemKC + * + * If both the System and Aux KCs fail to load, then the error code will be: + * libkern_kext_err(0x1f) + */ +#define kOSKextReturnKCLoadFailureAuxKC libkern_kext_err(0x1e) + +/* next available error is: libkern_kext_err(0x20) */ + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark Kext/OSBundle Property List Keys +/********************************************************************/ +#endif +/*! + * @group Kext Property List Keys + * These constants cover CFBundle properties defined for kernel extensions. + * Because they are used in the kernel, if you want to use one with + * CFBundle APIs you'll need to wrap it in a CFSTR() macro. + */ + + +/*! + * @define kOSBundleCompatibleVersionKey + * @abstract A string giving the backwards-compatible version of a library kext + * in extended Mac OS 'vers' format (####.##.##s{1-255} where 's' + * is a build stage 'd', 'a', 'b', 'f' or 'fc'). + */ +#define kOSBundleCompatibleVersionKey "OSBundleCompatibleVersion" + +/*! + * @define kOSBundleEnableKextLoggingKey + * @abstract Set to true to have the kernel kext logging spec applied + * to the kext. + * See @link //apple_ref/c/econst/OSKextLogSpec + * OSKextLogSpec@/link. + */ +#define kOSBundleEnableKextLoggingKey "OSBundleEnableKextLogging" + +/*! + * @define kOSBundleIsInterfaceKey + * @abstract A boolean value indicating whether the kext executable + * contains only symbol references. + */ +#define kOSBundleIsInterfaceKey "OSBundleIsInterface" + +/*! + * @define kOSBundleLibrariesKey + * @abstract A dictionary listing link dependencies for this kext. + * Keys are bundle identifiers, values are version strings. + */ +#define kOSBundleLibrariesKey "OSBundleLibraries" + +/*! + * @define kOSBundleRequiredKey + * @abstract A string indicating in which kinds of startup this kext + * may need to load during early startup (before + * @link //apple_ref/doc/man/8/kextd kextcache(8)@/link). + * @discussion + * The value is one of: + *
    + *
  • @link kOSBundleRequiredRoot "OSBundleRequiredRoot"@/link
  • + *
  • @link kOSBundleRequiredLocalRoot "OSBundleRequiredLocalRoot"@/link
  • + *
  • @link kOSBundleRequiredNetworkRoot "OSBundleRequiredNetworkRoot"@/link
  • + *
  • @link kOSBundleRequiredSafeBoot "OSBundleRequiredSafeBoot"@/link
  • + *
  • @link kOSBundleRequiredConsole "OSBundleRequiredConsole"@/link
  • + *
+ * + * Use this property judiciously. + * Every kext that declares a value other than "OSBundleRequiredSafeBoot" + * increases startup time, as the booter must read it into memory, + * or startup kext caches must include it. + */ +#define kOSBundleRequiredKey "OSBundleRequired" + +/*! + * @define kOSBundleRequireExplicitLoadKey + * @abstract A boolean value indicating whether the kext requires an + * explicit kextload in order to start/match. + */ +#define kOSBundleRequireExplicitLoadKey "OSBundleRequireExplicitLoad" + +/*! + * @define kOSBundleAllowUserLoadKey + * @abstract A boolean value indicating whether + * @link //apple_ref/doc/man/8/kextd kextcache(8)@/link + * will honor a non-root process's request to load a kext. + * @discussion + * See @link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithURL + * KextManagerLoadKextWithURL@/link + * and @link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithIdentifier + * KextManagerLoadKextWithIdentifier@/link. + */ +#define kOSBundleAllowUserLoadKey "OSBundleAllowUserLoad" + +/*! + * @define kOSBundleAllowUserTerminateKey + * @abstract A boolean value indicating whether the kextunload tool + * is allowed to issue IOService terminate to classes defined in this kext. + * @discussion A boolean value indicating whether the kextunload tool + * is allowed to issue IOService terminate to classes defined in this kext. + */ +#define kOSBundleAllowUserTerminateKey "OSBundleAllowUserTerminate" + +/*! + * @define kOSKernelResourceKey + * @abstract A boolean value indicating whether the kext represents a built-in + * component of the kernel. + */ +#define kOSKernelResourceKey "OSKernelResource" + +/*! + * @define kOSKextVariantOverrideKey + * @abstract A dictionary with target names as key and a target-specific variant + * name as value. + */ +#define kOSKextVariantOverrideKey "OSKextVariantOverride" + +/*! + * @define kIOKitPersonalitiesKey + * @abstract A dictionary of dictionaries used in matching for I/O Kit drivers. + */ +#define kIOKitPersonalitiesKey "IOKitPersonalities" + +/* + * @define kIOPersonalityPublisherKey + * @abstract Used in personalities sent to the I/O Kit, + * contains the CFBundleIdentifier of the kext + * that the personality originated in. + */ +#define kIOPersonalityPublisherKey "IOPersonalityPublisher" + +#if CONFIG_KEC_FIPS +/* + * @define kAppleTextHashesKey + * @abstract A dictionary conataining hashes for corecrypto kext. + */ +#define kAppleTextHashesKey "AppleTextHashes" +#endif + +/*! + * @define kOSMutableSegmentCopy + * @abstract A boolean value indicating whether the kext requires a copy of + * its mutable segments to be kept in memory, and then reset when the kext + * unloads. This should be used with caution as it will increase the + * amount of memory used by the kext. + */ +#define kOSMutableSegmentCopy "OSMutableSegmentCopy" + + +#if PRAGMA_MARK +/********************************************************************/ +#pragma mark Kext/OSBundle Property Deprecated Keys +/********************************************************************/ +#endif +/* + * @define kOSBundleDebugLevelKey + * @abstract + * Deprecated (used on some releases of Mac OS X prior to 10.6 Snow Leopard). + * Value is an integer from 1-6, corresponding to the verbose levels + * of kext tools on those releases. + * On 10.6 Snow Leopard, use @link OSKextEnableKextLogging + * OSKextEnableKextLogging@/link. + */ +#define kOSBundleDebugLevelKey "OSBundleDebugLevel" + +/*! + * @define kOSBundleSharedExecutableIdentifierKey + * @abstract Deprecated (used on some releases of Mac OS X + * prior to 10.6 Snow Leopard). + * Value is the bundle identifier of the pseudokext + * that contains an executable shared by this kext. + */ +#define kOSBundleSharedExecutableIdentifierKey "OSBundleSharedExecutableIdentifier" + + +#if PRAGMA_MARK +/********************************************************************/ +#pragma mark Kext/OSBundle Property List Values +/********************************************************************/ +#endif + +/*! + * @group Kext Property List Values + * These constants encompass established values + * for kernel extension bundle properties. + */ + +/*! + * @define kOSKextKernelIdentifier + * @abstract + * This is the CFBundleIdentifier user for the kernel itself. + */ +#define kOSKextKernelIdentifier "__kernel__" + +/*! + * @define kOSKextBundlePackageTypeKext + * @abstract + * The bundle type value for Kernel Extensions. + */ +#define kOSKextBundlePackageTypeKext "KEXT" + +/*! + * @define kOSKextBundlePackageTypeDriverKit + * @abstract + * The bundle type value for Driver Extensions. + */ +#define kOSKextBundlePackageTypeDriverKit "DEXT" + +/*! + * @define kOSBundleRequiredRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * whether starting from a local or a network volume. + */ +#define kOSBundleRequiredRoot "Root" + +/*! + * @define kOSBundleRequiredLocalRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * when starting from a local disk. + */ +#define kOSBundleRequiredLocalRoot "Local-Root" + +/*! + * @define kOSBundleRequiredNetworkRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * when starting over a network connection. + */ +#define kOSBundleRequiredNetworkRoot "Network-Root" + +/*! + * @define kOSBundleRequiredSafeBoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext can be loaded during a safe startup. + * This value does not normally cause the kext to be read by the booter + * or included in startup kext caches. + */ +#define kOSBundleRequiredSafeBoot "Safe Boot" + +/*! + * @define kOSBundleRequiredConsole + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed for console access + * (specifically in a single-user startup when + * @link //apple_ref/doc/man/8/kextd kextd(8)@/link. + * does not run) + * and should be loaded during early startup. + */ +#define kOSBundleRequiredConsole "Console" + +/*! + * @define kOSBundleRequiredDriverKit + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the driver extension's (DriverKit driver's) + * personalities must be present in the kernel at early boot (specifically + * before @link //apple_ref/doc/man/8/kextd kextd(8)@/link starts) + * in order to compete with kexts built into the prelinkedkernel. Note that + * kextd is still required to launch the user space driver binary. The IOKit + * matching will happen during early boot, and the actual driver launch + * will happen after kextd starts. + */ +#define kOSBundleRequiredDriverKit "DriverKit" + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark Kext Information +/********************************************************************/ +#endif +/*! + * @group Kext Information + * Types, constants, and macros providing a kext with information + * about itself. + */ + +/*! + * @typedef OSKextLoadTag + * + * @abstract + * A unique identifier assigned to a loaded instanace of a kext. + * + * @discussion + * If a kext is unloaded and later reloaded, the new instance + * has a different load tag. + * + * A kext can get its own load tag in the kmod_info_t + * structure passed into its module start routine, as the + * id field (cast to this type). + */ +typedef uint32_t OSKextLoadTag; + +/*! + * @define kOSKextInvalidLoadTag + * + * @abstract + * A load tag value that will never be used for a loaded kext; + * indicates kext not found. + */ +#define kOSKextInvalidLoadTag ((OSKextLoadTag)(-1)) + + +__END_DECLS + +#endif /* _LIBKERN_OSKEXTLIB_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/libproc.h b/lib/libc/include/any-macos.11-any/libproc.h new file mode 100644 index 0000000000..de2c766c28 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/libproc.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef _LIBPROC_H_ +#define _LIBPROC_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for audit_token_t */ + +#include + +#include +#include + +/* + * This header file contains private interfaces to obtain process information. + * These interfaces are subject to change in future releases. + */ + +/*! + * @define PROC_LISTPIDSPATH_PATH_IS_VOLUME + * @discussion This flag indicates that all processes that hold open + * file references on the volume associated with the specified + * path should be returned. + */ +#define PROC_LISTPIDSPATH_PATH_IS_VOLUME 1 + + +/*! + * @define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY + * @discussion This flag indicates that file references that were opened + * with the O_EVTONLY flag should be excluded from the matching + * criteria. + */ +#define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY 2 + +__BEGIN_DECLS + + +/*! + * @function proc_listpidspath + * @discussion A function which will search through the current + * processes looking for open file references which match + * a specified path or volume. + * @param type types of processes to be searched (see proc_listpids) + * @param typeinfo adjunct information for type + * @param path file or volume path + * @param pathflags flags to control which files should be considered + * during the process search. + * @param buffer a C array of int-sized values to be filled with + * process identifiers that hold an open file reference + * matching the specified path or volume. Pass NULL to + * obtain the minimum buffer size needed to hold the + * currently active processes. + * @param buffersize the size (in bytes) of the provided buffer. + * @result the number of bytes of data returned in the provided buffer; + * -1 if an error was encountered; + */ +int proc_listpidspath(uint32_t type, + uint32_t typeinfo, + const char *path, + uint32_t pathflags, + void *buffer, + int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_listallpids(void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); +int proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); +int proc_listchildpids(pid_t ppid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); +int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int proc_name(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_kmsgbuf(void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidpath(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int proc_pidpath_audittoken(audit_token_t *audittoken, void * buffer, uint32_t buffersize) API_AVAILABLE(macos(11.0), ios(14.0), watchos(7.0), tvos(14.0)); +int proc_libversion(int *major, int * minor) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +/* + * Return resource usage information for the given pid, which can be a live process or a zombie. + * + * Returns 0 on success; or -1 on failure, with errno set to indicate the specific error. + */ +int proc_pid_rusage(int pid, int flavor, rusage_info_t *buffer) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); + +/* + * A process can use the following api to set its own process control + * state on resoure starvation. The argument can have one of the PROC_SETPC_XX values + */ +#define PROC_SETPC_NONE 0 +#define PROC_SETPC_THROTTLEMEM 1 +#define PROC_SETPC_SUSPEND 2 +#define PROC_SETPC_TERMINATE 3 + +int proc_setpcontrol(const int control) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int proc_setpcontrol(const int control); + +int proc_track_dirty(pid_t pid, uint32_t flags); +int proc_set_dirty(pid_t pid, bool dirty); +int proc_get_dirty(pid_t pid, uint32_t *flags); +int proc_clear_dirty(pid_t pid, uint32_t flags); + +int proc_terminate(pid_t pid, int *sig); + +/* + * NO_SMT means that on an SMT CPU, this thread must be scheduled alone, + * with the paired CPU idle. + * + * Set NO_SMT on the current proc (all existing and future threads) + * This attribute is inherited on fork and exec + */ +int proc_set_no_smt(void) __API_AVAILABLE(macos(11.0)); + +/* Set NO_SMT on the current thread */ +int proc_setthread_no_smt(void) __API_AVAILABLE(macos(11.0)); + +/* + * CPU Security Mitigation APIs + * + * Set CPU security mitigation on the current proc (all existing and future threads) + * This attribute is inherited on fork and exec + */ +int proc_set_csm(uint32_t flags) __API_AVAILABLE(macos(11.0)); + +/* Set CPU security mitigation on the current thread */ +int proc_setthread_csm(uint32_t flags) __API_AVAILABLE(macos(11.0)); + +/* + * flags for CPU Security Mitigation APIs + * PROC_CSM_ALL should be used in most cases, + * the individual flags are provided only for performance evaluation etc + */ +#define PROC_CSM_ALL 0x0001 /* Set all available mitigations */ +#define PROC_CSM_NOSMT 0x0002 /* Set NO_SMT - see above */ +#define PROC_CSM_TECS 0x0004 /* Execute VERW on every return to user mode */ + +#ifdef PRIVATE +#include +/* + * Enumerate potential userspace pointers embedded in kernel data structures. + * Currently inspects kqueues only. + * + * NOTE: returned "pointers" are opaque user-supplied values and thus not + * guaranteed to address valid objects or be pointers at all. + * + * Returns the number of pointers found (which may exceed buffersize), or -1 on + * failure and errno set appropriately. + */ +int proc_list_uptrs(pid_t pid, uint64_t *buffer, uint32_t buffersize); + +int proc_list_dynkqueueids(int pid, kqueue_id_t *buf, uint32_t bufsz); +int proc_piddynkqueueinfo(int pid, int flavor, kqueue_id_t kq_id, void *buffer, + int buffersize); +#endif /* PRIVATE */ + +int proc_udata_info(int pid, int flavor, void *buffer, int buffersize); + +__END_DECLS + +#endif /*_LIBPROC_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach-o/loader.h b/lib/libc/include/any-macos.11-any/mach-o/loader.h index a65dad7aa1..d1520d52cb 100644 --- a/lib/libc/include/any-macos.11-any/mach-o/loader.h +++ b/lib/libc/include/any-macos.11-any/mach-o/loader.h @@ -1274,8 +1274,6 @@ struct build_tool_version { #define PLATFORM_WATCHOSSIMULATOR 9 #define PLATFORM_DRIVERKIT 10 - - /* Known values for the tool field above. */ #define TOOL_CLANG 1 #define TOOL_SWIFT 2 @@ -1458,8 +1456,6 @@ struct dyld_info_command { #define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 #define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 #define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 -#define EXPORT_SYMBOL_FLAGS_STATIC_RESOLVER 0x20 - /* * The linker_option_command contains linker options embedded in object files. diff --git a/lib/libc/include/any-macos.11-any/mach/clock.h b/lib/libc/include/any-macos.11-any/mach/clock.h new file mode 100644 index 0000000000..ec293fc9c1 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/clock.h @@ -0,0 +1,245 @@ +#ifndef _clock_user_ +#define _clock_user_ + +/* Module clock */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef clock_MSG_COUNT +#define clock_MSG_COUNT 3 +#endif /* clock_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine clock_get_time */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_get_time +( + clock_serv_t clock_serv, + mach_timespec_t *cur_time +); + +/* Routine clock_get_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_get_attributes +( + clock_serv_t clock_serv, + clock_flavor_t flavor, + clock_attr_t clock_attr, + mach_msg_type_number_t *clock_attrCnt +); + +/* Routine clock_alarm */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_alarm +( + clock_serv_t clock_serv, + alarm_type_t alarm_type, + mach_timespec_t alarm_time, + clock_reply_t alarm_port +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__clock_subsystem__defined +#define __Request__clock_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__clock_get_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_flavor_t flavor; + mach_msg_type_number_t clock_attrCnt; + } __Request__clock_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t alarm_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + alarm_type_t alarm_type; + mach_timespec_t alarm_time; + } __Request__clock_alarm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__clock_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__clock_subsystem__defined +#define __RequestUnion__clock_subsystem__defined +union __RequestUnion__clock_subsystem { + __Request__clock_get_time_t Request_clock_get_time; + __Request__clock_get_attributes_t Request_clock_get_attributes; + __Request__clock_alarm_t Request_clock_alarm; +}; +#endif /* !__RequestUnion__clock_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__clock_subsystem__defined +#define __Reply__clock_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_timespec_t cur_time; + } __Reply__clock_get_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t clock_attrCnt; + int clock_attr[1]; + } __Reply__clock_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_alarm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__clock_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__clock_subsystem__defined +#define __ReplyUnion__clock_subsystem__defined +union __ReplyUnion__clock_subsystem { + __Reply__clock_get_time_t Reply_clock_get_time; + __Reply__clock_get_attributes_t Reply_clock_get_attributes; + __Reply__clock_alarm_t Reply_clock_alarm; +}; +#endif /* !__RequestUnion__clock_subsystem__defined */ + +#ifndef subsystem_to_name_map_clock +#define subsystem_to_name_map_clock \ + { "clock_get_time", 1000 },\ + { "clock_get_attributes", 1001 },\ + { "clock_alarm", 1002 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _clock_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/clock_priv.h b/lib/libc/include/any-macos.11-any/mach/clock_priv.h new file mode 100644 index 0000000000..0c9d11d9c6 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/clock_priv.h @@ -0,0 +1,199 @@ +#ifndef _clock_priv_user_ +#define _clock_priv_user_ + +/* Module clock_priv */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef clock_priv_MSG_COUNT +#define clock_priv_MSG_COUNT 2 +#endif /* clock_priv_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine clock_set_time */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_set_time +( + clock_ctrl_t clock_ctrl, + mach_timespec_t new_time +); + +/* Routine clock_set_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_set_attributes +( + clock_ctrl_t clock_ctrl, + clock_flavor_t flavor, + clock_attr_t clock_attr, + mach_msg_type_number_t clock_attrCnt +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__clock_priv_subsystem__defined +#define __Request__clock_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_timespec_t new_time; + } __Request__clock_set_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_flavor_t flavor; + mach_msg_type_number_t clock_attrCnt; + int clock_attr[1]; + } __Request__clock_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__clock_priv_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__clock_priv_subsystem__defined +#define __RequestUnion__clock_priv_subsystem__defined +union __RequestUnion__clock_priv_subsystem { + __Request__clock_set_time_t Request_clock_set_time; + __Request__clock_set_attributes_t Request_clock_set_attributes; +}; +#endif /* !__RequestUnion__clock_priv_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__clock_priv_subsystem__defined +#define __Reply__clock_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_set_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__clock_priv_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__clock_priv_subsystem__defined +#define __ReplyUnion__clock_priv_subsystem__defined +union __ReplyUnion__clock_priv_subsystem { + __Reply__clock_set_time_t Reply_clock_set_time; + __Reply__clock_set_attributes_t Reply_clock_set_attributes; +}; +#endif /* !__RequestUnion__clock_priv_subsystem__defined */ + +#ifndef subsystem_to_name_map_clock_priv +#define subsystem_to_name_map_clock_priv \ + { "clock_set_time", 1200 },\ + { "clock_set_attributes", 1201 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _clock_priv_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/exception_types.h b/lib/libc/include/any-macos.11-any/mach/exception_types.h new file mode 100644 index 0000000000..12a12615f2 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/exception_types.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +#ifndef _MACH_EXCEPTION_TYPES_H_ +#define _MACH_EXCEPTION_TYPES_H_ + +#include + +/* + * Machine-independent exception definitions. + */ + +#define EXC_BAD_ACCESS 1 /* Could not access memory */ +/* Code contains kern_return_t describing error. */ +/* Subcode contains bad memory address. */ + +#define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ +/* Illegal or undefined instruction or operand */ + +#define EXC_ARITHMETIC 3 /* Arithmetic exception */ +/* Exact nature of exception is in code field */ + +#define EXC_EMULATION 4 /* Emulation instruction */ +/* Emulation support instruction encountered */ +/* Details in code and subcode fields */ + +#define EXC_SOFTWARE 5 /* Software generated exception */ +/* Exact exception is in code field. */ +/* Codes 0 - 0xFFFF reserved to hardware */ +/* Codes 0x10000 - 0x1FFFF reserved for OS emulation (Unix) */ + +#define EXC_BREAKPOINT 6 /* Trace, breakpoint, etc. */ +/* Details in code field. */ + +#define EXC_SYSCALL 7 /* System calls. */ + +#define EXC_MACH_SYSCALL 8 /* Mach system calls. */ + +#define EXC_RPC_ALERT 9 /* RPC alert */ + +#define EXC_CRASH 10 /* Abnormal process exit */ + +#define EXC_RESOURCE 11 /* Hit resource consumption limit */ +/* Exact resource is in code field. */ + +#define EXC_GUARD 12 /* Violated guarded resource protections */ + +#define EXC_CORPSE_NOTIFY 13 /* Abnormal process exited to corpse state */ + +#define EXC_CORPSE_VARIANT_BIT 0x100 /* bit set for EXC_*_CORPSE variants of EXC_* */ + + +/* + * Machine-independent exception behaviors + */ + +# define EXCEPTION_DEFAULT 1 +/* Send a catch_exception_raise message including the identity. + */ + +# define EXCEPTION_STATE 2 +/* Send a catch_exception_raise_state message including the + * thread state. + */ + +# define EXCEPTION_STATE_IDENTITY 3 +/* Send a catch_exception_raise_state_identity message including + * the thread identity and state. + */ + +#define MACH_EXCEPTION_ERRORS 0x40000000 +/* include additional exception specific errors, not used yet. */ + +#define MACH_EXCEPTION_CODES 0x80000000 +/* Send 64-bit code and subcode in the exception header */ + +#define MACH_EXCEPTION_MASK (MACH_EXCEPTION_CODES | MACH_EXCEPTION_ERRORS) +/* + * Masks for exception definitions, above + * bit zero is unused, therefore 1 word = 31 exception types + */ + +#define EXC_MASK_BAD_ACCESS (1 << EXC_BAD_ACCESS) +#define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) +#define EXC_MASK_ARITHMETIC (1 << EXC_ARITHMETIC) +#define EXC_MASK_EMULATION (1 << EXC_EMULATION) +#define EXC_MASK_SOFTWARE (1 << EXC_SOFTWARE) +#define EXC_MASK_BREAKPOINT (1 << EXC_BREAKPOINT) +#define EXC_MASK_SYSCALL (1 << EXC_SYSCALL) +#define EXC_MASK_MACH_SYSCALL (1 << EXC_MACH_SYSCALL) +#define EXC_MASK_RPC_ALERT (1 << EXC_RPC_ALERT) +#define EXC_MASK_CRASH (1 << EXC_CRASH) +#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE) +#define EXC_MASK_GUARD (1 << EXC_GUARD) +#define EXC_MASK_CORPSE_NOTIFY (1 << EXC_CORPSE_NOTIFY) + +#define EXC_MASK_ALL (EXC_MASK_BAD_ACCESS | \ + EXC_MASK_BAD_INSTRUCTION | \ + EXC_MASK_ARITHMETIC | \ + EXC_MASK_EMULATION | \ + EXC_MASK_SOFTWARE | \ + EXC_MASK_BREAKPOINT | \ + EXC_MASK_SYSCALL | \ + EXC_MASK_MACH_SYSCALL | \ + EXC_MASK_RPC_ALERT | \ + EXC_MASK_RESOURCE | \ + EXC_MASK_GUARD | \ + EXC_MASK_MACHINE) + + +#define FIRST_EXCEPTION 1 /* ZERO is illegal */ + +/* + * Machine independent codes for EXC_SOFTWARE + * Codes 0x10000 - 0x1FFFF reserved for OS emulation (Unix) + * 0x10000 - 0x10002 in use for unix signals + * 0x20000 - 0x2FFFF reserved for MACF + */ +#define EXC_SOFT_SIGNAL 0x10003 /* Unix signal exceptions */ + +#define EXC_MACF_MIN 0x20000 /* MACF exceptions */ +#define EXC_MACF_MAX 0x2FFFF + +#ifndef ASSEMBLER + +#include +#include +#include +#include +/* + * Exported types + */ + +typedef int exception_type_t; +typedef integer_t exception_data_type_t; +typedef int64_t mach_exception_data_type_t; +typedef int exception_behavior_t; +typedef exception_data_type_t *exception_data_t; +typedef mach_exception_data_type_t *mach_exception_data_t; +typedef unsigned int exception_mask_t; +typedef exception_mask_t *exception_mask_array_t; +typedef exception_behavior_t *exception_behavior_array_t; +typedef thread_state_flavor_t *exception_flavor_array_t; +typedef mach_port_t *exception_port_array_t; +typedef ipc_info_port_t *exception_port_info_array_t; +typedef mach_exception_data_type_t mach_exception_code_t; +typedef mach_exception_data_type_t mach_exception_subcode_t; + +#endif /* ASSEMBLER */ + +#endif /* _MACH_EXCEPTION_TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/host_priv.h b/lib/libc/include/any-macos.11-any/mach/host_priv.h new file mode 100644 index 0000000000..9445ae5d93 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/host_priv.h @@ -0,0 +1,1163 @@ +#ifndef _host_priv_user_ +#define _host_priv_user_ + +/* Module host_priv */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef host_priv_MSG_COUNT +#define host_priv_MSG_COUNT 26 +#endif /* host_priv_MSG_COUNT */ + +#include +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine host_get_boot_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_boot_info +( + host_priv_t host_priv, + kernel_boot_info_t boot_info +); + +/* Routine host_reboot */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_reboot +( + host_priv_t host_priv, + int options +); + +/* Routine host_priv_statistics */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_priv_statistics +( + host_priv_t host_priv, + host_flavor_t flavor, + host_info_t host_info_out, + mach_msg_type_number_t *host_info_outCnt +); + +/* Routine host_default_memory_manager */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_default_memory_manager +( + host_priv_t host_priv, + memory_object_default_t *default_manager, + memory_object_cluster_size_t cluster_size +); + +/* Routine vm_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_wire +( + host_priv_t host_priv, + vm_map_t task, + vm_address_t address, + vm_size_t size, + vm_prot_t desired_access +); + +/* Routine thread_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_wire +( + host_priv_t host_priv, + thread_act_t thread, + boolean_t wired +); + +/* Routine vm_allocate_cpm */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_allocate_cpm +( + host_priv_t host_priv, + vm_map_t task, + vm_address_t *address, + vm_size_t size, + int flags +); + +/* Routine host_processors */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processors +( + host_priv_t host_priv, + processor_array_t *out_processor_list, + mach_msg_type_number_t *out_processor_listCnt +); + +/* Routine host_get_clock_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_clock_control +( + host_priv_t host_priv, + clock_id_t clock_id, + clock_ctrl_t *clock_ctrl +); + +/* Routine kmod_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_create +( + host_priv_t host_priv, + vm_address_t info, + kmod_t *module +); + +/* Routine kmod_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_destroy +( + host_priv_t host_priv, + kmod_t module +); + +/* Routine kmod_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_control +( + host_priv_t host_priv, + kmod_t module, + kmod_control_flavor_t flavor, + kmod_args_t *data, + mach_msg_type_number_t *dataCnt +); + +/* Routine host_get_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_special_port +( + host_priv_t host_priv, + int node, + int which, + mach_port_t *port +); + +/* Routine host_set_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_special_port +( + host_priv_t host_priv, + int which, + mach_port_t port +); + +/* Routine host_set_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_exception_ports +( + host_priv_t host_priv, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor +); + +/* Routine host_get_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_exception_ports +( + host_priv_t host_priv, + exception_mask_t exception_mask, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine host_swap_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_swap_exception_ports +( + host_priv_t host_priv, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlerss, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine mach_vm_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_wire +( + host_priv_t host_priv, + vm_map_t task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_prot_t desired_access +); + +/* Routine host_processor_sets */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processor_sets +( + host_priv_t host_priv, + processor_set_name_array_t *processor_sets, + mach_msg_type_number_t *processor_setsCnt +); + +/* Routine host_processor_set_priv */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processor_set_priv +( + host_priv_t host_priv, + processor_set_name_t set_name, + processor_set_t *set +); + +/* Routine host_set_UNDServer */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_UNDServer +( + host_priv_t host, + UNDServerRef server +); + +/* Routine host_get_UNDServer */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_UNDServer +( + host_priv_t host, + UNDServerRef *server +); + +/* Routine kext_request */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kext_request +( + host_priv_t host_priv, + uint32_t user_log_flags, + vm_offset_t request_data, + mach_msg_type_number_t request_dataCnt, + vm_offset_t *response_data, + mach_msg_type_number_t *response_dataCnt, + vm_offset_t *log_data, + mach_msg_type_number_t *log_dataCnt, + kern_return_t *op_result +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__host_priv_subsystem__defined +#define __Request__host_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_boot_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int options; + } __Request__host_reboot_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info_outCnt; + } __Request__host_priv_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t default_manager; + /* end of the kernel processed data */ + NDR_record_t NDR; + memory_object_cluster_size_t cluster_size; + } __Request__host_default_memory_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_prot_t desired_access; + } __Request__vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t wired; + } __Request__thread_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + int flags; + } __Request__vm_allocate_cpm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_processors_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_id_t clock_id; + } __Request__host_get_clock_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t info; + } __Request__kmod_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kmod_t module; + } __Request__kmod_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t data; + /* end of the kernel processed data */ + NDR_record_t NDR; + kmod_t module; + kmod_control_flavor_t flavor; + mach_msg_type_number_t dataCnt; + } __Request__kmod_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int node; + int which; + } __Request__host_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t port; + /* end of the kernel processed data */ + NDR_record_t NDR; + int which; + } __Request__host_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__host_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_mask_t exception_mask; + } __Request__host_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__host_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + vm_prot_t desired_access; + } __Request__mach_vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_processor_sets_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t set_name; + /* end of the kernel processed data */ + } __Request__host_processor_set_priv_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t server; + /* end of the kernel processed data */ + } __Request__host_set_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t request_data; + /* end of the kernel processed data */ + NDR_record_t NDR; + uint32_t user_log_flags; + mach_msg_type_number_t request_dataCnt; + } __Request__kext_request_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__host_priv_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__host_priv_subsystem__defined +#define __RequestUnion__host_priv_subsystem__defined +union __RequestUnion__host_priv_subsystem { + __Request__host_get_boot_info_t Request_host_get_boot_info; + __Request__host_reboot_t Request_host_reboot; + __Request__host_priv_statistics_t Request_host_priv_statistics; + __Request__host_default_memory_manager_t Request_host_default_memory_manager; + __Request__vm_wire_t Request_vm_wire; + __Request__thread_wire_t Request_thread_wire; + __Request__vm_allocate_cpm_t Request_vm_allocate_cpm; + __Request__host_processors_t Request_host_processors; + __Request__host_get_clock_control_t Request_host_get_clock_control; + __Request__kmod_create_t Request_kmod_create; + __Request__kmod_destroy_t Request_kmod_destroy; + __Request__kmod_control_t Request_kmod_control; + __Request__host_get_special_port_t Request_host_get_special_port; + __Request__host_set_special_port_t Request_host_set_special_port; + __Request__host_set_exception_ports_t Request_host_set_exception_ports; + __Request__host_get_exception_ports_t Request_host_get_exception_ports; + __Request__host_swap_exception_ports_t Request_host_swap_exception_ports; + __Request__mach_vm_wire_t Request_mach_vm_wire; + __Request__host_processor_sets_t Request_host_processor_sets; + __Request__host_processor_set_priv_t Request_host_processor_set_priv; + __Request__host_set_UNDServer_t Request_host_set_UNDServer; + __Request__host_get_UNDServer_t Request_host_get_UNDServer; + __Request__kext_request_t Request_kext_request; +}; +#endif /* !__RequestUnion__host_priv_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__host_priv_subsystem__defined +#define __Reply__host_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t boot_infoOffset; /* MiG doesn't use it */ + mach_msg_type_number_t boot_infoCnt; + char boot_info[4096]; + } __Reply__host_get_boot_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_reboot_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info_outCnt; + integer_t host_info_out[68]; + } __Reply__host_priv_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t default_manager; + /* end of the kernel processed data */ + } __Reply__host_default_memory_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_allocate_cpm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t out_processor_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t out_processor_listCnt; + } __Reply__host_processors_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t clock_ctrl; + /* end of the kernel processed data */ + } __Reply__host_get_clock_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + kmod_t module; + } __Reply__kmod_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__kmod_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t data; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t dataCnt; + } __Reply__kmod_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t port; + /* end of the kernel processed data */ + } __Reply__host_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__host_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t old_handlerss[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__host_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t processor_sets; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t processor_setsCnt; + } __Reply__host_processor_sets_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t set; + /* end of the kernel processed data */ + } __Reply__host_processor_set_priv_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t server; + /* end of the kernel processed data */ + } __Reply__host_get_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t response_data; + mach_msg_ool_descriptor_t log_data; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t response_dataCnt; + mach_msg_type_number_t log_dataCnt; + kern_return_t op_result; + } __Reply__kext_request_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__host_priv_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__host_priv_subsystem__defined +#define __ReplyUnion__host_priv_subsystem__defined +union __ReplyUnion__host_priv_subsystem { + __Reply__host_get_boot_info_t Reply_host_get_boot_info; + __Reply__host_reboot_t Reply_host_reboot; + __Reply__host_priv_statistics_t Reply_host_priv_statistics; + __Reply__host_default_memory_manager_t Reply_host_default_memory_manager; + __Reply__vm_wire_t Reply_vm_wire; + __Reply__thread_wire_t Reply_thread_wire; + __Reply__vm_allocate_cpm_t Reply_vm_allocate_cpm; + __Reply__host_processors_t Reply_host_processors; + __Reply__host_get_clock_control_t Reply_host_get_clock_control; + __Reply__kmod_create_t Reply_kmod_create; + __Reply__kmod_destroy_t Reply_kmod_destroy; + __Reply__kmod_control_t Reply_kmod_control; + __Reply__host_get_special_port_t Reply_host_get_special_port; + __Reply__host_set_special_port_t Reply_host_set_special_port; + __Reply__host_set_exception_ports_t Reply_host_set_exception_ports; + __Reply__host_get_exception_ports_t Reply_host_get_exception_ports; + __Reply__host_swap_exception_ports_t Reply_host_swap_exception_ports; + __Reply__mach_vm_wire_t Reply_mach_vm_wire; + __Reply__host_processor_sets_t Reply_host_processor_sets; + __Reply__host_processor_set_priv_t Reply_host_processor_set_priv; + __Reply__host_set_UNDServer_t Reply_host_set_UNDServer; + __Reply__host_get_UNDServer_t Reply_host_get_UNDServer; + __Reply__kext_request_t Reply_kext_request; +}; +#endif /* !__RequestUnion__host_priv_subsystem__defined */ + +#ifndef subsystem_to_name_map_host_priv +#define subsystem_to_name_map_host_priv \ + { "host_get_boot_info", 400 },\ + { "host_reboot", 401 },\ + { "host_priv_statistics", 402 },\ + { "host_default_memory_manager", 403 },\ + { "vm_wire", 404 },\ + { "thread_wire", 405 },\ + { "vm_allocate_cpm", 406 },\ + { "host_processors", 407 },\ + { "host_get_clock_control", 408 },\ + { "kmod_create", 409 },\ + { "kmod_destroy", 410 },\ + { "kmod_control", 411 },\ + { "host_get_special_port", 412 },\ + { "host_set_special_port", 413 },\ + { "host_set_exception_ports", 414 },\ + { "host_get_exception_ports", 415 },\ + { "host_swap_exception_ports", 416 },\ + { "mach_vm_wire", 418 },\ + { "host_processor_sets", 419 },\ + { "host_processor_set_priv", 420 },\ + { "host_set_UNDServer", 423 },\ + { "host_get_UNDServer", 424 },\ + { "kext_request", 425 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _host_priv_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/host_security.h b/lib/libc/include/any-macos.11-any/mach/host_security.h new file mode 100644 index 0000000000..1c1b6d9144 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/host_security.h @@ -0,0 +1,221 @@ +#ifndef _host_security_user_ +#define _host_security_user_ + +/* Module host_security */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef host_security_MSG_COUNT +#define host_security_MSG_COUNT 2 +#endif /* host_security_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine host_security_create_task_token */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_security_create_task_token +( + host_security_t host_security, + task_t parent_task, + security_token_t sec_token, + audit_token_t audit_token, + host_t host, + ledger_array_t ledgers, + mach_msg_type_number_t ledgersCnt, + boolean_t inherit_memory, + task_t *child_task +); + +/* Routine host_security_set_task_token */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_security_set_task_token +( + host_security_t host_security, + task_t target_task, + security_token_t sec_token, + audit_token_t audit_token, + host_t host +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__host_security_subsystem__defined +#define __Request__host_security_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t parent_task; + mach_msg_port_descriptor_t host; + mach_msg_ool_ports_descriptor_t ledgers; + /* end of the kernel processed data */ + NDR_record_t NDR; + security_token_t sec_token; + audit_token_t audit_token; + mach_msg_type_number_t ledgersCnt; + boolean_t inherit_memory; + } __Request__host_security_create_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t target_task; + mach_msg_port_descriptor_t host; + /* end of the kernel processed data */ + NDR_record_t NDR; + security_token_t sec_token; + audit_token_t audit_token; + } __Request__host_security_set_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__host_security_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__host_security_subsystem__defined +#define __RequestUnion__host_security_subsystem__defined +union __RequestUnion__host_security_subsystem { + __Request__host_security_create_task_token_t Request_host_security_create_task_token; + __Request__host_security_set_task_token_t Request_host_security_set_task_token; +}; +#endif /* !__RequestUnion__host_security_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__host_security_subsystem__defined +#define __Reply__host_security_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t child_task; + /* end of the kernel processed data */ + } __Reply__host_security_create_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_security_set_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__host_security_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__host_security_subsystem__defined +#define __ReplyUnion__host_security_subsystem__defined +union __ReplyUnion__host_security_subsystem { + __Reply__host_security_create_task_token_t Reply_host_security_create_task_token; + __Reply__host_security_set_task_token_t Reply_host_security_set_task_token; +}; +#endif /* !__RequestUnion__host_security_subsystem__defined */ + +#ifndef subsystem_to_name_map_host_security +#define subsystem_to_name_map_host_security \ + { "host_security_create_task_token", 600 },\ + { "host_security_set_task_token", 601 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _host_security_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/kern_return.h b/lib/libc/include/any-macos.11-any/mach/kern_return.h new file mode 100644 index 0000000000..28f6e1b59f --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/kern_return.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: h/kern_return.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * Kernel return codes. + * + */ + +#ifndef _MACH_KERN_RETURN_H_ +#define _MACH_KERN_RETURN_H_ + +#include + +#define KERN_SUCCESS 0 + +#define KERN_INVALID_ADDRESS 1 +/* Specified address is not currently valid. + */ + +#define KERN_PROTECTION_FAILURE 2 +/* Specified memory is valid, but does not permit the + * required forms of access. + */ + +#define KERN_NO_SPACE 3 +/* The address range specified is already in use, or + * no address range of the size specified could be + * found. + */ + +#define KERN_INVALID_ARGUMENT 4 +/* The function requested was not applicable to this + * type of argument, or an argument is invalid + */ + +#define KERN_FAILURE 5 +/* The function could not be performed. A catch-all. + */ + +#define KERN_RESOURCE_SHORTAGE 6 +/* A system resource could not be allocated to fulfill + * this request. This failure may not be permanent. + */ + +#define KERN_NOT_RECEIVER 7 +/* The task in question does not hold receive rights + * for the port argument. + */ + +#define KERN_NO_ACCESS 8 +/* Bogus access restriction. + */ + +#define KERN_MEMORY_FAILURE 9 +/* During a page fault, the target address refers to a + * memory object that has been destroyed. This + * failure is permanent. + */ + +#define KERN_MEMORY_ERROR 10 +/* During a page fault, the memory object indicated + * that the data could not be returned. This failure + * may be temporary; future attempts to access this + * same data may succeed, as defined by the memory + * object. + */ + +#define KERN_ALREADY_IN_SET 11 +/* The receive right is already a member of the portset. + */ + +#define KERN_NOT_IN_SET 12 +/* The receive right is not a member of a port set. + */ + +#define KERN_NAME_EXISTS 13 +/* The name already denotes a right in the task. + */ + +#define KERN_ABORTED 14 +/* The operation was aborted. Ipc code will + * catch this and reflect it as a message error. + */ + +#define KERN_INVALID_NAME 15 +/* The name doesn't denote a right in the task. + */ + +#define KERN_INVALID_TASK 16 +/* Target task isn't an active task. + */ + +#define KERN_INVALID_RIGHT 17 +/* The name denotes a right, but not an appropriate right. + */ + +#define KERN_INVALID_VALUE 18 +/* A blatant range error. + */ + +#define KERN_UREFS_OVERFLOW 19 +/* Operation would overflow limit on user-references. + */ + +#define KERN_INVALID_CAPABILITY 20 +/* The supplied (port) capability is improper. + */ + +#define KERN_RIGHT_EXISTS 21 +/* The task already has send or receive rights + * for the port under another name. + */ + +#define KERN_INVALID_HOST 22 +/* Target host isn't actually a host. + */ + +#define KERN_MEMORY_PRESENT 23 +/* An attempt was made to supply "precious" data + * for memory that is already present in a + * memory object. + */ + +#define KERN_MEMORY_DATA_MOVED 24 +/* A page was requested of a memory manager via + * memory_object_data_request for an object using + * a MEMORY_OBJECT_COPY_CALL strategy, with the + * VM_PROT_WANTS_COPY flag being used to specify + * that the page desired is for a copy of the + * object, and the memory manager has detected + * the page was pushed into a copy of the object + * while the kernel was walking the shadow chain + * from the copy to the object. This error code + * is delivered via memory_object_data_error + * and is handled by the kernel (it forces the + * kernel to restart the fault). It will not be + * seen by users. + */ + +#define KERN_MEMORY_RESTART_COPY 25 +/* A strategic copy was attempted of an object + * upon which a quicker copy is now possible. + * The caller should retry the copy using + * vm_object_copy_quickly. This error code + * is seen only by the kernel. + */ + +#define KERN_INVALID_PROCESSOR_SET 26 +/* An argument applied to assert processor set privilege + * was not a processor set control port. + */ + +#define KERN_POLICY_LIMIT 27 +/* The specified scheduling attributes exceed the thread's + * limits. + */ + +#define KERN_INVALID_POLICY 28 +/* The specified scheduling policy is not currently + * enabled for the processor set. + */ + +#define KERN_INVALID_OBJECT 29 +/* The external memory manager failed to initialize the + * memory object. + */ + +#define KERN_ALREADY_WAITING 30 +/* A thread is attempting to wait for an event for which + * there is already a waiting thread. + */ + +#define KERN_DEFAULT_SET 31 +/* An attempt was made to destroy the default processor + * set. + */ + +#define KERN_EXCEPTION_PROTECTED 32 +/* An attempt was made to fetch an exception port that is + * protected, or to abort a thread while processing a + * protected exception. + */ + +#define KERN_INVALID_LEDGER 33 +/* A ledger was required but not supplied. + */ + +#define KERN_INVALID_MEMORY_CONTROL 34 +/* The port was not a memory cache control port. + */ + +#define KERN_INVALID_SECURITY 35 +/* An argument supplied to assert security privilege + * was not a host security port. + */ + +#define KERN_NOT_DEPRESSED 36 +/* thread_depress_abort was called on a thread which + * was not currently depressed. + */ + +#define KERN_TERMINATED 37 +/* Object has been terminated and is no longer available + */ + +#define KERN_LOCK_SET_DESTROYED 38 +/* Lock set has been destroyed and is no longer available. + */ + +#define KERN_LOCK_UNSTABLE 39 +/* The thread holding the lock terminated before releasing + * the lock + */ + +#define KERN_LOCK_OWNED 40 +/* The lock is already owned by another thread + */ + +#define KERN_LOCK_OWNED_SELF 41 +/* The lock is already owned by the calling thread + */ + +#define KERN_SEMAPHORE_DESTROYED 42 +/* Semaphore has been destroyed and is no longer available. + */ + +#define KERN_RPC_SERVER_TERMINATED 43 +/* Return from RPC indicating the target server was + * terminated before it successfully replied + */ + +#define KERN_RPC_TERMINATE_ORPHAN 44 +/* Terminate an orphaned activation. + */ + +#define KERN_RPC_CONTINUE_ORPHAN 45 +/* Allow an orphaned activation to continue executing. + */ + +#define KERN_NOT_SUPPORTED 46 +/* Empty thread activation (No thread linked to it) + */ + +#define KERN_NODE_DOWN 47 +/* Remote node down or inaccessible. + */ + +#define KERN_NOT_WAITING 48 +/* A signalled thread was not actually waiting. */ + +#define KERN_OPERATION_TIMED_OUT 49 +/* Some thread-oriented operation (semaphore_wait) timed out + */ + +#define KERN_CODESIGN_ERROR 50 +/* During a page fault, indicates that the page was rejected + * as a result of a signature check. + */ + +#define KERN_POLICY_STATIC 51 +/* The requested property cannot be changed at this time. + */ + +#define KERN_INSUFFICIENT_BUFFER_SIZE 52 +/* The provided buffer is of insufficient size for the requested data. + */ + +#define KERN_DENIED 53 +/* Denied by security policy + */ + +#define KERN_MISSING_KC 54 +/* The KC on which the function is operating is missing + */ + +#define KERN_INVALID_KC 55 +/* The KC on which the function is operating is invalid + */ + +#define KERN_RETURN_MAX 0x100 +/* Maximum return value allowable + */ + +#endif /* _MACH_KERN_RETURN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/lock_set.h b/lib/libc/include/any-macos.11-any/mach/lock_set.h new file mode 100644 index 0000000000..752d7c2976 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/lock_set.h @@ -0,0 +1,350 @@ +#ifndef _lock_set_user_ +#define _lock_set_user_ + +/* Module lock_set */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef lock_set_MSG_COUNT +#define lock_set_MSG_COUNT 6 +#endif /* lock_set_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine lock_acquire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_acquire +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_release */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_release +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_try */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_try +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_make_stable */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_make_stable +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_handoff */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_handoff +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_handoff_accept */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_handoff_accept +( + lock_set_t lock_set, + int lock_id +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__lock_set_subsystem__defined +#define __Request__lock_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_acquire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_release_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_try_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_make_stable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_handoff_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_handoff_accept_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__lock_set_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__lock_set_subsystem__defined +#define __RequestUnion__lock_set_subsystem__defined +union __RequestUnion__lock_set_subsystem { + __Request__lock_acquire_t Request_lock_acquire; + __Request__lock_release_t Request_lock_release; + __Request__lock_try_t Request_lock_try; + __Request__lock_make_stable_t Request_lock_make_stable; + __Request__lock_handoff_t Request_lock_handoff; + __Request__lock_handoff_accept_t Request_lock_handoff_accept; +}; +#endif /* !__RequestUnion__lock_set_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__lock_set_subsystem__defined +#define __Reply__lock_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_acquire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_release_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_try_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_make_stable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_handoff_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_handoff_accept_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__lock_set_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__lock_set_subsystem__defined +#define __ReplyUnion__lock_set_subsystem__defined +union __ReplyUnion__lock_set_subsystem { + __Reply__lock_acquire_t Reply_lock_acquire; + __Reply__lock_release_t Reply_lock_release; + __Reply__lock_try_t Reply_lock_try; + __Reply__lock_make_stable_t Reply_lock_make_stable; + __Reply__lock_handoff_t Reply_lock_handoff; + __Reply__lock_handoff_accept_t Reply_lock_handoff_accept; +}; +#endif /* !__RequestUnion__lock_set_subsystem__defined */ + +#ifndef subsystem_to_name_map_lock_set +#define subsystem_to_name_map_lock_set \ + { "lock_acquire", 617000 },\ + { "lock_release", 617001 },\ + { "lock_try", 617002 },\ + { "lock_make_stable", 617003 },\ + { "lock_handoff", 617004 },\ + { "lock_handoff_accept", 617005 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _lock_set_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/mach.h b/lib/libc/include/any-macos.11-any/mach/mach.h new file mode 100644 index 0000000000..159fd67b99 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/mach.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 1999-2014 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Includes all the types that a normal user + * of Mach programs should need + */ + +#ifndef _MACH_H_ +#define _MACH_H_ + +#define __MACH30__ +#define MACH_IPC_FLAVOR UNTYPED + +#include +#include +#include +#include +#include +#include +#include + +#include /* for compatibility only */ +#include + +#include +#include + +#include + +__BEGIN_DECLS +/* + * Standard prototypes + */ +extern void panic_init(mach_port_t); +extern void panic(const char *, ...); + +extern void safe_gets(char *, + char *, + int); + +extern void slot_name(cpu_type_t, + cpu_subtype_t, + char **, + char **); + +extern void mig_reply_setup(mach_msg_header_t *, + mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern void mach_msg_destroy(mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_receive(mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_send(mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_server_once(boolean_t (*) + (mach_msg_header_t *, + mach_msg_header_t *), + mach_msg_size_t, + mach_port_t, + mach_msg_options_t); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_server(boolean_t (*) + (mach_msg_header_t *, + mach_msg_header_t *), + mach_msg_size_t, + mach_port_t, + mach_msg_options_t); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_server_importance(boolean_t (*) + (mach_msg_header_t *, + mach_msg_header_t *), + mach_msg_size_t, + mach_port_t, + mach_msg_options_t); + +/* + * Prototypes for compatibility + */ +extern kern_return_t clock_get_res(mach_port_t, + clock_res_t *); +extern kern_return_t clock_set_res(mach_port_t, + clock_res_t); + +extern kern_return_t clock_sleep(mach_port_t, + int, + mach_timespec_t, + mach_timespec_t *); + +/*! + * @group voucher_mach_msg Prototypes + */ + +#define VOUCHER_MACH_MSG_API_VERSION 20140205 + +/*! + * @typedef voucher_mach_msg_state_t + * + * @abstract + * Opaque object encapsulating state changed by voucher_mach_msg_adopt(). + */ +typedef struct voucher_mach_msg_state_s *voucher_mach_msg_state_t; + +/*! + * @const VOUCHER_MACH_MSG_STATE_UNCHANGED + * + * @discussion + * Constant indicating no state change occurred. + */ +#define VOUCHER_MACH_MSG_STATE_UNCHANGED ((voucher_mach_msg_state_t)~0ul) + +/*! + * @function voucher_mach_msg_set + * + * @abstract + * Change specified message header to contain current mach voucher with a + * COPY_SEND disposition. + * Does not change message if it already has non-zero MACH_MSGH_BITS_VOUCHER. + * + * @discussion + * Borrows reference to current thread voucher so message should be sent + * immediately (without intervening calls that might change that voucher). + * + * @param msg + * The message to modify. + * + * @result + * True if header was changed. + */ +extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg); + +/*! + * @function voucher_mach_msg_clear + * + * @abstract + * Removes changes made to specified message header by voucher_mach_msg_set() + * and any mach_msg() send operations (successful or not). + * If the message is not needed further, mach_msg_destroy() should be called + * instead. + * + * @discussion + * Not intended to be called if voucher_mach_msg_set() returned false. + * Releases reference to message mach voucher if an extra reference was + * acquired due to an unsuccessful send operation (pseudo-receive). + * + * @param msg + * The message to modify. + */ +extern void voucher_mach_msg_clear(mach_msg_header_t *msg); + +/*! + * @function voucher_mach_msg_adopt + * + * @abstract + * Adopt the voucher contained in the specified message on the current thread + * and return the previous thread voucher state. + * + * @discussion + * Ownership of the mach voucher in the message is transferred to the current + * thread and the message header voucher fields are cleared. + * + * @param msg + * The message to query and modify. + * + * @result + * The previous thread voucher state or VOUCHER_MACH_MSG_STATE_UNCHANGED if no + * state change occurred. + */ +extern voucher_mach_msg_state_t voucher_mach_msg_adopt(mach_msg_header_t *msg); + +/*! + * @function voucher_mach_msg_revert + * + * @abstract + * Restore thread voucher state previously modified by voucher_mach_msg_adopt(). + * + * @discussion + * Current thread voucher reference is released. + * No change to thread voucher state if passed VOUCHER_MACH_MSG_STATE_UNCHANGED. + * + * @param state + * The thread voucher state to restore. + */ + +extern void voucher_mach_msg_revert(voucher_mach_msg_state_t state); + +__END_DECLS + +#endif /* _MACH_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/mach_host.h b/lib/libc/include/any-macos.11-any/mach/mach_host.h new file mode 100644 index 0000000000..a5b6d2cd84 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/mach_host.h @@ -0,0 +1,1295 @@ +#ifndef _mach_host_user_ +#define _mach_host_user_ + +/* Module mach_host */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_host_MSG_COUNT +#define mach_host_MSG_COUNT 35 +#endif /* mach_host_MSG_COUNT */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine host_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_info +( + host_t host, + host_flavor_t flavor, + host_info_t host_info_out, + mach_msg_type_number_t *host_info_outCnt +); + +/* Routine host_kernel_version */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_kernel_version +( + host_t host, + kernel_version_t kernel_version +); + +/* Routine _host_page_size */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t _host_page_size +( + host_t host, + vm_size_t *out_page_size +); + +/* Routine mach_memory_object_memory_entry */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_object_memory_entry +( + host_t host, + boolean_t internal, + vm_size_t size, + vm_prot_t permission, + memory_object_t pager, + mach_port_t *entry_handle +); + +/* Routine host_processor_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processor_info +( + host_t host, + processor_flavor_t flavor, + natural_t *out_processor_count, + processor_info_array_t *out_processor_info, + mach_msg_type_number_t *out_processor_infoCnt +); + +/* Routine host_get_io_master */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_io_master +( + host_t host, + io_master_t *io_master +); + +/* Routine host_get_clock_service */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_clock_service +( + host_t host, + clock_id_t clock_id, + clock_serv_t *clock_serv +); + +/* Routine kmod_get_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_get_info +( + host_t host, + kmod_args_t *modules, + mach_msg_type_number_t *modulesCnt +); + +/* Routine host_virtual_physical_table_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_virtual_physical_table_info +( + host_t host, + hash_info_bucket_array_t *info, + mach_msg_type_number_t *infoCnt +); + +/* Routine processor_set_default */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_default +( + host_t host, + processor_set_name_t *default_set +); + +/* Routine processor_set_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_create +( + host_t host, + processor_set_t *new_set, + processor_set_name_t *new_name +); + +/* Routine mach_memory_object_memory_entry_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_object_memory_entry_64 +( + host_t host, + boolean_t internal, + memory_object_size_t size, + vm_prot_t permission, + memory_object_t pager, + mach_port_t *entry_handle +); + +/* Routine host_statistics */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_statistics +( + host_t host_priv, + host_flavor_t flavor, + host_info_t host_info_out, + mach_msg_type_number_t *host_info_outCnt +); + +/* Routine host_request_notification */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_request_notification +( + host_t host, + host_flavor_t notify_type, + mach_port_t notify_port +); + +/* Routine host_lockgroup_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_lockgroup_info +( + host_t host, + lockgroup_info_array_t *lockgroup_info, + mach_msg_type_number_t *lockgroup_infoCnt +); + +/* Routine host_statistics64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_statistics64 +( + host_t host_priv, + host_flavor_t flavor, + host_info64_t host_info64_out, + mach_msg_type_number_t *host_info64_outCnt +); + +/* Routine mach_zone_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_zone_info +( + host_priv_t host, + mach_zone_name_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_zone_info_array_t *info, + mach_msg_type_number_t *infoCnt +); + +/* Routine host_create_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_create_mach_voucher +( + host_t host, + mach_voucher_attr_raw_recipe_array_t recipes, + mach_msg_type_number_t recipesCnt, + ipc_voucher_t *voucher +); + +/* Routine host_register_mach_voucher_attr_manager */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_register_mach_voucher_attr_manager +( + host_t host, + mach_voucher_attr_manager_t attr_manager, + mach_voucher_attr_value_handle_t default_value, + mach_voucher_attr_key_t *new_key, + ipc_voucher_attr_control_t *new_attr_control +); + +/* Routine host_register_well_known_mach_voucher_attr_manager */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_register_well_known_mach_voucher_attr_manager +( + host_t host, + mach_voucher_attr_manager_t attr_manager, + mach_voucher_attr_value_handle_t default_value, + mach_voucher_attr_key_t key, + ipc_voucher_attr_control_t *new_attr_control +); + +/* Routine host_set_atm_diagnostic_flag */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_set_atm_diagnostic_flag +( + host_t host, + uint32_t diagnostic_flag +); + +/* Routine host_get_atm_diagnostic_flag */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_get_atm_diagnostic_flag +( + host_t host, + uint32_t *diagnostic_flag +); + +/* Routine mach_memory_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_info +( + host_priv_t host, + mach_zone_name_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_zone_info_array_t *info, + mach_msg_type_number_t *infoCnt, + mach_memory_info_array_t *memory_info, + mach_msg_type_number_t *memory_infoCnt +); + +/* Routine host_set_multiuser_config_flags */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_multiuser_config_flags +( + host_priv_t host_priv, + uint32_t multiuser_flags +); + +/* Routine host_get_multiuser_config_flags */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_multiuser_config_flags +( + host_t host, + uint32_t *multiuser_flags +); + +/* Routine host_check_multiuser_mode */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_check_multiuser_mode +( + host_t host, + uint32_t *multiuser_mode +); + +/* Routine mach_zone_info_for_zone */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_zone_info_for_zone +( + host_priv_t host, + mach_zone_name_t name, + mach_zone_info_t *info +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__mach_host_subsystem__defined +#define __Request__mach_host_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info_outCnt; + } __Request__host_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_kernel_version_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request___host_page_size_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t pager; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t internal; + vm_size_t size; + vm_prot_t permission; + } __Request__mach_memory_object_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_flavor_t flavor; + } __Request__host_processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_io_master_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_id_t clock_id; + } __Request__host_get_clock_service_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__kmod_get_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_virtual_physical_table_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t pager; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t internal; + memory_object_size_t size; + vm_prot_t permission; + } __Request__mach_memory_object_memory_entry_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info_outCnt; + } __Request__host_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t notify_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + host_flavor_t notify_type; + } __Request__host_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_lockgroup_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info64_outCnt; + } __Request__host_statistics64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_zone_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_msg_type_number_t recipesCnt; + uint8_t recipes[5120]; + } __Request__host_create_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t attr_manager; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_voucher_attr_value_handle_t default_value; + } __Request__host_register_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t attr_manager; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_voucher_attr_value_handle_t default_value; + mach_voucher_attr_key_t key; + } __Request__host_register_well_known_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + uint32_t diagnostic_flag; + } __Request__host_set_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_memory_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + uint32_t multiuser_flags; + } __Request__host_set_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_check_multiuser_mode_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_zone_name_t name; + } __Request__mach_zone_info_for_zone_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__mach_host_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_host_subsystem__defined +#define __RequestUnion__mach_host_subsystem__defined +union __RequestUnion__mach_host_subsystem { + __Request__host_info_t Request_host_info; + __Request__host_kernel_version_t Request_host_kernel_version; + __Request___host_page_size_t Request__host_page_size; + __Request__mach_memory_object_memory_entry_t Request_mach_memory_object_memory_entry; + __Request__host_processor_info_t Request_host_processor_info; + __Request__host_get_io_master_t Request_host_get_io_master; + __Request__host_get_clock_service_t Request_host_get_clock_service; + __Request__kmod_get_info_t Request_kmod_get_info; + __Request__host_virtual_physical_table_info_t Request_host_virtual_physical_table_info; + __Request__processor_set_default_t Request_processor_set_default; + __Request__processor_set_create_t Request_processor_set_create; + __Request__mach_memory_object_memory_entry_64_t Request_mach_memory_object_memory_entry_64; + __Request__host_statistics_t Request_host_statistics; + __Request__host_request_notification_t Request_host_request_notification; + __Request__host_lockgroup_info_t Request_host_lockgroup_info; + __Request__host_statistics64_t Request_host_statistics64; + __Request__mach_zone_info_t Request_mach_zone_info; + __Request__host_create_mach_voucher_t Request_host_create_mach_voucher; + __Request__host_register_mach_voucher_attr_manager_t Request_host_register_mach_voucher_attr_manager; + __Request__host_register_well_known_mach_voucher_attr_manager_t Request_host_register_well_known_mach_voucher_attr_manager; + __Request__host_set_atm_diagnostic_flag_t Request_host_set_atm_diagnostic_flag; + __Request__host_get_atm_diagnostic_flag_t Request_host_get_atm_diagnostic_flag; + __Request__mach_memory_info_t Request_mach_memory_info; + __Request__host_set_multiuser_config_flags_t Request_host_set_multiuser_config_flags; + __Request__host_get_multiuser_config_flags_t Request_host_get_multiuser_config_flags; + __Request__host_check_multiuser_mode_t Request_host_check_multiuser_mode; + __Request__mach_zone_info_for_zone_t Request_mach_zone_info_for_zone; +}; +#endif /* !__RequestUnion__mach_host_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_host_subsystem__defined +#define __Reply__mach_host_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info_outCnt; + integer_t host_info_out[68]; + } __Reply__host_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t kernel_versionOffset; /* MiG doesn't use it */ + mach_msg_type_number_t kernel_versionCnt; + char kernel_version[512]; + } __Reply__host_kernel_version_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_size_t out_page_size; + } __Reply___host_page_size_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t entry_handle; + /* end of the kernel processed data */ + } __Reply__mach_memory_object_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t out_processor_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + natural_t out_processor_count; + mach_msg_type_number_t out_processor_infoCnt; + } __Reply__host_processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t io_master; + /* end of the kernel processed data */ + } __Reply__host_get_io_master_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t clock_serv; + /* end of the kernel processed data */ + } __Reply__host_get_clock_service_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t modules; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t modulesCnt; + } __Reply__kmod_get_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t infoCnt; + } __Reply__host_virtual_physical_table_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t default_set; + /* end of the kernel processed data */ + } __Reply__processor_set_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_set; + mach_msg_port_descriptor_t new_name; + /* end of the kernel processed data */ + } __Reply__processor_set_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t entry_handle; + /* end of the kernel processed data */ + } __Reply__mach_memory_object_memory_entry_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info_outCnt; + integer_t host_info_out[68]; + } __Reply__host_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t lockgroup_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t lockgroup_infoCnt; + } __Reply__host_lockgroup_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info64_outCnt; + integer_t host_info64_out[256]; + } __Reply__host_statistics64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t names; + mach_msg_ool_descriptor_t info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t infoCnt; + } __Reply__mach_zone_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t voucher; + /* end of the kernel processed data */ + } __Reply__host_create_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_attr_control; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_voucher_attr_key_t new_key; + } __Reply__host_register_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_attr_control; + /* end of the kernel processed data */ + } __Reply__host_register_well_known_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + uint32_t diagnostic_flag; + } __Reply__host_get_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t names; + mach_msg_ool_descriptor_t info; + mach_msg_ool_descriptor_t memory_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t infoCnt; + mach_msg_type_number_t memory_infoCnt; + } __Reply__mach_memory_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + uint32_t multiuser_flags; + } __Reply__host_get_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + uint32_t multiuser_mode; + } __Reply__host_check_multiuser_mode_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_zone_info_t info; + } __Reply__mach_zone_info_for_zone_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__mach_host_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_host_subsystem__defined +#define __ReplyUnion__mach_host_subsystem__defined +union __ReplyUnion__mach_host_subsystem { + __Reply__host_info_t Reply_host_info; + __Reply__host_kernel_version_t Reply_host_kernel_version; + __Reply___host_page_size_t Reply__host_page_size; + __Reply__mach_memory_object_memory_entry_t Reply_mach_memory_object_memory_entry; + __Reply__host_processor_info_t Reply_host_processor_info; + __Reply__host_get_io_master_t Reply_host_get_io_master; + __Reply__host_get_clock_service_t Reply_host_get_clock_service; + __Reply__kmod_get_info_t Reply_kmod_get_info; + __Reply__host_virtual_physical_table_info_t Reply_host_virtual_physical_table_info; + __Reply__processor_set_default_t Reply_processor_set_default; + __Reply__processor_set_create_t Reply_processor_set_create; + __Reply__mach_memory_object_memory_entry_64_t Reply_mach_memory_object_memory_entry_64; + __Reply__host_statistics_t Reply_host_statistics; + __Reply__host_request_notification_t Reply_host_request_notification; + __Reply__host_lockgroup_info_t Reply_host_lockgroup_info; + __Reply__host_statistics64_t Reply_host_statistics64; + __Reply__mach_zone_info_t Reply_mach_zone_info; + __Reply__host_create_mach_voucher_t Reply_host_create_mach_voucher; + __Reply__host_register_mach_voucher_attr_manager_t Reply_host_register_mach_voucher_attr_manager; + __Reply__host_register_well_known_mach_voucher_attr_manager_t Reply_host_register_well_known_mach_voucher_attr_manager; + __Reply__host_set_atm_diagnostic_flag_t Reply_host_set_atm_diagnostic_flag; + __Reply__host_get_atm_diagnostic_flag_t Reply_host_get_atm_diagnostic_flag; + __Reply__mach_memory_info_t Reply_mach_memory_info; + __Reply__host_set_multiuser_config_flags_t Reply_host_set_multiuser_config_flags; + __Reply__host_get_multiuser_config_flags_t Reply_host_get_multiuser_config_flags; + __Reply__host_check_multiuser_mode_t Reply_host_check_multiuser_mode; + __Reply__mach_zone_info_for_zone_t Reply_mach_zone_info_for_zone; +}; +#endif /* !__RequestUnion__mach_host_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_host +#define subsystem_to_name_map_mach_host \ + { "host_info", 200 },\ + { "host_kernel_version", 201 },\ + { "_host_page_size", 202 },\ + { "mach_memory_object_memory_entry", 203 },\ + { "host_processor_info", 204 },\ + { "host_get_io_master", 205 },\ + { "host_get_clock_service", 206 },\ + { "kmod_get_info", 207 },\ + { "host_virtual_physical_table_info", 209 },\ + { "processor_set_default", 213 },\ + { "processor_set_create", 214 },\ + { "mach_memory_object_memory_entry_64", 215 },\ + { "host_statistics", 216 },\ + { "host_request_notification", 217 },\ + { "host_lockgroup_info", 218 },\ + { "host_statistics64", 219 },\ + { "mach_zone_info", 220 },\ + { "host_create_mach_voucher", 222 },\ + { "host_register_mach_voucher_attr_manager", 223 },\ + { "host_register_well_known_mach_voucher_attr_manager", 224 },\ + { "host_set_atm_diagnostic_flag", 225 },\ + { "host_get_atm_diagnostic_flag", 226 },\ + { "mach_memory_info", 227 },\ + { "host_set_multiuser_config_flags", 228 },\ + { "host_get_multiuser_config_flags", 229 },\ + { "host_check_multiuser_mode", 230 },\ + { "mach_zone_info_for_zone", 231 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_host_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/mach_init.h b/lib/libc/include/any-macos.11-any/mach/mach_init.h index a18c708eab..a779363409 100644 --- a/lib/libc/include/any-macos.11-any/mach/mach_init.h +++ b/lib/libc/include/any-macos.11-any/mach/mach_init.h @@ -64,7 +64,9 @@ #include +#ifndef KERNEL #include +#endif /* * Kernel-related ports; how a task/thread controls itself diff --git a/lib/libc/include/any-macos.11-any/mach/mach_port.h b/lib/libc/include/any-macos.11-any/mach/mach_port.h new file mode 100644 index 0000000000..c0b2526016 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/mach_port.h @@ -0,0 +1,1808 @@ +#ifndef _mach_port_user_ +#define _mach_port_user_ + +/* Module mach_port */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_port_MSG_COUNT +#define mach_port_MSG_COUNT 40 +#endif /* mach_port_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine mach_port_names */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_names +( + ipc_space_t task, + mach_port_name_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_port_type_array_t *types, + mach_msg_type_number_t *typesCnt +); + +/* Routine mach_port_type */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_type +( + ipc_space_t task, + mach_port_name_t name, + mach_port_type_t *ptype +); + +/* Routine mach_port_rename */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_rename +( + ipc_space_t task, + mach_port_name_t old_name, + mach_port_name_t new_name +); + +/* Routine mach_port_allocate_name */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t mach_port_allocate_name +( + ipc_space_t task, + mach_port_right_t right, + mach_port_name_t name +); + +/* Routine mach_port_allocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_allocate +( + ipc_space_t task, + mach_port_right_t right, + mach_port_name_t *name +); + +/* Routine mach_port_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_destroy +( + ipc_space_t task, + mach_port_name_t name +); + +/* Routine mach_port_deallocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_deallocate +( + ipc_space_t task, + mach_port_name_t name +); + +/* Routine mach_port_get_refs */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_refs +( + ipc_space_t task, + mach_port_name_t name, + mach_port_right_t right, + mach_port_urefs_t *refs +); + +/* Routine mach_port_mod_refs */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_mod_refs +( + ipc_space_t task, + mach_port_name_t name, + mach_port_right_t right, + mach_port_delta_t delta +); + +/* Routine mach_port_peek */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_peek +( + ipc_space_t task, + mach_port_name_t name, + mach_msg_trailer_type_t trailer_type, + mach_port_seqno_t *request_seqnop, + mach_msg_size_t *msg_sizep, + mach_msg_id_t *msg_idp, + mach_msg_trailer_info_t trailer_infop, + mach_msg_type_number_t *trailer_infopCnt +); + +/* Routine mach_port_set_mscount */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_mscount +( + ipc_space_t task, + mach_port_name_t name, + mach_port_mscount_t mscount +); + +/* Routine mach_port_get_set_status */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_set_status +( + ipc_space_read_t task, + mach_port_name_t name, + mach_port_name_array_t *members, + mach_msg_type_number_t *membersCnt +); + +/* Routine mach_port_move_member */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_move_member +( + ipc_space_t task, + mach_port_name_t member, + mach_port_name_t after +); + +/* Routine mach_port_request_notification */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_request_notification +( + ipc_space_t task, + mach_port_name_t name, + mach_msg_id_t msgid, + mach_port_mscount_t sync, + mach_port_t notify, + mach_msg_type_name_t notifyPoly, + mach_port_t *previous +); + +/* Routine mach_port_insert_right */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_insert_right +( + ipc_space_t task, + mach_port_name_t name, + mach_port_t poly, + mach_msg_type_name_t polyPoly +); + +/* Routine mach_port_extract_right */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_extract_right +( + ipc_space_t task, + mach_port_name_t name, + mach_msg_type_name_t msgt_name, + mach_port_t *poly, + mach_msg_type_name_t *polyPoly +); + +/* Routine mach_port_set_seqno */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_seqno +( + ipc_space_t task, + mach_port_name_t name, + mach_port_seqno_t seqno +); + +/* Routine mach_port_get_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_attributes +( + ipc_space_read_t task, + mach_port_name_t name, + mach_port_flavor_t flavor, + mach_port_info_t port_info_out, + mach_msg_type_number_t *port_info_outCnt +); + +/* Routine mach_port_set_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_attributes +( + ipc_space_t task, + mach_port_name_t name, + mach_port_flavor_t flavor, + mach_port_info_t port_info, + mach_msg_type_number_t port_infoCnt +); + +/* Routine mach_port_allocate_qos */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_allocate_qos +( + ipc_space_t task, + mach_port_right_t right, + mach_port_qos_t *qos, + mach_port_name_t *name +); + +/* Routine mach_port_allocate_full */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_allocate_full +( + ipc_space_t task, + mach_port_right_t right, + mach_port_t proto, + mach_port_qos_t *qos, + mach_port_name_t *name +); + +/* Routine task_set_port_space */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_port_space +( + ipc_space_t task, + int table_entries +); + +/* Routine mach_port_get_srights */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_srights +( + ipc_space_t task, + mach_port_name_t name, + mach_port_rights_t *srights +); + +/* Routine mach_port_space_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_space_info +( + ipc_space_read_t space, + ipc_info_space_t *space_info, + ipc_info_name_array_t *table_info, + mach_msg_type_number_t *table_infoCnt, + ipc_info_tree_name_array_t *tree_info, + mach_msg_type_number_t *tree_infoCnt +); + +/* Routine mach_port_dnrequest_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_dnrequest_info +( + ipc_space_t task, + mach_port_name_t name, + unsigned *dnr_total, + unsigned *dnr_used +); + +/* Routine mach_port_kernel_object */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_kernel_object +( + ipc_space_read_t task, + mach_port_name_t name, + unsigned *object_type, + unsigned *object_addr +); + +/* Routine mach_port_insert_member */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_insert_member +( + ipc_space_t task, + mach_port_name_t name, + mach_port_name_t pset +); + +/* Routine mach_port_extract_member */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_extract_member +( + ipc_space_t task, + mach_port_name_t name, + mach_port_name_t pset +); + +/* Routine mach_port_get_context */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_context +( + ipc_space_read_t task, + mach_port_name_t name, + mach_port_context_t *context +); + +/* Routine mach_port_set_context */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_context +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t context +); + +/* Routine mach_port_kobject */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_kobject +( + ipc_space_read_t task, + mach_port_name_t name, + natural_t *object_type, + mach_vm_address_t *object_addr +); + +/* Routine mach_port_construct */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_construct +( + ipc_space_t task, + mach_port_options_ptr_t options, + mach_port_context_t context, + mach_port_name_t *name +); + +/* Routine mach_port_destruct */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_destruct +( + ipc_space_t task, + mach_port_name_t name, + mach_port_delta_t srdelta, + mach_port_context_t guard +); + +/* Routine mach_port_guard */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_guard +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t guard, + boolean_t strict +); + +/* Routine mach_port_unguard */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_unguard +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t guard +); + +/* Routine mach_port_space_basic_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_space_basic_info +( + ipc_space_inspect_t task, + ipc_info_space_basic_t *basic_info +); + +/* Routine mach_port_guard_with_flags */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_guard_with_flags +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t guard, + uint64_t flags +); + +/* Routine mach_port_swap_guard */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_swap_guard +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t old_guard, + mach_port_context_t new_guard +); + +/* Routine mach_port_kobject_description */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_kobject_description +( + ipc_space_read_t task, + mach_port_name_t name, + natural_t *object_type, + mach_vm_address_t *object_addr, + kobject_description_t description +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__mach_port_subsystem__defined +#define __Request__mach_port_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_port_names_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_type_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t old_name; + mach_port_name_t new_name; + } __Request__mach_port_rename_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_right_t right; + mach_port_name_t name; + } __Request__mach_port_allocate_name_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_right_t right; + } __Request__mach_port_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_right_t right; + } __Request__mach_port_get_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_right_t right; + mach_port_delta_t delta; + } __Request__mach_port_mod_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_msg_trailer_type_t trailer_type; + mach_port_seqno_t request_seqnop; + mach_msg_type_number_t trailer_infopCnt; + } __Request__mach_port_peek_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_mscount_t mscount; + } __Request__mach_port_set_mscount_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_get_set_status_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t member; + mach_port_name_t after; + } __Request__mach_port_move_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t notify; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_name_t name; + mach_msg_id_t msgid; + mach_port_mscount_t sync; + } __Request__mach_port_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t poly; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_insert_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_msg_type_name_t msgt_name; + } __Request__mach_port_extract_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_seqno_t seqno; + } __Request__mach_port_set_seqno_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_flavor_t flavor; + mach_msg_type_number_t port_info_outCnt; + } __Request__mach_port_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_flavor_t flavor; + mach_msg_type_number_t port_infoCnt; + integer_t port_info[17]; + } __Request__mach_port_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_right_t right; + mach_port_qos_t qos; + } __Request__mach_port_allocate_qos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t proto; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_right_t right; + mach_port_qos_t qos; + mach_port_name_t name; + } __Request__mach_port_allocate_full_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int table_entries; + } __Request__task_set_port_space_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_get_srights_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_port_space_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_dnrequest_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_kernel_object_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_name_t pset; + } __Request__mach_port_insert_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_name_t pset; + } __Request__mach_port_extract_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_get_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t context; + } __Request__mach_port_set_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_kobject_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t options; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_context_t context; + } __Request__mach_port_construct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_delta_t srdelta; + mach_port_context_t guard; + } __Request__mach_port_destruct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t guard; + boolean_t strict; + } __Request__mach_port_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t guard; + } __Request__mach_port_unguard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_port_space_basic_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t guard; + uint64_t flags; + } __Request__mach_port_guard_with_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t old_guard; + mach_port_context_t new_guard; + } __Request__mach_port_swap_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_kobject_description_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__mach_port_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_port_subsystem__defined +#define __RequestUnion__mach_port_subsystem__defined +union __RequestUnion__mach_port_subsystem { + __Request__mach_port_names_t Request_mach_port_names; + __Request__mach_port_type_t Request_mach_port_type; + __Request__mach_port_rename_t Request_mach_port_rename; + __Request__mach_port_allocate_name_t Request_mach_port_allocate_name; + __Request__mach_port_allocate_t Request_mach_port_allocate; + __Request__mach_port_destroy_t Request_mach_port_destroy; + __Request__mach_port_deallocate_t Request_mach_port_deallocate; + __Request__mach_port_get_refs_t Request_mach_port_get_refs; + __Request__mach_port_mod_refs_t Request_mach_port_mod_refs; + __Request__mach_port_peek_t Request_mach_port_peek; + __Request__mach_port_set_mscount_t Request_mach_port_set_mscount; + __Request__mach_port_get_set_status_t Request_mach_port_get_set_status; + __Request__mach_port_move_member_t Request_mach_port_move_member; + __Request__mach_port_request_notification_t Request_mach_port_request_notification; + __Request__mach_port_insert_right_t Request_mach_port_insert_right; + __Request__mach_port_extract_right_t Request_mach_port_extract_right; + __Request__mach_port_set_seqno_t Request_mach_port_set_seqno; + __Request__mach_port_get_attributes_t Request_mach_port_get_attributes; + __Request__mach_port_set_attributes_t Request_mach_port_set_attributes; + __Request__mach_port_allocate_qos_t Request_mach_port_allocate_qos; + __Request__mach_port_allocate_full_t Request_mach_port_allocate_full; + __Request__task_set_port_space_t Request_task_set_port_space; + __Request__mach_port_get_srights_t Request_mach_port_get_srights; + __Request__mach_port_space_info_t Request_mach_port_space_info; + __Request__mach_port_dnrequest_info_t Request_mach_port_dnrequest_info; + __Request__mach_port_kernel_object_t Request_mach_port_kernel_object; + __Request__mach_port_insert_member_t Request_mach_port_insert_member; + __Request__mach_port_extract_member_t Request_mach_port_extract_member; + __Request__mach_port_get_context_t Request_mach_port_get_context; + __Request__mach_port_set_context_t Request_mach_port_set_context; + __Request__mach_port_kobject_t Request_mach_port_kobject; + __Request__mach_port_construct_t Request_mach_port_construct; + __Request__mach_port_destruct_t Request_mach_port_destruct; + __Request__mach_port_guard_t Request_mach_port_guard; + __Request__mach_port_unguard_t Request_mach_port_unguard; + __Request__mach_port_space_basic_info_t Request_mach_port_space_basic_info; + __Request__mach_port_guard_with_flags_t Request_mach_port_guard_with_flags; + __Request__mach_port_swap_guard_t Request_mach_port_swap_guard; + __Request__mach_port_kobject_description_t Request_mach_port_kobject_description; +}; +#endif /* !__RequestUnion__mach_port_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_port_subsystem__defined +#define __Reply__mach_port_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t names; + mach_msg_ool_descriptor_t types; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t typesCnt; + } __Reply__mach_port_names_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_type_t ptype; + } __Reply__mach_port_type_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_rename_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_allocate_name_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_name_t name; + } __Reply__mach_port_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_urefs_t refs; + } __Reply__mach_port_get_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_mod_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_seqno_t request_seqnop; + mach_msg_size_t msg_sizep; + mach_msg_id_t msg_idp; + mach_msg_type_number_t trailer_infopCnt; + char trailer_infop[68]; + } __Reply__mach_port_peek_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_mscount_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t members; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t membersCnt; + } __Reply__mach_port_get_set_status_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_move_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t previous; + /* end of the kernel processed data */ + } __Reply__mach_port_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_insert_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t poly; + /* end of the kernel processed data */ + } __Reply__mach_port_extract_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_seqno_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t port_info_outCnt; + integer_t port_info_out[17]; + } __Reply__mach_port_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_qos_t qos; + mach_port_name_t name; + } __Reply__mach_port_allocate_qos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_qos_t qos; + mach_port_name_t name; + } __Reply__mach_port_allocate_full_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_port_space_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_rights_t srights; + } __Reply__mach_port_get_srights_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t table_info; + mach_msg_ool_descriptor_t tree_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + ipc_info_space_t space_info; + mach_msg_type_number_t table_infoCnt; + mach_msg_type_number_t tree_infoCnt; + } __Reply__mach_port_space_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + unsigned dnr_total; + unsigned dnr_used; + } __Reply__mach_port_dnrequest_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + unsigned object_type; + unsigned object_addr; + } __Reply__mach_port_kernel_object_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_insert_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_extract_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_context_t context; + } __Reply__mach_port_get_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + natural_t object_type; + mach_vm_address_t object_addr; + } __Reply__mach_port_kobject_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_name_t name; + } __Reply__mach_port_construct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_destruct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_unguard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + ipc_info_space_basic_t basic_info; + } __Reply__mach_port_space_basic_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_guard_with_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_swap_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + natural_t object_type; + mach_vm_address_t object_addr; + mach_msg_type_number_t descriptionOffset; /* MiG doesn't use it */ + mach_msg_type_number_t descriptionCnt; + char description[512]; + } __Reply__mach_port_kobject_description_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__mach_port_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_port_subsystem__defined +#define __ReplyUnion__mach_port_subsystem__defined +union __ReplyUnion__mach_port_subsystem { + __Reply__mach_port_names_t Reply_mach_port_names; + __Reply__mach_port_type_t Reply_mach_port_type; + __Reply__mach_port_rename_t Reply_mach_port_rename; + __Reply__mach_port_allocate_name_t Reply_mach_port_allocate_name; + __Reply__mach_port_allocate_t Reply_mach_port_allocate; + __Reply__mach_port_destroy_t Reply_mach_port_destroy; + __Reply__mach_port_deallocate_t Reply_mach_port_deallocate; + __Reply__mach_port_get_refs_t Reply_mach_port_get_refs; + __Reply__mach_port_mod_refs_t Reply_mach_port_mod_refs; + __Reply__mach_port_peek_t Reply_mach_port_peek; + __Reply__mach_port_set_mscount_t Reply_mach_port_set_mscount; + __Reply__mach_port_get_set_status_t Reply_mach_port_get_set_status; + __Reply__mach_port_move_member_t Reply_mach_port_move_member; + __Reply__mach_port_request_notification_t Reply_mach_port_request_notification; + __Reply__mach_port_insert_right_t Reply_mach_port_insert_right; + __Reply__mach_port_extract_right_t Reply_mach_port_extract_right; + __Reply__mach_port_set_seqno_t Reply_mach_port_set_seqno; + __Reply__mach_port_get_attributes_t Reply_mach_port_get_attributes; + __Reply__mach_port_set_attributes_t Reply_mach_port_set_attributes; + __Reply__mach_port_allocate_qos_t Reply_mach_port_allocate_qos; + __Reply__mach_port_allocate_full_t Reply_mach_port_allocate_full; + __Reply__task_set_port_space_t Reply_task_set_port_space; + __Reply__mach_port_get_srights_t Reply_mach_port_get_srights; + __Reply__mach_port_space_info_t Reply_mach_port_space_info; + __Reply__mach_port_dnrequest_info_t Reply_mach_port_dnrequest_info; + __Reply__mach_port_kernel_object_t Reply_mach_port_kernel_object; + __Reply__mach_port_insert_member_t Reply_mach_port_insert_member; + __Reply__mach_port_extract_member_t Reply_mach_port_extract_member; + __Reply__mach_port_get_context_t Reply_mach_port_get_context; + __Reply__mach_port_set_context_t Reply_mach_port_set_context; + __Reply__mach_port_kobject_t Reply_mach_port_kobject; + __Reply__mach_port_construct_t Reply_mach_port_construct; + __Reply__mach_port_destruct_t Reply_mach_port_destruct; + __Reply__mach_port_guard_t Reply_mach_port_guard; + __Reply__mach_port_unguard_t Reply_mach_port_unguard; + __Reply__mach_port_space_basic_info_t Reply_mach_port_space_basic_info; + __Reply__mach_port_guard_with_flags_t Reply_mach_port_guard_with_flags; + __Reply__mach_port_swap_guard_t Reply_mach_port_swap_guard; + __Reply__mach_port_kobject_description_t Reply_mach_port_kobject_description; +}; +#endif /* !__RequestUnion__mach_port_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_port +#define subsystem_to_name_map_mach_port \ + { "mach_port_names", 3200 },\ + { "mach_port_type", 3201 },\ + { "mach_port_rename", 3202 },\ + { "mach_port_allocate_name", 3203 },\ + { "mach_port_allocate", 3204 },\ + { "mach_port_destroy", 3205 },\ + { "mach_port_deallocate", 3206 },\ + { "mach_port_get_refs", 3207 },\ + { "mach_port_mod_refs", 3208 },\ + { "mach_port_peek", 3209 },\ + { "mach_port_set_mscount", 3210 },\ + { "mach_port_get_set_status", 3211 },\ + { "mach_port_move_member", 3212 },\ + { "mach_port_request_notification", 3213 },\ + { "mach_port_insert_right", 3214 },\ + { "mach_port_extract_right", 3215 },\ + { "mach_port_set_seqno", 3216 },\ + { "mach_port_get_attributes", 3217 },\ + { "mach_port_set_attributes", 3218 },\ + { "mach_port_allocate_qos", 3219 },\ + { "mach_port_allocate_full", 3220 },\ + { "task_set_port_space", 3221 },\ + { "mach_port_get_srights", 3222 },\ + { "mach_port_space_info", 3223 },\ + { "mach_port_dnrequest_info", 3224 },\ + { "mach_port_kernel_object", 3225 },\ + { "mach_port_insert_member", 3226 },\ + { "mach_port_extract_member", 3227 },\ + { "mach_port_get_context", 3228 },\ + { "mach_port_set_context", 3229 },\ + { "mach_port_kobject", 3230 },\ + { "mach_port_construct", 3231 },\ + { "mach_port_destruct", 3232 },\ + { "mach_port_guard", 3233 },\ + { "mach_port_unguard", 3234 },\ + { "mach_port_space_basic_info", 3235 },\ + { "mach_port_guard_with_flags", 3237 },\ + { "mach_port_swap_guard", 3238 },\ + { "mach_port_kobject_description", 3239 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_port_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/mach_types.h b/lib/libc/include/any-macos.11-any/mach/mach_types.h index eacb70d0e0..50e84225eb 100644 --- a/lib/libc/include/any-macos.11-any/mach/mach_types.h +++ b/lib/libc/include/any-macos.11-any/mach/mach_types.h @@ -218,7 +218,6 @@ typedef exception_handler_t exception_port_t; typedef exception_handler_array_t exception_port_arrary_t; typedef char vfs_path_t[4096]; typedef char nspace_path_t[1024]; /* 1024 == PATH_MAX */ -typedef char nspace_name_t[1024]; /* 1024 == PATH_MAX */ typedef char suid_cred_path_t[1024]; typedef uint32_t suid_cred_uid_t; @@ -262,16 +261,12 @@ typedef unsigned int mach_task_flavor_t; #define TASK_FLAVOR_INSPECT 2 /* a task_inspect_t */ #define TASK_FLAVOR_NAME 3 /* a task_name_t */ -#define TASK_FLAVOR_MAX TASK_FLAVOR_NAME - /* capability strictly _DECREASING_ */ typedef unsigned int mach_thread_flavor_t; #define THREAD_FLAVOR_CONTROL 0 /* a thread_t */ #define THREAD_FLAVOR_READ 1 /* a thread_read_t */ #define THREAD_FLAVOR_INSPECT 2 /* a thread_inspect_t */ -#define THREAD_FLAVOR_MAX THREAD_FLAVOR_INSPECT - /* DEPRECATED */ typedef natural_t ledger_item_t; #define LEDGER_ITEM_INFINITY ((ledger_item_t) (~0)) diff --git a/lib/libc/include/any-macos.11-any/mach/mach_voucher_types.h b/lib/libc/include/any-macos.11-any/mach/mach_voucher_types.h new file mode 100644 index 0000000000..b5b34d7e4c --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/mach_voucher_types.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2013 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_VOUCHER_TYPES_H_ +#define _MACH_VOUCHER_TYPES_H_ + +#include +#include + +/* + * Mach Voucher - an immutable collection of attribute value handles. + * + * The mach voucher is such that it can be passed between processes + * as a Mach port send right (by convention in the mach_msg_header_t’s + * msgh_voucher field). + * + * You may construct a new mach voucher by passing a construction + * recipe to host_create_mach_voucher(). The construction recipe supports + * generic commands for copying, removing, and redeeming attribute value + * handles from previous vouchers, or running attribute-mananger-specific + * commands within the recipe. + * + * Once the set of attribute value handles is constructed and returned, + * that set will not change for the life of the voucher (just because the + * attribute value handle itself doesn't change, the value the handle refers + * to is free to change at will). + */ +typedef mach_port_t mach_voucher_t; +#define MACH_VOUCHER_NULL ((mach_voucher_t) 0) + +typedef mach_port_name_t mach_voucher_name_t; +#define MACH_VOUCHER_NAME_NULL ((mach_voucher_name_t) 0) + +typedef mach_voucher_name_t *mach_voucher_name_array_t; +#define MACH_VOUCHER_NAME_ARRAY_NULL ((mach_voucher_name_array_t) 0) + +/* + * This type changes appearance between user-space and kernel. It is + * a port at user-space and a reference to an ipc_voucher structure in-kernel. + */ +typedef mach_voucher_t ipc_voucher_t; +#define IPC_VOUCHER_NULL ((ipc_voucher_t) 0) + +/* + * mach_voucher_selector_t - A means of specifying which thread/task value to extract - + * the current voucher set at this level, or a voucher representing + * the full [layered] effective value for the task/thread. + */ +typedef uint32_t mach_voucher_selector_t; +#define MACH_VOUCHER_SELECTOR_CURRENT ((mach_voucher_selector_t)0) +#define MACH_VOUCHER_SELECTOR_EFFECTIVE ((mach_voucher_selector_t)1) + + +/* + * mach_voucher_attr_key_t - The key used to identify a particular managed resource or + * to select the specific resource manager’s data associated + * with a given voucher. + */ +typedef uint32_t mach_voucher_attr_key_t; +typedef mach_voucher_attr_key_t *mach_voucher_attr_key_array_t; + +#define MACH_VOUCHER_ATTR_KEY_ALL ((mach_voucher_attr_key_t)~0) +#define MACH_VOUCHER_ATTR_KEY_NONE ((mach_voucher_attr_key_t)0) + +/* other well-known-keys will be added here */ +#define MACH_VOUCHER_ATTR_KEY_ATM ((mach_voucher_attr_key_t)1) +#define MACH_VOUCHER_ATTR_KEY_IMPORTANCE ((mach_voucher_attr_key_t)2) +#define MACH_VOUCHER_ATTR_KEY_BANK ((mach_voucher_attr_key_t)3) +#define MACH_VOUCHER_ATTR_KEY_PTHPRIORITY ((mach_voucher_attr_key_t)4) + +#define MACH_VOUCHER_ATTR_KEY_USER_DATA ((mach_voucher_attr_key_t)7) +#define MACH_VOUCHER_ATTR_KEY_BITS MACH_VOUCHER_ATTR_KEY_USER_DATA /* deprecated */ +#define MACH_VOUCHER_ATTR_KEY_TEST ((mach_voucher_attr_key_t)8) + +#define MACH_VOUCHER_ATTR_KEY_NUM_WELL_KNOWN MACH_VOUCHER_ATTR_KEY_TEST + +/* + * mach_voucher_attr_content_t + * + * Data passed to a resource manager for modifying an attribute + * value or returned from the resource manager in response to a + * request to externalize the current value for that attribute. + */ +typedef uint8_t *mach_voucher_attr_content_t; +typedef uint32_t mach_voucher_attr_content_size_t; + +/* + * mach_voucher_attr_command_t - The private verbs implemented by each voucher + * attribute manager via mach_voucher_attr_command(). + */ +typedef uint32_t mach_voucher_attr_command_t; + +/* + * mach_voucher_attr_recipe_command_t + * + * The verbs used to create/morph a voucher attribute value. + * We define some system-wide commands here - related to creation, and transport of + * vouchers and attributes. Additional commands can be defined by, and supported by, + * individual attribute resource managers. + */ +typedef uint32_t mach_voucher_attr_recipe_command_t; +typedef mach_voucher_attr_recipe_command_t *mach_voucher_attr_recipe_command_array_t; + +#define MACH_VOUCHER_ATTR_NOOP ((mach_voucher_attr_recipe_command_t)0) +#define MACH_VOUCHER_ATTR_COPY ((mach_voucher_attr_recipe_command_t)1) +#define MACH_VOUCHER_ATTR_REMOVE ((mach_voucher_attr_recipe_command_t)2) +#define MACH_VOUCHER_ATTR_SET_VALUE_HANDLE ((mach_voucher_attr_recipe_command_t)3) +#define MACH_VOUCHER_ATTR_AUTO_REDEEM ((mach_voucher_attr_recipe_command_t)4) +#define MACH_VOUCHER_ATTR_SEND_PREPROCESS ((mach_voucher_attr_recipe_command_t)5) + +/* redeem is on its way out? */ +#define MACH_VOUCHER_ATTR_REDEEM ((mach_voucher_attr_recipe_command_t)10) + +/* recipe command(s) for importance attribute manager */ +#define MACH_VOUCHER_ATTR_IMPORTANCE_SELF ((mach_voucher_attr_recipe_command_t)200) + +/* recipe command(s) for bit-store attribute manager */ +#define MACH_VOUCHER_ATTR_USER_DATA_STORE ((mach_voucher_attr_recipe_command_t)211) +#define MACH_VOUCHER_ATTR_BITS_STORE MACH_VOUCHER_ATTR_USER_DATA_STORE /* deprecated */ + +/* recipe command(s) for test attribute manager */ +#define MACH_VOUCHER_ATTR_TEST_STORE MACH_VOUCHER_ATTR_USER_DATA_STORE + +/* + * mach_voucher_attr_recipe_t + * + * An element in a recipe list to create a voucher. + */ +#pragma pack(push, 1) + +typedef struct mach_voucher_attr_recipe_data { + mach_voucher_attr_key_t key; + mach_voucher_attr_recipe_command_t command; + mach_voucher_name_t previous_voucher; + mach_voucher_attr_content_size_t content_size; + uint8_t content[]; +} mach_voucher_attr_recipe_data_t; +typedef mach_voucher_attr_recipe_data_t *mach_voucher_attr_recipe_t; +typedef mach_msg_type_number_t mach_voucher_attr_recipe_size_t; + +/* Make the above palatable to MIG */ +typedef uint8_t *mach_voucher_attr_raw_recipe_t; +typedef mach_voucher_attr_raw_recipe_t mach_voucher_attr_raw_recipe_array_t; +typedef mach_msg_type_number_t mach_voucher_attr_raw_recipe_size_t; +typedef mach_msg_type_number_t mach_voucher_attr_raw_recipe_array_size_t; + +#define MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE 5120 +#define MACH_VOUCHER_TRAP_STACK_LIMIT 256 + +#pragma pack(pop) + +/* + * VOUCHER ATTRIBUTE MANAGER Writer types + */ + +/* + * mach_voucher_attr_manager_t + * + * A handle through which the mach voucher mechanism communicates with the voucher + * attribute manager for a given attribute key. + */ +typedef mach_port_t mach_voucher_attr_manager_t; +#define MACH_VOUCHER_ATTR_MANAGER_NULL ((mach_voucher_attr_manager_t) 0) + +/* + * mach_voucher_attr_control_t + * + * A handle provided to the voucher attribute manager for a given attribute key + * through which it makes inquiries or control operations of the mach voucher mechanism. + */ +typedef mach_port_t mach_voucher_attr_control_t; +#define MACH_VOUCHER_ATTR_CONTROL_NULL ((mach_voucher_attr_control_t) 0) + +/* + * These types are different in-kernel vs user-space. They are ports in user-space, + * pointers to opaque structs in most of the kernel, and pointers to known struct + * types in the Mach portion of the kernel. + */ +typedef mach_port_t ipc_voucher_attr_manager_t; +typedef mach_port_t ipc_voucher_attr_control_t; +#define IPC_VOUCHER_ATTR_MANAGER_NULL ((ipc_voucher_attr_manager_t) 0) +#define IPC_VOUCHER_ATTR_CONTROL_NULL ((ipc_voucher_attr_control_t) 0) + +/* + * mach_voucher_attr_value_handle_t + * + * The private handle that the voucher attribute manager provides to + * the mach voucher mechanism to represent a given attr content/value. + */ +typedef uint64_t mach_voucher_attr_value_handle_t; +typedef mach_voucher_attr_value_handle_t *mach_voucher_attr_value_handle_array_t; + +typedef mach_msg_type_number_t mach_voucher_attr_value_handle_array_size_t; +#define MACH_VOUCHER_ATTR_VALUE_MAX_NESTED ((mach_voucher_attr_value_handle_array_size_t)4) + +typedef uint32_t mach_voucher_attr_value_reference_t; +typedef uint32_t mach_voucher_attr_value_flags_t; +#define MACH_VOUCHER_ATTR_VALUE_FLAGS_NONE ((mach_voucher_attr_value_flags_t)0) +#define MACH_VOUCHER_ATTR_VALUE_FLAGS_PERSIST ((mach_voucher_attr_value_flags_t)1) + +/* USE - TBD */ +typedef uint32_t mach_voucher_attr_control_flags_t; +#define MACH_VOUCHER_ATTR_CONTROL_FLAGS_NONE ((mach_voucher_attr_control_flags_t)0) + +/* + * Commands and types for the IPC Importance Attribute Manager + * + * These are the valid mach_voucher_attr_command() options with the + * MACH_VOUCHER_ATTR_KEY_IMPORTANCE key. + */ +#define MACH_VOUCHER_IMPORTANCE_ATTR_ADD_EXTERNAL 1 /* Add some number of external refs (not supported) */ +#define MACH_VOUCHER_IMPORTANCE_ATTR_DROP_EXTERNAL 2 /* Drop some number of external refs */ +typedef uint32_t mach_voucher_attr_importance_refs; + +/* + * Activity id Generation defines + */ +#define MACH_ACTIVITY_ID_COUNT_MAX 16 + +#endif /* _MACH_VOUCHER_TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/machine.h b/lib/libc/include/any-macos.11-any/mach/machine.h new file mode 100644 index 0000000000..a6bbe15721 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/machine.h @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2007-2016 Apple, Inc. All rights reserved. + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* File: machine.h + * Author: Avadis Tevanian, Jr. + * Date: 1986 + * + * Machine independent machine abstraction. + */ + +#ifndef _MACH_MACHINE_H_ +#define _MACH_MACHINE_H_ + +#ifndef __ASSEMBLER__ + +#include +#include +#include + +typedef integer_t cpu_type_t; +typedef integer_t cpu_subtype_t; +typedef integer_t cpu_threadtype_t; + +#define CPU_STATE_MAX 4 + +#define CPU_STATE_USER 0 +#define CPU_STATE_SYSTEM 1 +#define CPU_STATE_IDLE 2 +#define CPU_STATE_NICE 3 + + + +/* + * Capability bits used in the definition of cpu_type. + */ +#define CPU_ARCH_MASK 0xff000000 /* mask for architecture bits */ +#define CPU_ARCH_ABI64 0x01000000 /* 64 bit ABI */ +#define CPU_ARCH_ABI64_32 0x02000000 /* ABI for 64-bit hardware with 32-bit types; LP32 */ + +/* + * Machine types known by all. + */ + +#define CPU_TYPE_ANY ((cpu_type_t) -1) + +#define CPU_TYPE_VAX ((cpu_type_t) 1) +/* skip ((cpu_type_t) 2) */ +/* skip ((cpu_type_t) 3) */ +/* skip ((cpu_type_t) 4) */ +/* skip ((cpu_type_t) 5) */ +#define CPU_TYPE_MC680x0 ((cpu_type_t) 6) +#define CPU_TYPE_X86 ((cpu_type_t) 7) +#define CPU_TYPE_I386 CPU_TYPE_X86 /* compatibility */ +#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) + +/* skip CPU_TYPE_MIPS ((cpu_type_t) 8) */ +/* skip ((cpu_type_t) 9) */ +#define CPU_TYPE_MC98000 ((cpu_type_t) 10) +#define CPU_TYPE_HPPA ((cpu_type_t) 11) +#define CPU_TYPE_ARM ((cpu_type_t) 12) +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) +#define CPU_TYPE_ARM64_32 (CPU_TYPE_ARM | CPU_ARCH_ABI64_32) +#define CPU_TYPE_MC88000 ((cpu_type_t) 13) +#define CPU_TYPE_SPARC ((cpu_type_t) 14) +#define CPU_TYPE_I860 ((cpu_type_t) 15) +/* skip CPU_TYPE_ALPHA ((cpu_type_t) 16) */ +/* skip ((cpu_type_t) 17) */ +#define CPU_TYPE_POWERPC ((cpu_type_t) 18) +#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) +/* skip ((cpu_type_t) 19) */ +/* skip ((cpu_type_t) 20 */ +/* skip ((cpu_type_t) 21 */ +/* skip ((cpu_type_t) 22 */ + +/* + * Machine subtypes (these are defined here, instead of in a machine + * dependent directory, so that any program can get all definitions + * regardless of where is it compiled). + */ + +/* + * Capability bits used in the definition of cpu_subtype. + */ +#define CPU_SUBTYPE_MASK 0xff000000 /* mask for feature flags */ +#define CPU_SUBTYPE_LIB64 0x80000000 /* 64 bit libraries */ +#define CPU_SUBTYPE_PTRAUTH_ABI 0x80000000 /* pointer authentication with versioned ABI */ + +/* + * When selecting a slice, ANY will pick the slice with the best + * grading for the selected cpu_type_t, unlike the "ALL" subtypes, + * which are the slices that can run on any hardware for that cpu type. + */ +#define CPU_SUBTYPE_ANY ((cpu_subtype_t) -1) + +/* + * Object files that are hand-crafted to run on any + * implementation of an architecture are tagged with + * CPU_SUBTYPE_MULTIPLE. This functions essentially the same as + * the "ALL" subtype of an architecture except that it allows us + * to easily find object files that may need to be modified + * whenever a new implementation of an architecture comes out. + * + * It is the responsibility of the implementor to make sure the + * software handles unsupported implementations elegantly. + */ +#define CPU_SUBTYPE_MULTIPLE ((cpu_subtype_t) -1) +#define CPU_SUBTYPE_LITTLE_ENDIAN ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_BIG_ENDIAN ((cpu_subtype_t) 1) + +/* + * Machine threadtypes. + * This is none - not defined - for most machine types/subtypes. + */ +#define CPU_THREADTYPE_NONE ((cpu_threadtype_t) 0) + +/* + * VAX subtypes (these do *not* necessary conform to the actual cpu + * ID assigned by DEC available via the SID register). + */ + +#define CPU_SUBTYPE_VAX_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_VAX780 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_VAX785 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_VAX750 ((cpu_subtype_t) 3) +#define CPU_SUBTYPE_VAX730 ((cpu_subtype_t) 4) +#define CPU_SUBTYPE_UVAXI ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_UVAXII ((cpu_subtype_t) 6) +#define CPU_SUBTYPE_VAX8200 ((cpu_subtype_t) 7) +#define CPU_SUBTYPE_VAX8500 ((cpu_subtype_t) 8) +#define CPU_SUBTYPE_VAX8600 ((cpu_subtype_t) 9) +#define CPU_SUBTYPE_VAX8650 ((cpu_subtype_t) 10) +#define CPU_SUBTYPE_VAX8800 ((cpu_subtype_t) 11) +#define CPU_SUBTYPE_UVAXIII ((cpu_subtype_t) 12) + +/* + * 680x0 subtypes + * + * The subtype definitions here are unusual for historical reasons. + * NeXT used to consider 68030 code as generic 68000 code. For + * backwards compatability: + * + * CPU_SUBTYPE_MC68030 symbol has been preserved for source code + * compatability. + * + * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same + * subtype as CPU_SUBTYPE_MC68030 for binary comatability. + * + * CPU_SUBTYPE_MC68030_ONLY has been added to allow new object + * files to be tagged as containing 68030-specific instructions. + */ + +#define CPU_SUBTYPE_MC680x0_ALL ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_MC68030 ((cpu_subtype_t) 1) /* compat */ +#define CPU_SUBTYPE_MC68040 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_MC68030_ONLY ((cpu_subtype_t) 3) + +/* + * I386 subtypes + */ + +#define CPU_SUBTYPE_INTEL(f, m) ((cpu_subtype_t) (f) + ((m) << 4)) + +#define CPU_SUBTYPE_I386_ALL CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_386 CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_486 CPU_SUBTYPE_INTEL(4, 0) +#define CPU_SUBTYPE_486SX CPU_SUBTYPE_INTEL(4, 8) // 8 << 4 = 128 +#define CPU_SUBTYPE_586 CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENT CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENTPRO CPU_SUBTYPE_INTEL(6, 1) +#define CPU_SUBTYPE_PENTII_M3 CPU_SUBTYPE_INTEL(6, 3) +#define CPU_SUBTYPE_PENTII_M5 CPU_SUBTYPE_INTEL(6, 5) +#define CPU_SUBTYPE_CELERON CPU_SUBTYPE_INTEL(7, 6) +#define CPU_SUBTYPE_CELERON_MOBILE CPU_SUBTYPE_INTEL(7, 7) +#define CPU_SUBTYPE_PENTIUM_3 CPU_SUBTYPE_INTEL(8, 0) +#define CPU_SUBTYPE_PENTIUM_3_M CPU_SUBTYPE_INTEL(8, 1) +#define CPU_SUBTYPE_PENTIUM_3_XEON CPU_SUBTYPE_INTEL(8, 2) +#define CPU_SUBTYPE_PENTIUM_M CPU_SUBTYPE_INTEL(9, 0) +#define CPU_SUBTYPE_PENTIUM_4 CPU_SUBTYPE_INTEL(10, 0) +#define CPU_SUBTYPE_PENTIUM_4_M CPU_SUBTYPE_INTEL(10, 1) +#define CPU_SUBTYPE_ITANIUM CPU_SUBTYPE_INTEL(11, 0) +#define CPU_SUBTYPE_ITANIUM_2 CPU_SUBTYPE_INTEL(11, 1) +#define CPU_SUBTYPE_XEON CPU_SUBTYPE_INTEL(12, 0) +#define CPU_SUBTYPE_XEON_MP CPU_SUBTYPE_INTEL(12, 1) + +#define CPU_SUBTYPE_INTEL_FAMILY(x) ((x) & 15) +#define CPU_SUBTYPE_INTEL_FAMILY_MAX 15 + +#define CPU_SUBTYPE_INTEL_MODEL(x) ((x) >> 4) +#define CPU_SUBTYPE_INTEL_MODEL_ALL 0 + +/* + * X86 subtypes. + */ + +#define CPU_SUBTYPE_X86_ALL ((cpu_subtype_t)3) +#define CPU_SUBTYPE_X86_64_ALL ((cpu_subtype_t)3) +#define CPU_SUBTYPE_X86_ARCH1 ((cpu_subtype_t)4) +#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8) /* Haswell feature subset */ + + +#define CPU_THREADTYPE_INTEL_HTT ((cpu_threadtype_t) 1) + +/* + * Mips subtypes. + */ + +#define CPU_SUBTYPE_MIPS_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_MIPS_R2300 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_MIPS_R2600 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_MIPS_R2800 ((cpu_subtype_t) 3) +#define CPU_SUBTYPE_MIPS_R2000a ((cpu_subtype_t) 4) /* pmax */ +#define CPU_SUBTYPE_MIPS_R2000 ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_MIPS_R3000a ((cpu_subtype_t) 6) /* 3max */ +#define CPU_SUBTYPE_MIPS_R3000 ((cpu_subtype_t) 7) + +/* + * MC98000 (PowerPC) subtypes + */ +#define CPU_SUBTYPE_MC98000_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_MC98601 ((cpu_subtype_t) 1) + +/* + * HPPA subtypes for Hewlett-Packard HP-PA family of + * risc processors. Port by NeXT to 700 series. + */ + +#define CPU_SUBTYPE_HPPA_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_HPPA_7100 ((cpu_subtype_t) 0) /* compat */ +#define CPU_SUBTYPE_HPPA_7100LC ((cpu_subtype_t) 1) + +/* + * MC88000 subtypes. + */ +#define CPU_SUBTYPE_MC88000_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_MC88100 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_MC88110 ((cpu_subtype_t) 2) + +/* + * SPARC subtypes + */ +#define CPU_SUBTYPE_SPARC_ALL ((cpu_subtype_t) 0) + +/* + * I860 subtypes + */ +#define CPU_SUBTYPE_I860_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_I860_860 ((cpu_subtype_t) 1) + +/* + * PowerPC subtypes + */ +#define CPU_SUBTYPE_POWERPC_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_POWERPC_601 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_POWERPC_602 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_POWERPC_603 ((cpu_subtype_t) 3) +#define CPU_SUBTYPE_POWERPC_603e ((cpu_subtype_t) 4) +#define CPU_SUBTYPE_POWERPC_603ev ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_POWERPC_604 ((cpu_subtype_t) 6) +#define CPU_SUBTYPE_POWERPC_604e ((cpu_subtype_t) 7) +#define CPU_SUBTYPE_POWERPC_620 ((cpu_subtype_t) 8) +#define CPU_SUBTYPE_POWERPC_750 ((cpu_subtype_t) 9) +#define CPU_SUBTYPE_POWERPC_7400 ((cpu_subtype_t) 10) +#define CPU_SUBTYPE_POWERPC_7450 ((cpu_subtype_t) 11) +#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) + +/* + * ARM subtypes + */ +#define CPU_SUBTYPE_ARM_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t) 6) +#define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) +#define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) +#define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) /* ARMv7-A and ARMv7-R */ +#define CPU_SUBTYPE_ARM_V7F ((cpu_subtype_t) 10) /* Cortex A9 */ +#define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t) 11) /* Swift */ +#define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t) 12) +#define CPU_SUBTYPE_ARM_V8 ((cpu_subtype_t) 13) +#define CPU_SUBTYPE_ARM_V6M ((cpu_subtype_t) 14) /* Not meant to be run under xnu */ +#define CPU_SUBTYPE_ARM_V7M ((cpu_subtype_t) 15) /* Not meant to be run under xnu */ +#define CPU_SUBTYPE_ARM_V7EM ((cpu_subtype_t) 16) /* Not meant to be run under xnu */ +#define CPU_SUBTYPE_ARM_V8M ((cpu_subtype_t) 17) /* Not meant to be run under xnu */ + +/* + * ARM64 subtypes + */ +#define CPU_SUBTYPE_ARM64_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_ARM64_V8 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_ARM64E ((cpu_subtype_t) 2) + +/* CPU subtype feature flags for ptrauth on arm64e platforms */ +#define CPU_SUBTYPE_ARM64_PTR_AUTH_MASK 0x0f000000 +#define CPU_SUBTYPE_ARM64_PTR_AUTH_VERSION(x) (((x) & CPU_SUBTYPE_ARM64_PTR_AUTH_MASK) >> 24) + +/* + * ARM64_32 subtypes + */ +#define CPU_SUBTYPE_ARM64_32_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_ARM64_32_V8 ((cpu_subtype_t) 1) + +#endif /* !__ASSEMBLER__ */ + +/* + * CPU families (sysctl hw.cpufamily) + * + * These are meant to identify the CPU's marketing name - an + * application can map these to (possibly) localized strings. + * NB: the encodings of the CPU families are intentionally arbitrary. + * There is no ordering, and you should never try to deduce whether + * or not some feature is available based on the family. + * Use feature flags (eg, hw.optional.altivec) to test for optional + * functionality. + */ +#define CPUFAMILY_UNKNOWN 0 +#define CPUFAMILY_POWERPC_G3 0xcee41549 +#define CPUFAMILY_POWERPC_G4 0x77c184ae +#define CPUFAMILY_POWERPC_G5 0xed76d8aa +#define CPUFAMILY_INTEL_6_13 0xaa33392b +#define CPUFAMILY_INTEL_PENRYN 0x78ea4fbc +#define CPUFAMILY_INTEL_NEHALEM 0x6b5a4cd2 +#define CPUFAMILY_INTEL_WESTMERE 0x573b5eec +#define CPUFAMILY_INTEL_SANDYBRIDGE 0x5490b78c +#define CPUFAMILY_INTEL_IVYBRIDGE 0x1f65e835 +#define CPUFAMILY_INTEL_HASWELL 0x10b282dc +#define CPUFAMILY_INTEL_BROADWELL 0x582ed09c +#define CPUFAMILY_INTEL_SKYLAKE 0x37fc219f +#define CPUFAMILY_INTEL_KABYLAKE 0x0f817246 +#define CPUFAMILY_INTEL_ICELAKE 0x38435547 +#define CPUFAMILY_INTEL_COMETLAKE 0x1cf8a03e +#define CPUFAMILY_ARM_9 0xe73283ae +#define CPUFAMILY_ARM_11 0x8ff620d8 +#define CPUFAMILY_ARM_XSCALE 0x53b005f5 +#define CPUFAMILY_ARM_12 0xbd1b0ae9 +#define CPUFAMILY_ARM_13 0x0cc90e64 +#define CPUFAMILY_ARM_14 0x96077ef1 +#define CPUFAMILY_ARM_15 0xa8511bca +#define CPUFAMILY_ARM_SWIFT 0x1e2d6381 +#define CPUFAMILY_ARM_CYCLONE 0x37a09642 +#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e +#define CPUFAMILY_ARM_TWISTER 0x92fb37c8 +#define CPUFAMILY_ARM_HURRICANE 0x67ceee93 +#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6 +#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f +#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2 +#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3 + +#define CPUSUBFAMILY_UNKNOWN 0 +#define CPUSUBFAMILY_ARM_HP 1 +#define CPUSUBFAMILY_ARM_HG 2 +#define CPUSUBFAMILY_ARM_M 3 +#define CPUSUBFAMILY_ARM_HS 4 +#define CPUSUBFAMILY_ARM_HC_HD 5 + +/* The following synonyms are deprecated: */ +#define CPUFAMILY_INTEL_6_23 CPUFAMILY_INTEL_PENRYN +#define CPUFAMILY_INTEL_6_26 CPUFAMILY_INTEL_NEHALEM + + +#endif /* _MACH_MACHINE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/machine/thread_state.h b/lib/libc/include/any-macos.11-any/mach/machine/thread_state.h new file mode 100644 index 0000000000..167b263c82 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/machine/thread_state.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_THREAD_STATE_H_ +#define _MACH_MACHINE_THREAD_STATE_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/thread_state.h" +#elif defined (__arm__) || defined (__arm64__) +#include "mach/arm/thread_state.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_THREAD_STATE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/message.h b/lib/libc/include/any-macos.11-any/mach/message.h new file mode 100644 index 0000000000..6cbd768500 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/message.h @@ -0,0 +1,908 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + * Copyright (c) 2005 SPARTA, Inc. + */ +/* + */ +/* + * File: mach/message.h + * + * Mach IPC message and primitive function definitions. + */ + +#ifndef _MACH_MESSAGE_H_ +#define _MACH_MESSAGE_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * The timeout mechanism uses mach_msg_timeout_t values, + * passed by value. The timeout units are milliseconds. + * It is controlled with the MACH_SEND_TIMEOUT + * and MACH_RCV_TIMEOUT options. + */ + +typedef natural_t mach_msg_timeout_t; + +/* + * The value to be used when there is no timeout. + * (No MACH_SEND_TIMEOUT/MACH_RCV_TIMEOUT option.) + */ + +#define MACH_MSG_TIMEOUT_NONE ((mach_msg_timeout_t) 0) + +/* + * The kernel uses MACH_MSGH_BITS_COMPLEX as a hint. If it isn't on, it + * assumes the body of the message doesn't contain port rights or OOL + * data. The field is set in received messages. A user task must + * use caution in interpreting the body of a message if the bit isn't + * on, because the mach_msg_type's in the body might "lie" about the + * contents. If the bit isn't on, but the mach_msg_types + * in the body specify rights or OOL data, the behavior is undefined. + * (Ie, an error may or may not be produced.) + * + * The value of MACH_MSGH_BITS_REMOTE determines the interpretation + * of the msgh_remote_port field. It is handled like a msgt_name, + * but must result in a send or send-once type right. + * + * The value of MACH_MSGH_BITS_LOCAL determines the interpretation + * of the msgh_local_port field. It is handled like a msgt_name, + * and also must result in a send or send-once type right. + * + * The value of MACH_MSGH_BITS_VOUCHER determines the interpretation + * of the msgh_voucher_port field. It is handled like a msgt_name, + * but must result in a send right (and the msgh_voucher_port field + * must be the name of a send right to a Mach voucher kernel object. + * + * MACH_MSGH_BITS() combines two MACH_MSG_TYPE_* values, for the remote + * and local fields, into a single value suitable for msgh_bits. + * + * MACH_MSGH_BITS_CIRCULAR should be zero; is is used internally. + * + * The unused bits should be zero and are reserved for the kernel + * or for future interface expansion. + */ + +#define MACH_MSGH_BITS_ZERO 0x00000000 + +#define MACH_MSGH_BITS_REMOTE_MASK 0x0000001f +#define MACH_MSGH_BITS_LOCAL_MASK 0x00001f00 +#define MACH_MSGH_BITS_VOUCHER_MASK 0x001f0000 + +#define MACH_MSGH_BITS_PORTS_MASK \ + (MACH_MSGH_BITS_REMOTE_MASK | \ + MACH_MSGH_BITS_LOCAL_MASK | \ + MACH_MSGH_BITS_VOUCHER_MASK) + +#define MACH_MSGH_BITS_COMPLEX 0x80000000U /* message is complex */ + +#define MACH_MSGH_BITS_USER 0x801f1f1fU /* allowed bits user->kernel */ + +#define MACH_MSGH_BITS_RAISEIMP 0x20000000U /* importance raised due to msg */ +#define MACH_MSGH_BITS_DENAP MACH_MSGH_BITS_RAISEIMP + +#define MACH_MSGH_BITS_IMPHOLDASRT 0x10000000U /* assertion help, userland private */ +#define MACH_MSGH_BITS_DENAPHOLDASRT MACH_MSGH_BITS_IMPHOLDASRT + +#define MACH_MSGH_BITS_CIRCULAR 0x10000000U /* message circular, kernel private */ + +#define MACH_MSGH_BITS_USED 0xb01f1f1fU + +/* setter macros for the bits */ +#define MACH_MSGH_BITS(remote, local) /* legacy */ \ + ((remote) | ((local) << 8)) +#define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher) \ + (((remote) & MACH_MSGH_BITS_REMOTE_MASK) | \ + (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | \ + (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK)) +#define MACH_MSGH_BITS_SET(remote, local, voucher, other) \ + (MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher)) \ + | ((other) &~ MACH_MSGH_BITS_PORTS_MASK)) + +/* getter macros for pulling values out of the bits field */ +#define MACH_MSGH_BITS_REMOTE(bits) \ + ((bits) & MACH_MSGH_BITS_REMOTE_MASK) +#define MACH_MSGH_BITS_LOCAL(bits) \ + (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8) +#define MACH_MSGH_BITS_VOUCHER(bits) \ + (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16) +#define MACH_MSGH_BITS_PORTS(bits) \ + ((bits) & MACH_MSGH_BITS_PORTS_MASK) +#define MACH_MSGH_BITS_OTHER(bits) \ + ((bits) &~ MACH_MSGH_BITS_PORTS_MASK) + +/* checking macros */ +#define MACH_MSGH_BITS_HAS_REMOTE(bits) \ + (MACH_MSGH_BITS_REMOTE(bits) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_HAS_LOCAL(bits) \ + (MACH_MSGH_BITS_LOCAL(bits) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_HAS_VOUCHER(bits) \ + (MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_IS_COMPLEX(bits) \ + (((bits) & MACH_MSGH_BITS_COMPLEX) != MACH_MSGH_BITS_ZERO) + +/* importance checking macros */ +#define MACH_MSGH_BITS_RAISED_IMPORTANCE(bits) \ + (((bits) & MACH_MSGH_BITS_RAISEIMP) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION(bits) \ + (((bits) & MACH_MSGH_BITS_IMPHOLDASRT) != MACH_MSGH_BITS_ZERO) + +/* + * Every message starts with a message header. + * Following the message header, if the message is complex, are a count + * of type descriptors and the type descriptors themselves + * (mach_msg_descriptor_t). The size of the message must be specified in + * bytes, and includes the message header, descriptor count, descriptors, + * and inline data. + * + * The msgh_remote_port field specifies the destination of the message. + * It must specify a valid send or send-once right for a port. + * + * The msgh_local_port field specifies a "reply port". Normally, + * This field carries a send-once right that the receiver will use + * to reply to the message. It may carry the values MACH_PORT_NULL, + * MACH_PORT_DEAD, a send-once right, or a send right. + * + * The msgh_voucher_port field specifies a Mach voucher port. Only + * send rights to kernel-implemented Mach Voucher kernel objects in + * addition to MACH_PORT_NULL or MACH_PORT_DEAD may be passed. + * + * The msgh_id field is uninterpreted by the message primitives. + * It normally carries information specifying the format + * or meaning of the message. + */ + +typedef unsigned int mach_msg_bits_t; +typedef natural_t mach_msg_size_t; +typedef integer_t mach_msg_id_t; + +#define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0 + +typedef unsigned int mach_msg_priority_t; + +#define MACH_MSG_PRIORITY_UNSPECIFIED (mach_msg_priority_t) 0 + + +typedef unsigned int mach_msg_type_name_t; + +#define MACH_MSG_TYPE_MOVE_RECEIVE 16 /* Must hold receive right */ +#define MACH_MSG_TYPE_MOVE_SEND 17 /* Must hold send right(s) */ +#define MACH_MSG_TYPE_MOVE_SEND_ONCE 18 /* Must hold sendonce right */ +#define MACH_MSG_TYPE_COPY_SEND 19 /* Must hold send right(s) */ +#define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ +#define MACH_MSG_TYPE_MAKE_SEND_ONCE 21 /* Must hold receive right */ +#define MACH_MSG_TYPE_COPY_RECEIVE 22 /* NOT VALID */ +#define MACH_MSG_TYPE_DISPOSE_RECEIVE 24 /* must hold receive right */ +#define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */ +#define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26 /* must hold sendonce right */ + +typedef unsigned int mach_msg_copy_options_t; + +#define MACH_MSG_PHYSICAL_COPY 0 +#define MACH_MSG_VIRTUAL_COPY 1 +#define MACH_MSG_ALLOCATE 2 +#define MACH_MSG_OVERWRITE 3 /* deprecated */ +#ifdef MACH_KERNEL +#define MACH_MSG_KALLOC_COPY_T 4 +#endif /* MACH_KERNEL */ + +#define MACH_MSG_GUARD_FLAGS_NONE 0x0000 +#define MACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE 0x0001 /* Move the receive right and mark it as immovable */ +#define MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND 0x0002 /* Verify that the port is unguarded */ +#define MACH_MSG_GUARD_FLAGS_MASK 0x0003 /* Valid flag bits */ +typedef unsigned int mach_msg_guard_flags_t; + +/* + * In a complex mach message, the mach_msg_header_t is followed by + * a descriptor count, then an array of that number of descriptors + * (mach_msg_*_descriptor_t). The type field of mach_msg_type_descriptor_t + * (which any descriptor can be cast to) indicates the flavor of the + * descriptor. + * + * Note that in LP64, the various types of descriptors are no longer all + * the same size as mach_msg_descriptor_t, so the array cannot be indexed + * as expected. + */ + +typedef unsigned int mach_msg_descriptor_type_t; + +#define MACH_MSG_PORT_DESCRIPTOR 0 +#define MACH_MSG_OOL_DESCRIPTOR 1 +#define MACH_MSG_OOL_PORTS_DESCRIPTOR 2 +#define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3 +#define MACH_MSG_GUARDED_PORT_DESCRIPTOR 4 + +#pragma pack(push, 4) + +typedef struct{ + natural_t pad1; + mach_msg_size_t pad2; + unsigned int pad3 : 24; + mach_msg_descriptor_type_t type : 8; +} mach_msg_type_descriptor_t; + +typedef struct{ + mach_port_t name; +// Pad to 8 bytes everywhere except the K64 kernel where mach_port_t is 8 bytes + mach_msg_size_t pad1; + unsigned int pad2 : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +} mach_msg_port_descriptor_t; + +typedef struct{ + uint32_t address; + mach_msg_size_t size; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + unsigned int pad1: 8; + mach_msg_descriptor_type_t type: 8; +} mach_msg_ool_descriptor32_t; + +typedef struct{ + uint64_t address; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + unsigned int pad1: 8; + mach_msg_descriptor_type_t type: 8; + mach_msg_size_t size; +} mach_msg_ool_descriptor64_t; + +typedef struct{ + void* address; +#if !defined(__LP64__) + mach_msg_size_t size; +#endif + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + unsigned int pad1: 8; + mach_msg_descriptor_type_t type: 8; +#if defined(__LP64__) + mach_msg_size_t size; +#endif +} mach_msg_ool_descriptor_t; + +typedef struct{ + uint32_t address; + mach_msg_size_t count; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +} mach_msg_ool_ports_descriptor32_t; + +typedef struct{ + uint64_t address; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; + mach_msg_size_t count; +} mach_msg_ool_ports_descriptor64_t; + +typedef struct{ + void* address; +#if !defined(__LP64__) + mach_msg_size_t count; +#endif + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +#if defined(__LP64__) + mach_msg_size_t count; +#endif +} mach_msg_ool_ports_descriptor_t; + +typedef struct{ + uint32_t context; + mach_port_name_t name; + mach_msg_guard_flags_t flags : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +} mach_msg_guarded_port_descriptor32_t; + +typedef struct{ + uint64_t context; + mach_msg_guard_flags_t flags : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; + mach_port_name_t name; +} mach_msg_guarded_port_descriptor64_t; + +typedef struct{ + mach_port_context_t context; +#if !defined(__LP64__) + mach_port_name_t name; +#endif + mach_msg_guard_flags_t flags : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +#if defined(__LP64__) + mach_port_name_t name; +#endif /* defined(__LP64__) */ +} mach_msg_guarded_port_descriptor_t; + +/* + * LP64support - This union definition is not really + * appropriate in LP64 mode because not all descriptors + * are of the same size in that environment. + */ +typedef union{ + mach_msg_port_descriptor_t port; + mach_msg_ool_descriptor_t out_of_line; + mach_msg_ool_ports_descriptor_t ool_ports; + mach_msg_type_descriptor_t type; + mach_msg_guarded_port_descriptor_t guarded_port; +} mach_msg_descriptor_t; + +typedef struct{ + mach_msg_size_t msgh_descriptor_count; +} mach_msg_body_t; + +#define MACH_MSG_BODY_NULL (mach_msg_body_t *) 0 +#define MACH_MSG_DESCRIPTOR_NULL (mach_msg_descriptor_t *) 0 + +typedef struct{ + mach_msg_bits_t msgh_bits; + mach_msg_size_t msgh_size; + mach_port_t msgh_remote_port; + mach_port_t msgh_local_port; + mach_port_name_t msgh_voucher_port; + mach_msg_id_t msgh_id; +} mach_msg_header_t; + +#define msgh_reserved msgh_voucher_port +#define MACH_MSG_NULL (mach_msg_header_t *) 0 + +typedef struct{ + mach_msg_header_t header; + mach_msg_body_t body; +} mach_msg_base_t; + +typedef unsigned int mach_msg_trailer_type_t; + +#define MACH_MSG_TRAILER_FORMAT_0 0 + +typedef unsigned int mach_msg_trailer_size_t; +typedef char *mach_msg_trailer_info_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; +} mach_msg_trailer_t; + +/* + * The msgh_seqno field carries a sequence number + * associated with the received-from port. A port's + * sequence number is incremented every time a message + * is received from it and included in the received + * trailer to help put messages back in sequence if + * multiple threads receive and/or process received + * messages. + */ +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; +} mach_msg_seqno_trailer_t; + +typedef struct{ + unsigned int val[2]; +} security_token_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; +} mach_msg_security_trailer_t; + +/* + * The audit token is an opaque token which identifies + * Mach tasks and senders of Mach messages as subjects + * to the BSM audit system. Only the appropriate BSM + * library routines should be used to interpret the + * contents of the audit token as the representation + * of the subject identity within the token may change + * over time. + */ +typedef struct{ + unsigned int val[8]; +} audit_token_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; + audit_token_t msgh_audit; +} mach_msg_audit_trailer_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; + audit_token_t msgh_audit; + mach_port_context_t msgh_context; +} mach_msg_context_trailer_t; + + + +typedef struct{ + mach_port_name_t sender; +} msg_labels_t; + +typedef int mach_msg_filter_id; +#define MACH_MSG_FILTER_POLICY_ALLOW (mach_msg_filter_id)0 + +/* + * Trailer type to pass MAC policy label info as a mach message trailer. + * + */ + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; + audit_token_t msgh_audit; + mach_port_context_t msgh_context; + mach_msg_filter_id msgh_ad; + msg_labels_t msgh_labels; +} mach_msg_mac_trailer_t; + + +#define MACH_MSG_TRAILER_MINIMUM_SIZE sizeof(mach_msg_trailer_t) + +/* + * These values can change from release to release - but clearly + * code cannot request additional trailer elements one was not + * compiled to understand. Therefore, it is safe to use this + * constant when the same module specified the receive options. + * Otherwise, you run the risk that the options requested by + * another module may exceed the local modules notion of + * MAX_TRAILER_SIZE. + */ + +typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t; +#define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t)) + +/* + * Legacy requirements keep us from ever updating these defines (even + * when the format_0 trailers gain new option data fields in the future). + * Therefore, they shouldn't be used going forward. Instead, the sizes + * should be compared against the specific element size requested using + * REQUESTED_TRAILER_SIZE. + */ +typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t; + +/*typedef mach_msg_mac_trailer_t mach_msg_format_0_trailer_t; + */ + +#define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t) + +#define KERNEL_SECURITY_TOKEN_VALUE { {0, 1} } +extern const security_token_t KERNEL_SECURITY_TOKEN; + +#define KERNEL_AUDIT_TOKEN_VALUE { {0, 0, 0, 0, 0, 0, 0, 0} } +extern const audit_token_t KERNEL_AUDIT_TOKEN; + +typedef integer_t mach_msg_options_t; + +typedef struct{ + mach_msg_header_t header; +} mach_msg_empty_send_t; + +typedef struct{ + mach_msg_header_t header; + mach_msg_trailer_t trailer; +} mach_msg_empty_rcv_t; + +typedef union{ + mach_msg_empty_send_t send; + mach_msg_empty_rcv_t rcv; +} mach_msg_empty_t; + +#pragma pack(pop) + +/* utility to round the message size - will become machine dependent */ +#define round_msg(x) (((mach_msg_size_t)(x) + sizeof (natural_t) - 1) & \ + ~(sizeof (natural_t) - 1)) + + +/* + * There is no fixed upper bound to the size of Mach messages. + */ +#define MACH_MSG_SIZE_MAX ((mach_msg_size_t) ~0) + +#if defined(__APPLE_API_PRIVATE) +/* + * But architectural limits of a given implementation, or + * temporal conditions may cause unpredictable send failures + * for messages larger than MACH_MSG_SIZE_RELIABLE. + * + * In either case, waiting for memory is [currently] outside + * the scope of send timeout values provided to IPC. + */ +#define MACH_MSG_SIZE_RELIABLE ((mach_msg_size_t) 256 * 1024) +#endif +/* + * Compatibility definitions, for code written + * when there was a msgh_kind instead of msgh_seqno. + */ +#define MACH_MSGH_KIND_NORMAL 0x00000000 +#define MACH_MSGH_KIND_NOTIFICATION 0x00000001 +#define msgh_kind msgh_seqno +#define mach_msg_kind_t mach_port_seqno_t + +typedef natural_t mach_msg_type_size_t; +typedef natural_t mach_msg_type_number_t; + +/* + * Values received/carried in messages. Tells the receiver what + * sort of port right he now has. + * + * MACH_MSG_TYPE_PORT_NAME is used to transfer a port name + * which should remain uninterpreted by the kernel. (Port rights + * are not transferred, just the port name.) + */ + +#define MACH_MSG_TYPE_PORT_NONE 0 + +#define MACH_MSG_TYPE_PORT_NAME 15 +#define MACH_MSG_TYPE_PORT_RECEIVE MACH_MSG_TYPE_MOVE_RECEIVE +#define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND +#define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE + +#define MACH_MSG_TYPE_LAST 22 /* Last assigned */ + +/* + * A dummy value. Mostly used to indicate that the actual value + * will be filled in later, dynamically. + */ + +#define MACH_MSG_TYPE_POLYMORPHIC ((mach_msg_type_name_t) -1) + +/* + * Is a given item a port type? + */ + +#define MACH_MSG_TYPE_PORT_ANY(x) \ + (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \ + ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE)) + +#define MACH_MSG_TYPE_PORT_ANY_SEND(x) \ + (((x) >= MACH_MSG_TYPE_MOVE_SEND) && \ + ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE)) + +#define MACH_MSG_TYPE_PORT_ANY_RIGHT(x) \ + (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \ + ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE)) + +typedef integer_t mach_msg_option_t; + +#define MACH_MSG_OPTION_NONE 0x00000000 + +#define MACH_SEND_MSG 0x00000001 +#define MACH_RCV_MSG 0x00000002 + +#define MACH_RCV_LARGE 0x00000004 /* report large message sizes */ +#define MACH_RCV_LARGE_IDENTITY 0x00000008 /* identify source of large messages */ + +#define MACH_SEND_TIMEOUT 0x00000010 /* timeout value applies to send */ +#define MACH_SEND_OVERRIDE 0x00000020 /* priority override for send */ +#define MACH_SEND_INTERRUPT 0x00000040 /* don't restart interrupted sends */ +#define MACH_SEND_NOTIFY 0x00000080 /* arm send-possible notify */ +#define MACH_SEND_ALWAYS 0x00010000 /* ignore qlimits - kernel only */ +#define MACH_SEND_TRAILER 0x00020000 /* sender-provided trailer */ +#define MACH_SEND_NOIMPORTANCE 0x00040000 /* msg won't carry importance */ +#define MACH_SEND_NODENAP MACH_SEND_NOIMPORTANCE +#define MACH_SEND_IMPORTANCE 0x00080000 /* msg carries importance - kernel only */ +#define MACH_SEND_SYNC_OVERRIDE 0x00100000 /* msg should do sync ipc override */ +#define MACH_SEND_PROPAGATE_QOS 0x00200000 /* IPC should propagate the caller's QoS */ +#define MACH_SEND_SYNC_USE_THRPRI MACH_SEND_PROPAGATE_QOS /* obsolete name */ +#define MACH_SEND_KERNEL 0x00400000 /* full send from kernel space - kernel only */ +#define MACH_SEND_SYNC_BOOTSTRAP_CHECKIN 0x00800000 /* special reply port should boost thread doing sync bootstrap checkin */ + +#define MACH_RCV_TIMEOUT 0x00000100 /* timeout value applies to receive */ +#define MACH_RCV_NOTIFY 0x00000000 /* legacy name (value was: 0x00000200) */ +#define MACH_RCV_INTERRUPT 0x00000400 /* don't restart interrupted receive */ +#define MACH_RCV_VOUCHER 0x00000800 /* willing to receive voucher port */ +#define MACH_RCV_OVERWRITE 0x00000000 /* scatter receive (deprecated) */ +#define MACH_RCV_GUARDED_DESC 0x00001000 /* Can receive new guarded descriptor */ +#define MACH_RCV_SYNC_WAIT 0x00004000 /* sync waiter waiting for rcv */ +#define MACH_RCV_SYNC_PEEK 0x00008000 /* sync waiter waiting to peek */ + +#define MACH_MSG_STRICT_REPLY 0x00000200 /* Enforce specific properties about the reply port, and + * the context in which a thread replies to a message. + * This flag must be passed on both the SEND and RCV */ + + +/* + * NOTE: a 0x00------ RCV mask implies to ask for + * a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements, + * which is equivalent to a mach_msg_trailer_t. + * + * XXXMAC: unlike the rest of the MACH_RCV_* flags, MACH_RCV_TRAILER_LABELS + * needs its own private bit since we only calculate its fields when absolutely + * required. + */ +#define MACH_RCV_TRAILER_NULL 0 +#define MACH_RCV_TRAILER_SEQNO 1 +#define MACH_RCV_TRAILER_SENDER 2 +#define MACH_RCV_TRAILER_AUDIT 3 +#define MACH_RCV_TRAILER_CTX 4 +#define MACH_RCV_TRAILER_AV 7 +#define MACH_RCV_TRAILER_LABELS 8 + +#define MACH_RCV_TRAILER_TYPE(x) (((x) & 0xf) << 28) +#define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24) +#define MACH_RCV_TRAILER_MASK ((0xf << 24)) + +#define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf) + + +/* + * XXXMAC: note that in the case of MACH_RCV_TRAILER_LABELS, + * we just fall through to mach_msg_max_trailer_t. + * This is correct behavior since mach_msg_max_trailer_t is defined as + * mac_msg_mac_trailer_t which is used for the LABELS trailer. + * It also makes things work properly if MACH_RCV_TRAILER_LABELS is ORed + * with one of the other options. + */ + +#define REQUESTED_TRAILER_SIZE_NATIVE(y) \ + ((mach_msg_trailer_size_t) \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ? \ + sizeof(mach_msg_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ? \ + sizeof(mach_msg_seqno_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ? \ + sizeof(mach_msg_security_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ? \ + sizeof(mach_msg_audit_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ? \ + sizeof(mach_msg_context_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ? \ + sizeof(mach_msg_mac_trailer_t) : \ + sizeof(mach_msg_max_trailer_t)))))))) + + +#define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y) + +/* + * Much code assumes that mach_msg_return_t == kern_return_t. + * This definition is useful for descriptive purposes. + * + * See for the format of error codes. + * IPC errors are system 4. Send errors are subsystem 0; + * receive errors are subsystem 1. The code field is always non-zero. + * The high bits of the code field communicate extra information + * for some error codes. MACH_MSG_MASK masks off these special bits. + */ + +typedef kern_return_t mach_msg_return_t; + +#define MACH_MSG_SUCCESS 0x00000000 + + +#define MACH_MSG_MASK 0x00003e00 +/* All special error code bits defined below. */ +#define MACH_MSG_IPC_SPACE 0x00002000 +/* No room in IPC name space for another capability name. */ +#define MACH_MSG_VM_SPACE 0x00001000 +/* No room in VM address space for out-of-line memory. */ +#define MACH_MSG_IPC_KERNEL 0x00000800 +/* Kernel resource shortage handling an IPC capability. */ +#define MACH_MSG_VM_KERNEL 0x00000400 +/* Kernel resource shortage handling out-of-line memory. */ + +#define MACH_SEND_IN_PROGRESS 0x10000001 +/* Thread is waiting to send. (Internal use only.) */ +#define MACH_SEND_INVALID_DATA 0x10000002 +/* Bogus in-line data. */ +#define MACH_SEND_INVALID_DEST 0x10000003 +/* Bogus destination port. */ +#define MACH_SEND_TIMED_OUT 0x10000004 +/* Message not sent before timeout expired. */ +#define MACH_SEND_INVALID_VOUCHER 0x10000005 +/* Bogus voucher port. */ +#define MACH_SEND_INTERRUPTED 0x10000007 +/* Software interrupt. */ +#define MACH_SEND_MSG_TOO_SMALL 0x10000008 +/* Data doesn't contain a complete message. */ +#define MACH_SEND_INVALID_REPLY 0x10000009 +/* Bogus reply port. */ +#define MACH_SEND_INVALID_RIGHT 0x1000000a +/* Bogus port rights in the message body. */ +#define MACH_SEND_INVALID_NOTIFY 0x1000000b +/* Bogus notify port argument. */ +#define MACH_SEND_INVALID_MEMORY 0x1000000c +/* Invalid out-of-line memory pointer. */ +#define MACH_SEND_NO_BUFFER 0x1000000d +/* No message buffer is available. */ +#define MACH_SEND_TOO_LARGE 0x1000000e +/* Send is too large for port */ +#define MACH_SEND_INVALID_TYPE 0x1000000f +/* Invalid msg-type specification. */ +#define MACH_SEND_INVALID_HEADER 0x10000010 +/* A field in the header had a bad value. */ +#define MACH_SEND_INVALID_TRAILER 0x10000011 +/* The trailer to be sent does not match kernel format. */ +#define MACH_SEND_INVALID_CONTEXT 0x10000012 +/* The sending thread context did not match the context on the dest port */ +#define MACH_SEND_INVALID_RT_OOL_SIZE 0x10000015 +/* compatibility: no longer a returned error */ +#define MACH_SEND_NO_GRANT_DEST 0x10000016 +/* The destination port doesn't accept ports in body */ +#define MACH_SEND_MSG_FILTERED 0x10000017 +/* Message send was rejected by message filter */ + +#define MACH_RCV_IN_PROGRESS 0x10004001 +/* Thread is waiting for receive. (Internal use only.) */ +#define MACH_RCV_INVALID_NAME 0x10004002 +/* Bogus name for receive port/port-set. */ +#define MACH_RCV_TIMED_OUT 0x10004003 +/* Didn't get a message within the timeout value. */ +#define MACH_RCV_TOO_LARGE 0x10004004 +/* Message buffer is not large enough for inline data. */ +#define MACH_RCV_INTERRUPTED 0x10004005 +/* Software interrupt. */ +#define MACH_RCV_PORT_CHANGED 0x10004006 +/* compatibility: no longer a returned error */ +#define MACH_RCV_INVALID_NOTIFY 0x10004007 +/* Bogus notify port argument. */ +#define MACH_RCV_INVALID_DATA 0x10004008 +/* Bogus message buffer for inline data. */ +#define MACH_RCV_PORT_DIED 0x10004009 +/* Port/set was sent away/died during receive. */ +#define MACH_RCV_IN_SET 0x1000400a +/* compatibility: no longer a returned error */ +#define MACH_RCV_HEADER_ERROR 0x1000400b +/* Error receiving message header. See special bits. */ +#define MACH_RCV_BODY_ERROR 0x1000400c +/* Error receiving message body. See special bits. */ +#define MACH_RCV_INVALID_TYPE 0x1000400d +/* Invalid msg-type specification in scatter list. */ +#define MACH_RCV_SCATTER_SMALL 0x1000400e +/* Out-of-line overwrite region is not large enough */ +#define MACH_RCV_INVALID_TRAILER 0x1000400f +/* trailer type or number of trailer elements not supported */ +#define MACH_RCV_IN_PROGRESS_TIMED 0x10004011 +/* Waiting for receive with timeout. (Internal use only.) */ +#define MACH_RCV_INVALID_REPLY 0x10004012 +/* invalid reply port used in a STRICT_REPLY message */ + + + +__BEGIN_DECLS + +/* + * Routine: mach_msg_overwrite + * Purpose: + * Send and/or receive a message. If the message operation + * is interrupted, and the user did not request an indication + * of that fact, then restart the appropriate parts of the + * operation silently (trap version does not restart). + * + * Distinct send and receive buffers may be specified. If + * no separate receive buffer is specified, the msg parameter + * will be used for both send and receive operations. + * + * In addition to a distinct receive buffer, that buffer may + * already contain scatter control information to direct the + * receiving of the message. + */ +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_overwrite( + mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_name_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_name_t notify, + mach_msg_header_t *rcv_msg, + mach_msg_size_t rcv_limit); + + +/* + * Routine: mach_msg + * Purpose: + * Send and/or receive a message. If the message operation + * is interrupted, and the user did not request an indication + * of that fact, then restart the appropriate parts of the + * operation silently (trap version does not restart). + */ +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg( + mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_name_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_name_t notify); + +/* + * Routine: mach_voucher_deallocate + * Purpose: + * Deallocate a mach voucher created or received in a message. Drops + * one (send right) reference to the voucher. + */ +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern kern_return_t mach_voucher_deallocate( + mach_port_name_t voucher); + + +__END_DECLS + +#endif /* _MACH_MESSAGE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/mig.h b/lib/libc/include/any-macos.11-any/mach/mig.h new file mode 100644 index 0000000000..aa7bcf7448 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/mig.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +/* + * Mach MIG Subsystem Interfaces + */ + +#ifndef _MACH_MIG_H_ +#define _MACH_MIG_H_ + +#include +#include +#include +#include + +#include + +#if defined(MACH_KERNEL) + +#if !defined(__MigTypeCheck) +/* Turn MIG type checking on by default for kernel */ +#define __MigTypeCheck 1 +#endif + +#define __MigKernelSpecificCode 1 +#define _MIG_KERNEL_SPECIFIC_CODE_ 1 + +#elif !defined(__MigTypeCheck) + +#if defined(TypeCheck) +/* use legacy setting (temporary) */ +#define __MigTypeCheck TypeCheck +#else +/* default MIG type checking on */ +#define __MigTypeCheck 1 +#endif + +#endif /* !defined(MACH_KERNEL) && !defined(__MigTypeCheck) */ + +/* + * Pack MIG message structs. + * This is an indicator of the need to view shared structs in a + * binary-compatible format - and MIG message structs are no different. + */ +#define __MigPackStructs 1 + +/* + * Definition for MIG-generated server stub routines. These routines + * unpack the request message, call the server procedure, and pack the + * reply message. + */ +typedef void (*mig_stub_routine_t) (mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +typedef mig_stub_routine_t mig_routine_t; + +/* + * Definition for MIG-generated server routine. This routine takes a + * message, and returns the appropriate stub function for handling that + * message. + */ +typedef mig_routine_t (*mig_server_routine_t) (mach_msg_header_t *InHeadP); + +/* + * Generic definition for implementation routines. These routines do + * the real work associated with this request. This generic type is + * used for keeping the pointers in the subsystem array. + */ +typedef kern_return_t (*mig_impl_routine_t)(void); + +typedef mach_msg_type_descriptor_t routine_arg_descriptor; +typedef mach_msg_type_descriptor_t *routine_arg_descriptor_t; +typedef mach_msg_type_descriptor_t *mig_routine_arg_descriptor_t; + +#define MIG_ROUTINE_ARG_DESCRIPTOR_NULL ((mig_routine_arg_descriptor_t)0) + +struct routine_descriptor { + mig_impl_routine_t impl_routine; /* Server work func pointer */ + mig_stub_routine_t stub_routine; /* Unmarshalling func pointer */ + unsigned int argc; /* Number of argument words */ + unsigned int descr_count; /* Number complex descriptors */ + routine_arg_descriptor_t + arg_descr; /* pointer to descriptor array*/ + unsigned int max_reply_msg; /* Max size for reply msg */ +}; +typedef struct routine_descriptor *routine_descriptor_t; + +typedef struct routine_descriptor mig_routine_descriptor; +typedef mig_routine_descriptor *mig_routine_descriptor_t; + +#define MIG_ROUTINE_DESCRIPTOR_NULL ((mig_routine_descriptor_t)0) + +typedef struct mig_subsystem { + mig_server_routine_t server; /* pointer to demux routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + mach_msg_size_t maxsize; /* Max reply message size */ + vm_address_t reserved; /* reserved for MIG use */ + mig_routine_descriptor + routine[1]; /* Routine descriptor array */ +} *mig_subsystem_t; + +#define MIG_SUBSYSTEM_NULL ((mig_subsystem_t)0) + +typedef struct mig_symtab { + char *ms_routine_name; + int ms_routine_number; + void (*ms_routine)(void); /* Since the functions in the + * symbol table have unknown + * signatures, this is the best + * we can do... + */ +} mig_symtab_t; + +/* + * A compiler attribute for annotating all MIG server routines and other + * functions that should behave similarly. Allows the compiler to perform + * additional static bug-finding over them. + */ +#if __has_attribute(mig_server_routine) +#define MIG_SERVER_ROUTINE __attribute__((mig_server_routine)) +#else +#define MIG_SERVER_ROUTINE +#endif + + +__BEGIN_DECLS + +/* Client side reply port allocate */ +extern mach_port_t mig_get_reply_port(void); + +/* Client side reply port deallocate */ +extern void mig_dealloc_reply_port(mach_port_t reply_port); + +/* Client side reply port "deallocation" */ +extern void mig_put_reply_port(mach_port_t reply_port); + +/* Bounded string copy */ +extern int mig_strncpy(char *dest, const char *src, int len); +extern int mig_strncpy_zerofill(char *dest, const char *src, int len); + + +/* Allocate memory for out-of-line mig structures */ +extern void mig_allocate(vm_address_t *, vm_size_t); + +/* Deallocate memory used for out-of-line mig structures */ +extern void mig_deallocate(vm_address_t, vm_size_t); + + +__END_DECLS + +#endif /* _MACH_MIG_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/port.h b/lib/libc/include/any-macos.11-any/mach/port.h new file mode 100644 index 0000000000..2a1f6443fd --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/port.h @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ +/* + */ +/* + * File: mach/port.h + * + * Definition of a Mach port + * + * Mach ports are the endpoints to Mach-implemented communications + * channels (usually uni-directional message queues, but other types + * also exist). + * + * Unique collections of these endpoints are maintained for each + * Mach task. Each Mach port in the task's collection is given a + * [task-local] name to identify it - and the the various "rights" + * held by the task for that specific endpoint. + * + * This header defines the types used to identify these Mach ports + * and the various rights associated with them. For more info see: + * + * - manipulation of port rights in a given space + * - message queue [and port right passing] mechanism + * + */ + +#ifndef _MACH_PORT_H_ +#define _MACH_PORT_H_ + +#include +#include +#include +#include + +/* + * mach_port_name_t - the local identity for a Mach port + * + * The name is Mach port namespace specific. It is used to + * identify the rights held for that port by the task whose + * namespace is implied [or specifically provided]. + * + * Use of this type usually implies just a name - no rights. + * See mach_port_t for a type that implies a "named right." + * + */ + +typedef natural_t mach_port_name_t; +typedef mach_port_name_t *mach_port_name_array_t; + + +/* + * mach_port_t - a named port right + * + * In user-space, "rights" are represented by the name of the + * right in the Mach port namespace. Even so, this type is + * presented as a unique one to more clearly denote the presence + * of a right coming along with the name. + * + * Often, various rights for a port held in a single name space + * will coalesce and are, therefore, be identified by a single name + * [this is the case for send and receive rights]. But not + * always [send-once rights currently get a unique name for + * each right]. + * + */ + +#include +#include + + +typedef mach_port_t *mach_port_array_t; + +/* + * MACH_PORT_NULL is a legal value that can be carried in messages. + * It indicates the absence of any port or port rights. (A port + * argument keeps the message from being "simple", even if the + * value is MACH_PORT_NULL.) The value MACH_PORT_DEAD is also a legal + * value that can be carried in messages. It indicates + * that a port right was present, but it died. + */ + +#define MACH_PORT_NULL 0 /* intentional loose typing */ +#define MACH_PORT_DEAD ((mach_port_name_t) ~0) +#define MACH_PORT_VALID(name) \ + (((name) != MACH_PORT_NULL) && \ + ((name) != MACH_PORT_DEAD)) + + +/* + * For kernel-selected [assigned] port names, the name is + * comprised of two parts: a generation number and an index. + * This approach keeps the exact same name from being generated + * and reused too quickly [to catch right/reference counting bugs]. + * The dividing line between the constituent parts is exposed so + * that efficient "mach_port_name_t to data structure pointer" + * conversion implementation can be made. But it is possible + * for user-level code to assign their own names to Mach ports. + * These are not required to participate in this algorithm. So + * care should be taken before "assuming" this model. + * + */ + +#ifndef NO_PORT_GEN + +#define MACH_PORT_INDEX(name) ((name) >> 8) +#define MACH_PORT_GEN(name) (((name) & 0xff) << 24) +#define MACH_PORT_MAKE(index, gen) \ + (((index) << 8) | (gen) >> 24) + +#else /* NO_PORT_GEN */ + +#define MACH_PORT_INDEX(name) (name) +#define MACH_PORT_GEN(name) (0) +#define MACH_PORT_MAKE(index, gen) (index) + +#endif /* NO_PORT_GEN */ + + +/* + * These are the different rights a task may have for a port. + * The MACH_PORT_RIGHT_* definitions are used as arguments + * to mach_port_allocate, mach_port_get_refs, etc, to specify + * a particular right to act upon. The mach_port_names and + * mach_port_type calls return bitmasks using the MACH_PORT_TYPE_* + * definitions. This is because a single name may denote + * multiple rights. + */ + +typedef natural_t mach_port_right_t; + +#define MACH_PORT_RIGHT_SEND ((mach_port_right_t) 0) +#define MACH_PORT_RIGHT_RECEIVE ((mach_port_right_t) 1) +#define MACH_PORT_RIGHT_SEND_ONCE ((mach_port_right_t) 2) +#define MACH_PORT_RIGHT_PORT_SET ((mach_port_right_t) 3) +#define MACH_PORT_RIGHT_DEAD_NAME ((mach_port_right_t) 4) +#define MACH_PORT_RIGHT_LABELH ((mach_port_right_t) 5) /* obsolete right */ +#define MACH_PORT_RIGHT_NUMBER ((mach_port_right_t) 6) /* right not implemented */ + + +typedef natural_t mach_port_type_t; +typedef mach_port_type_t *mach_port_type_array_t; + +#define MACH_PORT_TYPE(right) \ + ((mach_port_type_t)(((mach_port_type_t) 1) \ + << ((right) + ((mach_port_right_t) 16)))) +#define MACH_PORT_TYPE_NONE ((mach_port_type_t) 0L) +#define MACH_PORT_TYPE_SEND MACH_PORT_TYPE(MACH_PORT_RIGHT_SEND) +#define MACH_PORT_TYPE_RECEIVE MACH_PORT_TYPE(MACH_PORT_RIGHT_RECEIVE) +#define MACH_PORT_TYPE_SEND_ONCE MACH_PORT_TYPE(MACH_PORT_RIGHT_SEND_ONCE) +#define MACH_PORT_TYPE_PORT_SET MACH_PORT_TYPE(MACH_PORT_RIGHT_PORT_SET) +#define MACH_PORT_TYPE_DEAD_NAME MACH_PORT_TYPE(MACH_PORT_RIGHT_DEAD_NAME) +#define MACH_PORT_TYPE_LABELH MACH_PORT_TYPE(MACH_PORT_RIGHT_LABELH) /* obsolete */ + + +/* Convenient combinations. */ + +#define MACH_PORT_TYPE_SEND_RECEIVE \ + (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_RECEIVE) +#define MACH_PORT_TYPE_SEND_RIGHTS \ + (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE) +#define MACH_PORT_TYPE_PORT_RIGHTS \ + (MACH_PORT_TYPE_SEND_RIGHTS|MACH_PORT_TYPE_RECEIVE) +#define MACH_PORT_TYPE_PORT_OR_DEAD \ + (MACH_PORT_TYPE_PORT_RIGHTS|MACH_PORT_TYPE_DEAD_NAME) +#define MACH_PORT_TYPE_ALL_RIGHTS \ + (MACH_PORT_TYPE_PORT_OR_DEAD|MACH_PORT_TYPE_PORT_SET) + +/* Dummy type bits that mach_port_type/mach_port_names can return. */ + +#define MACH_PORT_TYPE_DNREQUEST 0x80000000 +#define MACH_PORT_TYPE_SPREQUEST 0x40000000 +#define MACH_PORT_TYPE_SPREQUEST_DELAYED 0x20000000 + +/* User-references for capabilities. */ + +typedef natural_t mach_port_urefs_t; +typedef integer_t mach_port_delta_t; /* change in urefs */ + +/* Attributes of ports. (See mach_port_get_receive_status.) */ + +typedef natural_t mach_port_seqno_t; /* sequence number */ +typedef natural_t mach_port_mscount_t; /* make-send count */ +typedef natural_t mach_port_msgcount_t; /* number of msgs */ +typedef natural_t mach_port_rights_t; /* number of rights */ + +/* + * Are there outstanding send rights for a given port? + */ +#define MACH_PORT_SRIGHTS_NONE 0 /* no srights */ +#define MACH_PORT_SRIGHTS_PRESENT 1 /* srights */ +typedef unsigned int mach_port_srights_t; /* status of send rights */ + +typedef struct mach_port_status { + mach_port_rights_t mps_pset; /* count of containing port sets */ + mach_port_seqno_t mps_seqno; /* sequence number */ + mach_port_mscount_t mps_mscount; /* make-send count */ + mach_port_msgcount_t mps_qlimit; /* queue limit */ + mach_port_msgcount_t mps_msgcount; /* number in the queue */ + mach_port_rights_t mps_sorights; /* how many send-once rights */ + boolean_t mps_srights; /* do send rights exist? */ + boolean_t mps_pdrequest; /* port-deleted requested? */ + boolean_t mps_nsrequest; /* no-senders requested? */ + natural_t mps_flags; /* port flags */ +} mach_port_status_t; + +/* System-wide values for setting queue limits on a port */ +#define MACH_PORT_QLIMIT_ZERO (0) +#define MACH_PORT_QLIMIT_BASIC (5) +#define MACH_PORT_QLIMIT_SMALL (16) +#define MACH_PORT_QLIMIT_LARGE (1024) +#define MACH_PORT_QLIMIT_KERNEL (65534) +#define MACH_PORT_QLIMIT_MIN MACH_PORT_QLIMIT_ZERO +#define MACH_PORT_QLIMIT_DEFAULT MACH_PORT_QLIMIT_BASIC +#define MACH_PORT_QLIMIT_MAX MACH_PORT_QLIMIT_LARGE + +typedef struct mach_port_limits { + mach_port_msgcount_t mpl_qlimit; /* number of msgs */ +} mach_port_limits_t; + +/* Possible values for mps_flags (part of mach_port_status_t) */ +#define MACH_PORT_STATUS_FLAG_TEMPOWNER 0x01 +#define MACH_PORT_STATUS_FLAG_GUARDED 0x02 +#define MACH_PORT_STATUS_FLAG_STRICT_GUARD 0x04 +#define MACH_PORT_STATUS_FLAG_IMP_DONATION 0x08 +#define MACH_PORT_STATUS_FLAG_REVIVE 0x10 +#define MACH_PORT_STATUS_FLAG_TASKPTR 0x20 +#define MACH_PORT_STATUS_FLAG_GUARD_IMMOVABLE_RECEIVE 0x40 +#define MACH_PORT_STATUS_FLAG_NO_GRANT 0x80 + +typedef struct mach_port_info_ext { + mach_port_status_t mpie_status; + mach_port_msgcount_t mpie_boost_cnt; + uint32_t reserved[6]; +} mach_port_info_ext_t; + +typedef integer_t *mach_port_info_t; /* varying array of natural_t */ + +/* Flavors for mach_port_get/set_attributes() */ +typedef int mach_port_flavor_t; +#define MACH_PORT_LIMITS_INFO 1 /* uses mach_port_limits_t */ +#define MACH_PORT_RECEIVE_STATUS 2 /* uses mach_port_status_t */ +#define MACH_PORT_DNREQUESTS_SIZE 3 /* info is int */ +#define MACH_PORT_TEMPOWNER 4 /* indicates receive right will be reassigned to another task */ +#define MACH_PORT_IMPORTANCE_RECEIVER 5 /* indicates recieve right accepts priority donation */ +#define MACH_PORT_DENAP_RECEIVER 6 /* indicates receive right accepts de-nap donation */ +#define MACH_PORT_INFO_EXT 7 /* uses mach_port_info_ext_t */ + +#define MACH_PORT_LIMITS_INFO_COUNT ((natural_t) \ + (sizeof(mach_port_limits_t)/sizeof(natural_t))) +#define MACH_PORT_RECEIVE_STATUS_COUNT ((natural_t) \ + (sizeof(mach_port_status_t)/sizeof(natural_t))) +#define MACH_PORT_DNREQUESTS_SIZE_COUNT 1 +#define MACH_PORT_INFO_EXT_COUNT ((natural_t) \ + (sizeof(mach_port_info_ext_t)/sizeof(natural_t))) +/* + * Structure used to pass information about port allocation requests. + * Must be padded to 64-bits total length. + */ +typedef struct mach_port_qos { + unsigned int name:1; /* name given */ + unsigned int prealloc:1; /* prealloced message */ + boolean_t pad1:30; + natural_t len; +} mach_port_qos_t; + +/* Mach Port Guarding definitions */ + +/* + * Flags for mach_port_options (used for + * invocation of mach_port_construct). + * Indicates attributes to be set for the newly + * allocated port. + */ +#define MPO_CONTEXT_AS_GUARD 0x01 /* Add guard to the port */ +#define MPO_QLIMIT 0x02 /* Set qlimit for the port msg queue */ +#define MPO_TEMPOWNER 0x04 /* Set the tempowner bit of the port */ +#define MPO_IMPORTANCE_RECEIVER 0x08 /* Mark the port as importance receiver */ +#define MPO_INSERT_SEND_RIGHT 0x10 /* Insert a send right for the port */ +#define MPO_STRICT 0x20 /* Apply strict guarding for port */ +#define MPO_DENAP_RECEIVER 0x40 /* Mark the port as App de-nap receiver */ +#define MPO_IMMOVABLE_RECEIVE 0x80 /* Mark the port as immovable; protected by the guard context */ +#define MPO_FILTER_MSG 0x100 /* Allow message filtering */ +#define MPO_TG_BLOCK_TRACKING 0x200 /* Track blocking relationship for thread group during sync IPC */ + +/* + * Structure to define optional attributes for a newly + * constructed port. + */ +typedef struct mach_port_options { + uint32_t flags; /* Flags defining attributes for port */ + mach_port_limits_t mpl; /* Message queue limit for port */ + union { + uint64_t reserved[2]; /* Reserved */ + mach_port_name_t work_interval_port; /* Work interval port */ + }; +}mach_port_options_t; + +typedef mach_port_options_t *mach_port_options_ptr_t; + +/* + * EXC_GUARD represents a guard violation for both + * mach ports and file descriptors. GUARD_TYPE_ is used + * to differentiate among them. + */ +#define GUARD_TYPE_MACH_PORT 0x1 + +/* Reasons for exception for a guarded mach port */ +enum mach_port_guard_exception_codes { + kGUARD_EXC_DESTROY = 1u << 0, + kGUARD_EXC_MOD_REFS = 1u << 1, + kGUARD_EXC_SET_CONTEXT = 1u << 2, + kGUARD_EXC_UNGUARDED = 1u << 3, + kGUARD_EXC_INCORRECT_GUARD = 1u << 4, + kGUARD_EXC_IMMOVABLE = 1u << 5, + kGUARD_EXC_STRICT_REPLY = 1u << 6, + kGUARD_EXC_MSG_FILTERED = 1u << 7, + /* start of [optionally] non-fatal guards */ + kGUARD_EXC_INVALID_RIGHT = 1u << 8, + kGUARD_EXC_INVALID_NAME = 1u << 9, + kGUARD_EXC_INVALID_VALUE = 1u << 10, + kGUARD_EXC_INVALID_ARGUMENT = 1u << 11, + kGUARD_EXC_RIGHT_EXISTS = 1u << 12, + kGUARD_EXC_KERN_NO_SPACE = 1u << 13, + kGUARD_EXC_KERN_FAILURE = 1u << 14, + kGUARD_EXC_KERN_RESOURCE = 1u << 15, + kGUARD_EXC_SEND_INVALID_REPLY = 1u << 16, + kGUARD_EXC_SEND_INVALID_VOUCHER = 1u << 17, + kGUARD_EXC_SEND_INVALID_RIGHT = 1u << 18, + kGUARD_EXC_RCV_INVALID_NAME = 1u << 19, + kGUARD_EXC_RCV_GUARDED_DESC = 1u << 20, /* should never be fatal; for development only */ + kGUARD_EXC_MOD_REFS_NON_FATAL = 1u << 21, + kGUARD_EXC_IMMOVABLE_NON_FATAL = 1u << 22, +}; + +#define MAX_FATAL_kGUARD_EXC_CODE (1u << 7) + +/* + * Mach port guard flags. + */ +#define MPG_FLAGS_NONE (0x00ull) + +/* + * These flags are used as bits in the subcode of kGUARD_EXC_STRICT_REPLY exceptions. + */ +#define MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_DISP (0x01ull << 56) +#define MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_PORT (0x02ull << 56) +#define MPG_FLAGS_STRICT_REPLY_INVALID_VOUCHER (0x04ull << 56) +#define MPG_FLAGS_STRICT_REPLY_NO_BANK_ATTR (0x08ull << 56) +#define MPG_FLAGS_STRICT_REPLY_MISMATCHED_PERSONA (0x10ull << 56) +#define MPG_FLAGS_STRICT_REPLY_MASK (0xffull << 56) + +/* + * These flags are used as bits in the subcode of kGUARD_EXC_MOD_REFS exceptions. + */ +#define MPG_FLAGS_MOD_REFS_PINNED_DEALLOC (0x01ull << 56) + +/* + * These flags are used as bits in the subcode of kGUARD_EXC_IMMOVABLE exceptions. + */ +#define MPG_FLAGS_IMMOVABLE_PINNED (0x01ull << 56) + +/* + * Flags for mach_port_guard_with_flags. These flags extend + * the attributes associated with a guarded port. + */ +#define MPG_STRICT 0x01 /* Apply strict guarding for a port */ +#define MPG_IMMOVABLE_RECEIVE 0x02 /* Receive right cannot be moved out of the space */ + +#if !__DARWIN_UNIX03 && !defined(_NO_PORT_T_FROM_MACH) +/* + * Mach 3.0 renamed everything to have mach_ in front of it. + * These types and macros are provided for backward compatibility + * but are deprecated. + */ +typedef mach_port_t port_t; +typedef mach_port_name_t port_name_t; +typedef mach_port_name_t *port_name_array_t; + +#define PORT_NULL ((port_t) 0) +#define PORT_DEAD ((port_t) ~0) +#define PORT_VALID(name) \ + ((port_t)(name) != PORT_NULL && (port_t)(name) != PORT_DEAD) + +#endif /* !__DARWIN_UNIX03 && !_NO_PORT_T_FROM_MACH */ + +#endif /* _MACH_PORT_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/processor.h b/lib/libc/include/any-macos.11-any/mach/processor.h new file mode 100644 index 0000000000..64cf6b97b3 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/processor.h @@ -0,0 +1,360 @@ +#ifndef _processor_user_ +#define _processor_user_ + +/* Module processor */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef processor_MSG_COUNT +#define processor_MSG_COUNT 6 +#endif /* processor_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine processor_start */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_start +( + processor_t processor +); + +/* Routine processor_exit */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_exit +( + processor_t processor +); + +/* Routine processor_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_info +( + processor_t processor, + processor_flavor_t flavor, + host_t *host, + processor_info_t processor_info_out, + mach_msg_type_number_t *processor_info_outCnt +); + +/* Routine processor_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_control +( + processor_t processor, + processor_info_t processor_cmd, + mach_msg_type_number_t processor_cmdCnt +); + +/* Routine processor_assign */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_assign +( + processor_t processor, + processor_set_t new_set, + boolean_t wait +); + +/* Routine processor_get_assignment */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_get_assignment +( + processor_t processor, + processor_set_name_t *assigned_set +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__processor_subsystem__defined +#define __Request__processor_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_start_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_exit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_flavor_t flavor; + mach_msg_type_number_t processor_info_outCnt; + } __Request__processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_msg_type_number_t processor_cmdCnt; + integer_t processor_cmd[20]; + } __Request__processor_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_set; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t wait; + } __Request__processor_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__processor_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__processor_subsystem__defined +#define __RequestUnion__processor_subsystem__defined +union __RequestUnion__processor_subsystem { + __Request__processor_start_t Request_processor_start; + __Request__processor_exit_t Request_processor_exit; + __Request__processor_info_t Request_processor_info; + __Request__processor_control_t Request_processor_control; + __Request__processor_assign_t Request_processor_assign; + __Request__processor_get_assignment_t Request_processor_get_assignment; +}; +#endif /* !__RequestUnion__processor_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__processor_subsystem__defined +#define __Reply__processor_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_start_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_exit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t host; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t processor_info_outCnt; + integer_t processor_info_out[20]; + } __Reply__processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t assigned_set; + /* end of the kernel processed data */ + } __Reply__processor_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__processor_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__processor_subsystem__defined +#define __ReplyUnion__processor_subsystem__defined +union __ReplyUnion__processor_subsystem { + __Reply__processor_start_t Reply_processor_start; + __Reply__processor_exit_t Reply_processor_exit; + __Reply__processor_info_t Reply_processor_info; + __Reply__processor_control_t Reply_processor_control; + __Reply__processor_assign_t Reply_processor_assign; + __Reply__processor_get_assignment_t Reply_processor_get_assignment; +}; +#endif /* !__RequestUnion__processor_subsystem__defined */ + +#ifndef subsystem_to_name_map_processor +#define subsystem_to_name_map_processor \ + { "processor_start", 3000 },\ + { "processor_exit", 3001 },\ + { "processor_info", 3002 },\ + { "processor_control", 3003 },\ + { "processor_assign", 3004 },\ + { "processor_get_assignment", 3005 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _processor_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/processor_set.h b/lib/libc/include/any-macos.11-any/mach/processor_set.h new file mode 100644 index 0000000000..9d748d01dc --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/processor_set.h @@ -0,0 +1,585 @@ +#ifndef _processor_set_user_ +#define _processor_set_user_ + +/* Module processor_set */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef processor_set_MSG_COUNT +#define processor_set_MSG_COUNT 11 +#endif /* processor_set_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine processor_set_statistics */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_statistics +( + processor_set_name_t pset, + processor_set_flavor_t flavor, + processor_set_info_t info_out, + mach_msg_type_number_t *info_outCnt +); + +/* Routine processor_set_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_destroy +( + processor_set_t set +); + +/* Routine processor_set_max_priority */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_max_priority +( + processor_set_t processor_set, + int max_priority, + boolean_t change_threads +); + +/* Routine processor_set_policy_enable */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_policy_enable +( + processor_set_t processor_set, + int policy +); + +/* Routine processor_set_policy_disable */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_policy_disable +( + processor_set_t processor_set, + int policy, + boolean_t change_threads +); + +/* Routine processor_set_tasks */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_tasks +( + processor_set_t processor_set, + task_array_t *task_list, + mach_msg_type_number_t *task_listCnt +); + +/* Routine processor_set_threads */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_threads +( + processor_set_t processor_set, + thread_act_array_t *thread_list, + mach_msg_type_number_t *thread_listCnt +); + +/* Routine processor_set_policy_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_policy_control +( + processor_set_t pset, + processor_set_flavor_t flavor, + processor_set_info_t policy_info, + mach_msg_type_number_t policy_infoCnt, + boolean_t change +); + +/* Routine processor_set_stack_usage */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_stack_usage +( + processor_set_t pset, + unsigned *ltotal, + vm_size_t *space, + vm_size_t *resident, + vm_size_t *maxusage, + vm_offset_t *maxstack +); + +/* Routine processor_set_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_info +( + processor_set_name_t set_name, + int flavor, + host_t *host, + processor_set_info_t info_out, + mach_msg_type_number_t *info_outCnt +); + +/* Routine processor_set_tasks_with_flavor */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_tasks_with_flavor +( + processor_set_t processor_set, + mach_task_flavor_t flavor, + task_array_t *task_list, + mach_msg_type_number_t *task_listCnt +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__processor_set_subsystem__defined +#define __Request__processor_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_set_flavor_t flavor; + mach_msg_type_number_t info_outCnt; + } __Request__processor_set_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int max_priority; + boolean_t change_threads; + } __Request__processor_set_max_priority_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int policy; + } __Request__processor_set_policy_enable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int policy; + boolean_t change_threads; + } __Request__processor_set_policy_disable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_tasks_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_threads_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_set_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[5]; + boolean_t change; + } __Request__processor_set_policy_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_stack_usage_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int flavor; + mach_msg_type_number_t info_outCnt; + } __Request__processor_set_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_task_flavor_t flavor; + } __Request__processor_set_tasks_with_flavor_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__processor_set_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__processor_set_subsystem__defined +#define __RequestUnion__processor_set_subsystem__defined +union __RequestUnion__processor_set_subsystem { + __Request__processor_set_statistics_t Request_processor_set_statistics; + __Request__processor_set_destroy_t Request_processor_set_destroy; + __Request__processor_set_max_priority_t Request_processor_set_max_priority; + __Request__processor_set_policy_enable_t Request_processor_set_policy_enable; + __Request__processor_set_policy_disable_t Request_processor_set_policy_disable; + __Request__processor_set_tasks_t Request_processor_set_tasks; + __Request__processor_set_threads_t Request_processor_set_threads; + __Request__processor_set_policy_control_t Request_processor_set_policy_control; + __Request__processor_set_stack_usage_t Request_processor_set_stack_usage; + __Request__processor_set_info_t Request_processor_set_info; + __Request__processor_set_tasks_with_flavor_t Request_processor_set_tasks_with_flavor; +}; +#endif /* !__RequestUnion__processor_set_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__processor_set_subsystem__defined +#define __Reply__processor_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t info_outCnt; + integer_t info_out[5]; + } __Reply__processor_set_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_max_priority_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_policy_enable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_policy_disable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t task_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t task_listCnt; + } __Reply__processor_set_tasks_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t thread_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t thread_listCnt; + } __Reply__processor_set_threads_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_policy_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + unsigned ltotal; + vm_size_t space; + vm_size_t resident; + vm_size_t maxusage; + vm_offset_t maxstack; + } __Reply__processor_set_stack_usage_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t host; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t info_outCnt; + integer_t info_out[5]; + } __Reply__processor_set_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t task_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t task_listCnt; + } __Reply__processor_set_tasks_with_flavor_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__processor_set_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__processor_set_subsystem__defined +#define __ReplyUnion__processor_set_subsystem__defined +union __ReplyUnion__processor_set_subsystem { + __Reply__processor_set_statistics_t Reply_processor_set_statistics; + __Reply__processor_set_destroy_t Reply_processor_set_destroy; + __Reply__processor_set_max_priority_t Reply_processor_set_max_priority; + __Reply__processor_set_policy_enable_t Reply_processor_set_policy_enable; + __Reply__processor_set_policy_disable_t Reply_processor_set_policy_disable; + __Reply__processor_set_tasks_t Reply_processor_set_tasks; + __Reply__processor_set_threads_t Reply_processor_set_threads; + __Reply__processor_set_policy_control_t Reply_processor_set_policy_control; + __Reply__processor_set_stack_usage_t Reply_processor_set_stack_usage; + __Reply__processor_set_info_t Reply_processor_set_info; + __Reply__processor_set_tasks_with_flavor_t Reply_processor_set_tasks_with_flavor; +}; +#endif /* !__RequestUnion__processor_set_subsystem__defined */ + +#ifndef subsystem_to_name_map_processor_set +#define subsystem_to_name_map_processor_set \ + { "processor_set_statistics", 4000 },\ + { "processor_set_destroy", 4001 },\ + { "processor_set_max_priority", 4002 },\ + { "processor_set_policy_enable", 4003 },\ + { "processor_set_policy_disable", 4004 },\ + { "processor_set_tasks", 4005 },\ + { "processor_set_threads", 4006 },\ + { "processor_set_policy_control", 4007 },\ + { "processor_set_stack_usage", 4008 },\ + { "processor_set_info", 4009 },\ + { "processor_set_tasks_with_flavor", 4010 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _processor_set_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/sync_policy.h b/lib/libc/include/any-macos.11-any/mach/sync_policy.h new file mode 100644 index 0000000000..a4c477bf5d --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/sync_policy.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_SYNC_POLICY_H_ +#define _MACH_SYNC_POLICY_H_ + +typedef int sync_policy_t; + +/* + * These options define the wait ordering of the synchronizers + */ +#define SYNC_POLICY_FIFO 0x0 +#define SYNC_POLICY_FIXED_PRIORITY 0x1 +#define SYNC_POLICY_REVERSED 0x2 +#define SYNC_POLICY_ORDER_MASK 0x3 +#define SYNC_POLICY_LIFO (SYNC_POLICY_FIFO|SYNC_POLICY_REVERSED) + + +#define SYNC_POLICY_MAX 0x7 + +#endif /* _MACH_SYNC_POLICY_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/task.h b/lib/libc/include/any-macos.11-any/mach/task.h index b6ae38e40c..88648e8d32 100644 --- a/lib/libc/include/any-macos.11-any/mach/task.h +++ b/lib/libc/include/any-macos.11-any/mach/task.h @@ -49,10 +49,9 @@ typedef function_table_entry *function_table_t; #endif /* AUTOTEST */ #ifndef task_MSG_COUNT -#define task_MSG_COUNT 63 +#define task_MSG_COUNT 61 #endif /* task_MSG_COUNT */ -#include #include #include #include @@ -112,7 +111,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t mach_ports_register ( task_t target_task, @@ -126,7 +126,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t mach_ports_lookup ( task_t target_task, @@ -154,7 +155,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_set_info ( task_t target_task, @@ -169,7 +171,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_suspend ( task_read_t target_task @@ -181,7 +184,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_resume ( task_read_t target_task @@ -193,7 +197,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_get_special_port ( task_inspect_t task, @@ -207,7 +212,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_set_special_port ( task_t task, @@ -221,7 +227,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t thread_create ( task_t parent_task, @@ -234,7 +241,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t thread_create_running ( task_t parent_task, @@ -250,7 +258,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_set_exception_ports ( task_t task, @@ -266,7 +275,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_get_exception_ports ( task_t task, @@ -284,7 +294,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_swap_exception_ports ( task_t task, @@ -357,7 +368,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_policy_set ( task_policy_set_t task, @@ -372,7 +384,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_policy_get ( task_policy_get_t task, @@ -470,7 +483,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_zone_info ( task_inspect_t target_task, @@ -541,7 +555,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_get_state ( task_read_t task, @@ -556,7 +571,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_set_state ( task_t task, @@ -571,7 +587,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_set_phys_footprint_limit ( task_t task, @@ -585,7 +602,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_suspend2 ( task_read_t target_task, @@ -598,7 +616,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_resume2 ( task_suspension_token_t suspend_token @@ -622,7 +641,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_get_mach_voucher ( task_read_t task, @@ -636,7 +656,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_set_mach_voucher ( task_t task, @@ -649,7 +670,8 @@ mig_external #else extern #endif /* mig_external */ -__TVOS_PROHIBITED __WATCHOS_PROHIBITED +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED kern_return_t task_swap_mach_voucher ( task_t task, @@ -892,30 +914,6 @@ kern_return_t task_get_exception_ports_info exception_flavor_array_t old_flavors ); -/* Routine task_test_sync_upcall */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t task_test_sync_upcall -( - task_t task, - mach_port_t port -); - -/* Routine task_set_corpse_forking_behavior */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t task_set_corpse_forking_behavior -( - task_t task, - task_corpse_forking_behavior_t behavior -); - __END_DECLS /********************** Caution **************************/ @@ -1714,32 +1712,6 @@ __END_DECLS #ifdef __MigPackStructs #pragma pack(pop) #endif - -#ifdef __MigPackStructs -#pragma pack(push, 4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t port; - /* end of the kernel processed data */ - } __Request__task_test_sync_upcall_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack(pop) -#endif - -#ifdef __MigPackStructs -#pragma pack(push, 4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - task_corpse_forking_behavior_t behavior; - } __Request__task_set_corpse_forking_behavior_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack(pop) -#endif #endif /* !__Request__task_subsystem__defined */ /* union of all requests */ @@ -1807,8 +1779,6 @@ union __RequestUnion__task_subsystem { __Request__task_identity_token_get_task_port_t Request_task_identity_token_get_task_port; __Request__task_dyld_process_info_notify_deregister_t Request_task_dyld_process_info_notify_deregister; __Request__task_get_exception_ports_info_t Request_task_get_exception_ports_info; - __Request__task_test_sync_upcall_t Request_task_test_sync_upcall; - __Request__task_set_corpse_forking_behavior_t Request_task_set_corpse_forking_behavior; }; #endif /* !__RequestUnion__task_subsystem__defined */ /* typedefs for all replies */ @@ -2622,30 +2592,6 @@ union __RequestUnion__task_subsystem { #ifdef __MigPackStructs #pragma pack(pop) #endif - -#ifdef __MigPackStructs -#pragma pack(push, 4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__task_test_sync_upcall_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack(pop) -#endif - -#ifdef __MigPackStructs -#pragma pack(push, 4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__task_set_corpse_forking_behavior_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack(pop) -#endif #endif /* !__Reply__task_subsystem__defined */ /* union of all replies */ @@ -2713,8 +2659,6 @@ union __ReplyUnion__task_subsystem { __Reply__task_identity_token_get_task_port_t Reply_task_identity_token_get_task_port; __Reply__task_dyld_process_info_notify_deregister_t Reply_task_dyld_process_info_notify_deregister; __Reply__task_get_exception_ports_info_t Reply_task_get_exception_ports_info; - __Reply__task_test_sync_upcall_t Reply_task_test_sync_upcall; - __Reply__task_set_corpse_forking_behavior_t Reply_task_set_corpse_forking_behavior; }; #endif /* !__RequestUnion__task_subsystem__defined */ @@ -2779,9 +2723,7 @@ union __ReplyUnion__task_subsystem { { "task_create_identity_token", 3457 },\ { "task_identity_token_get_task_port", 3458 },\ { "task_dyld_process_info_notify_deregister", 3459 },\ - { "task_get_exception_ports_info", 3460 },\ - { "task_test_sync_upcall", 3461 },\ - { "task_set_corpse_forking_behavior", 3462 } + { "task_get_exception_ports_info", 3460 } #endif #ifdef __AfterMigUserHeader diff --git a/lib/libc/include/any-macos.11-any/mach/task_info.h b/lib/libc/include/any-macos.11-any/mach/task_info.h index 0ed533e11a..6d8258ad72 100644 --- a/lib/libc/include/any-macos.11-any/mach/task_info.h +++ b/lib/libc/include/any-macos.11-any/mach/task_info.h @@ -494,7 +494,6 @@ typedef struct task_flags_info * task_flags_info_t; typedef uint32_t task_exc_guard_behavior_t; /* EXC_GUARD optional delivery settings on a per-task basis */ -#define TASK_EXC_GUARD_NONE 0x00 #define TASK_EXC_GUARD_VM_DELIVER 0x01 /* Deliver virtual memory EXC_GUARD exceptions */ #define TASK_EXC_GUARD_VM_ONCE 0x02 /* Deliver them only once */ #define TASK_EXC_GUARD_VM_CORPSE 0x04 /* Deliver them via a forked corpse */ @@ -510,15 +509,6 @@ typedef uint32_t task_exc_guard_behavior_t; #define TASK_EXC_GUARD_ALL 0xff /* All optional deliver settings */ -/* - * Type to control corpse forking options for a task - * via task_get/set_corpse_forking_behavior interface(s). - */ -typedef uint32_t task_corpse_forking_behavior_t; - -#define TASK_CORPSE_FORKING_DISABLED_MEM_DIAG 0x01 /* Disable corpse forking because the task is running under a diagnostic tool */ - - /* * Obsolete interfaces. */ diff --git a/lib/libc/include/any-macos.11-any/mach/task_inspect.h b/lib/libc/include/any-macos.11-any/mach/task_inspect.h new file mode 100644 index 0000000000..1ae3c6e5f1 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/task_inspect.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef MACH_TASK_INSPECT_H +#define MACH_TASK_INSPECT_H + +/* + * XXX These interfaces are still in development -- they are subject to change + * without notice. + */ + +typedef natural_t task_inspect_flavor_t; + +enum task_inspect_flavor { + TASK_INSPECT_BASIC_COUNTS = 1, +}; + +struct task_inspect_basic_counts { + uint64_t instructions; + uint64_t cycles; +}; +#define TASK_INSPECT_BASIC_COUNTS_COUNT \ + (sizeof(struct task_inspect_basic_counts) / sizeof(natural_t)) +typedef struct task_inspect_basic_counts task_inspect_basic_counts_data_t; +typedef struct task_inspect_basic_counts *task_inspect_basic_counts_t; + +typedef integer_t *task_inspect_info_t; + +#endif /* !defined(MACH_TASK_INSPECT_H) */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/task_special_ports.h b/lib/libc/include/any-macos.11-any/mach/task_special_ports.h new file mode 100644 index 0000000000..d80fba55b4 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/task_special_ports.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2000-2010 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/task_special_ports.h + * + * Defines codes for special_purpose task ports. These are NOT + * port identifiers - they are only used for the task_get_special_port + * and task_set_special_port routines. + * + */ + +#ifndef _MACH_TASK_SPECIAL_PORTS_H_ +#define _MACH_TASK_SPECIAL_PORTS_H_ + +typedef int task_special_port_t; + +#define TASK_KERNEL_PORT 1 /* The full task port for task. */ + +#define TASK_HOST_PORT 2 /* The host (priv) port for task. */ + +#define TASK_NAME_PORT 3 /* The name port for task. */ + +#define TASK_BOOTSTRAP_PORT 4 /* Bootstrap environment for task. */ + +#define TASK_INSPECT_PORT 5 /* The inspect port for task. */ + +#define TASK_READ_PORT 6 /* The read port for task. */ + +/* + * Evolving and likely to change. + */ + +#define TASK_SEATBELT_PORT 7 /* Seatbelt compiler/DEM port for task. */ + +/* PORT 8 was the GSSD TASK PORT which transformed to a host port */ + +#define TASK_ACCESS_PORT 9 /* Permission check for task_for_pid. */ + +#define TASK_DEBUG_CONTROL_PORT 10 /* debug control port */ + +#define TASK_RESOURCE_NOTIFY_PORT 11 /* overrides host special RN port */ + +#define TASK_MAX_SPECIAL_PORT TASK_RESOURCE_NOTIFY_PORT + +/* + * Definitions for ease of use + */ + +#define task_get_kernel_port(task, port) \ + (task_get_special_port((task), TASK_KERNEL_PORT, (port))) + +#define task_set_kernel_port(task, port) \ + (task_set_special_port((task), TASK_KERNEL_PORT, (port))) + +#define task_get_host_port(task, port) \ + (task_get_special_port((task), TASK_HOST_PORT, (port))) + +#define task_set_host_port(task, port) \ + (task_set_special_port((task), TASK_HOST_PORT, (port))) + +#define task_get_bootstrap_port(task, port) \ + (task_get_special_port((task), TASK_BOOTSTRAP_PORT, (port))) + +#define task_get_debug_control_port(task, port) \ + (task_get_special_port((task), TASK_DEBUG_CONTROL_PORT, (port))) + +#define task_set_bootstrap_port(task, port) \ + (task_set_special_port((task), TASK_BOOTSTRAP_PORT, (port))) + +#define task_get_task_access_port(task, port) \ + (task_get_special_port((task), TASK_ACCESS_PORT, (port))) + +#define task_set_task_access_port(task, port) \ + (task_set_special_port((task), TASK_ACCESS_PORT, (port))) + +#define task_set_task_debug_control_port(task, port) \ + (task_set_special_port((task), TASK_DEBUG_CONTROL_PORT, (port))) + + +#endif /* _MACH_TASK_SPECIAL_PORTS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/thread_act.h b/lib/libc/include/any-macos.11-any/mach/thread_act.h new file mode 100644 index 0000000000..8264d64fcb --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/thread_act.h @@ -0,0 +1,1435 @@ +#ifndef _thread_act_user_ +#define _thread_act_user_ + +/* Module thread_act */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef thread_act_MSG_COUNT +#define thread_act_MSG_COUNT 31 +#endif /* thread_act_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine thread_terminate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_terminate +( + thread_act_t target_act +); + +/* Routine act_get_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t act_get_state +( + thread_read_t target_act, + int flavor, + thread_state_t old_state, + mach_msg_type_number_t *old_stateCnt +); + +/* Routine act_set_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t act_set_state +( + thread_act_t target_act, + int flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt +); + +/* Routine thread_get_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_get_state +( + thread_read_t target_act, + thread_state_flavor_t flavor, + thread_state_t old_state, + mach_msg_type_number_t *old_stateCnt +); + +/* Routine thread_set_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_set_state +( + thread_act_t target_act, + thread_state_flavor_t flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt +); + +/* Routine thread_suspend */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_suspend +( + thread_read_t target_act +); + +/* Routine thread_resume */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_resume +( + thread_read_t target_act +); + +/* Routine thread_abort */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_abort +( + thread_act_t target_act +); + +/* Routine thread_abort_safely */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_abort_safely +( + thread_act_t target_act +); + +/* Routine thread_depress_abort */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_depress_abort +( + thread_act_t thread +); + +/* Routine thread_get_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_get_special_port +( + thread_inspect_t thr_act, + int which_port, + mach_port_t *special_port +); + +/* Routine thread_set_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_set_special_port +( + thread_act_t thr_act, + int which_port, + mach_port_t special_port +); + +/* Routine thread_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_info +( + thread_inspect_t target_act, + thread_flavor_t flavor, + thread_info_t thread_info_out, + mach_msg_type_number_t *thread_info_outCnt +); + +/* Routine thread_set_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_set_exception_ports +( + thread_act_t thread, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor +); + +/* Routine thread_get_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_get_exception_ports +( + thread_act_t thread, + exception_mask_t exception_mask, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine thread_swap_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_swap_exception_ports +( + thread_act_t thread, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine thread_policy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_policy +( + thread_act_t thr_act, + policy_t policy, + policy_base_t base, + mach_msg_type_number_t baseCnt, + boolean_t set_limit +); + +/* Routine thread_policy_set */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_policy_set +( + thread_act_t thread, + thread_policy_flavor_t flavor, + thread_policy_t policy_info, + mach_msg_type_number_t policy_infoCnt +); + +/* Routine thread_policy_get */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_policy_get +( + thread_inspect_t thread, + thread_policy_flavor_t flavor, + thread_policy_t policy_info, + mach_msg_type_number_t *policy_infoCnt, + boolean_t *get_default +); + +/* Routine thread_sample */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_sample +( + thread_act_t thread, + mach_port_t reply +); + +/* Routine etap_trace_thread */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t etap_trace_thread +( + thread_act_t target_act, + boolean_t trace_status +); + +/* Routine thread_assign */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_assign +( + thread_act_t thread, + processor_set_t new_set +); + +/* Routine thread_assign_default */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_assign_default +( + thread_act_t thread +); + +/* Routine thread_get_assignment */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_get_assignment +( + thread_inspect_t thread, + processor_set_name_t *assigned_set +); + +/* Routine thread_set_policy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_set_policy +( + thread_act_t thr_act, + processor_set_t pset, + policy_t policy, + policy_base_t base, + mach_msg_type_number_t baseCnt, + policy_limit_t limit, + mach_msg_type_number_t limitCnt +); + +/* Routine thread_get_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_get_mach_voucher +( + thread_read_t thr_act, + mach_voucher_selector_t which, + ipc_voucher_t *voucher +); + +/* Routine thread_set_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_set_mach_voucher +( + thread_act_t thr_act, + ipc_voucher_t voucher +); + +/* Routine thread_swap_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_swap_mach_voucher +( + thread_act_t thr_act, + ipc_voucher_t new_voucher, + ipc_voucher_t *old_voucher +); + +/* Routine thread_convert_thread_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_convert_thread_state +( + thread_act_t thread, + int direction, + thread_state_flavor_t flavor, + thread_state_t in_state, + mach_msg_type_number_t in_stateCnt, + thread_state_t out_state, + mach_msg_type_number_t *out_stateCnt +); + +/* Routine thread_get_exception_ports_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_get_exception_ports_info +( + mach_port_t port, + exception_mask_t exception_mask, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_info_array_t old_handlers_info, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__thread_act_subsystem__defined +#define __Request__thread_act_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_terminate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int flavor; + mach_msg_type_number_t old_stateCnt; + } __Request__act_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[1296]; + } __Request__act_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t old_stateCnt; + } __Request__thread_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[1296]; + } __Request__thread_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_suspend_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_resume_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_abort_safely_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_depress_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int which_port; + } __Request__thread_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t special_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + int which_port; + } __Request__thread_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_flavor_t flavor; + mach_msg_type_number_t thread_info_outCnt; + } __Request__thread_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__thread_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_mask_t exception_mask; + } __Request__thread_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__thread_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + policy_t policy; + mach_msg_type_number_t baseCnt; + integer_t base[5]; + boolean_t set_limit; + } __Request__thread_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_policy_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[16]; + } __Request__thread_policy_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_policy_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + boolean_t get_default; + } __Request__thread_policy_get_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t reply; + /* end of the kernel processed data */ + } __Request__thread_sample_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + boolean_t trace_status; + } __Request__etap_trace_thread_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_set; + /* end of the kernel processed data */ + } __Request__thread_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_assign_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t pset; + /* end of the kernel processed data */ + NDR_record_t NDR; + policy_t policy; + mach_msg_type_number_t baseCnt; + integer_t base[5]; + mach_msg_type_number_t limitCnt; + integer_t limit[1]; + } __Request__thread_set_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_voucher_selector_t which; + } __Request__thread_get_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t voucher; + /* end of the kernel processed data */ + } __Request__thread_set_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t new_voucher; + mach_msg_port_descriptor_t old_voucher; + /* end of the kernel processed data */ + } __Request__thread_swap_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int direction; + thread_state_flavor_t flavor; + mach_msg_type_number_t in_stateCnt; + natural_t in_state[1296]; + mach_msg_type_number_t out_stateCnt; + } __Request__thread_convert_thread_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_mask_t exception_mask; + } __Request__thread_get_exception_ports_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__thread_act_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__thread_act_subsystem__defined +#define __RequestUnion__thread_act_subsystem__defined +union __RequestUnion__thread_act_subsystem { + __Request__thread_terminate_t Request_thread_terminate; + __Request__act_get_state_t Request_act_get_state; + __Request__act_set_state_t Request_act_set_state; + __Request__thread_get_state_t Request_thread_get_state; + __Request__thread_set_state_t Request_thread_set_state; + __Request__thread_suspend_t Request_thread_suspend; + __Request__thread_resume_t Request_thread_resume; + __Request__thread_abort_t Request_thread_abort; + __Request__thread_abort_safely_t Request_thread_abort_safely; + __Request__thread_depress_abort_t Request_thread_depress_abort; + __Request__thread_get_special_port_t Request_thread_get_special_port; + __Request__thread_set_special_port_t Request_thread_set_special_port; + __Request__thread_info_t Request_thread_info; + __Request__thread_set_exception_ports_t Request_thread_set_exception_ports; + __Request__thread_get_exception_ports_t Request_thread_get_exception_ports; + __Request__thread_swap_exception_ports_t Request_thread_swap_exception_ports; + __Request__thread_policy_t Request_thread_policy; + __Request__thread_policy_set_t Request_thread_policy_set; + __Request__thread_policy_get_t Request_thread_policy_get; + __Request__thread_sample_t Request_thread_sample; + __Request__etap_trace_thread_t Request_etap_trace_thread; + __Request__thread_assign_t Request_thread_assign; + __Request__thread_assign_default_t Request_thread_assign_default; + __Request__thread_get_assignment_t Request_thread_get_assignment; + __Request__thread_set_policy_t Request_thread_set_policy; + __Request__thread_get_mach_voucher_t Request_thread_get_mach_voucher; + __Request__thread_set_mach_voucher_t Request_thread_set_mach_voucher; + __Request__thread_swap_mach_voucher_t Request_thread_swap_mach_voucher; + __Request__thread_convert_thread_state_t Request_thread_convert_thread_state; + __Request__thread_get_exception_ports_info_t Request_thread_get_exception_ports_info; +}; +#endif /* !__RequestUnion__thread_act_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__thread_act_subsystem__defined +#define __Reply__thread_act_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_terminate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[1296]; + } __Reply__act_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__act_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[1296]; + } __Reply__thread_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_suspend_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_resume_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_abort_safely_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_depress_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t special_port; + /* end of the kernel processed data */ + } __Reply__thread_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t thread_info_outCnt; + integer_t thread_info_out[32]; + } __Reply__thread_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__thread_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__thread_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_policy_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[16]; + boolean_t get_default; + } __Reply__thread_policy_get_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_sample_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__etap_trace_thread_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_assign_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t assigned_set; + /* end of the kernel processed data */ + } __Reply__thread_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t voucher; + /* end of the kernel processed data */ + } __Reply__thread_get_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t old_voucher; + /* end of the kernel processed data */ + } __Reply__thread_swap_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t out_stateCnt; + natural_t out_state[1296]; + } __Reply__thread_convert_thread_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_handler_info_t old_handlers_info[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__thread_get_exception_ports_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__thread_act_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__thread_act_subsystem__defined +#define __ReplyUnion__thread_act_subsystem__defined +union __ReplyUnion__thread_act_subsystem { + __Reply__thread_terminate_t Reply_thread_terminate; + __Reply__act_get_state_t Reply_act_get_state; + __Reply__act_set_state_t Reply_act_set_state; + __Reply__thread_get_state_t Reply_thread_get_state; + __Reply__thread_set_state_t Reply_thread_set_state; + __Reply__thread_suspend_t Reply_thread_suspend; + __Reply__thread_resume_t Reply_thread_resume; + __Reply__thread_abort_t Reply_thread_abort; + __Reply__thread_abort_safely_t Reply_thread_abort_safely; + __Reply__thread_depress_abort_t Reply_thread_depress_abort; + __Reply__thread_get_special_port_t Reply_thread_get_special_port; + __Reply__thread_set_special_port_t Reply_thread_set_special_port; + __Reply__thread_info_t Reply_thread_info; + __Reply__thread_set_exception_ports_t Reply_thread_set_exception_ports; + __Reply__thread_get_exception_ports_t Reply_thread_get_exception_ports; + __Reply__thread_swap_exception_ports_t Reply_thread_swap_exception_ports; + __Reply__thread_policy_t Reply_thread_policy; + __Reply__thread_policy_set_t Reply_thread_policy_set; + __Reply__thread_policy_get_t Reply_thread_policy_get; + __Reply__thread_sample_t Reply_thread_sample; + __Reply__etap_trace_thread_t Reply_etap_trace_thread; + __Reply__thread_assign_t Reply_thread_assign; + __Reply__thread_assign_default_t Reply_thread_assign_default; + __Reply__thread_get_assignment_t Reply_thread_get_assignment; + __Reply__thread_set_policy_t Reply_thread_set_policy; + __Reply__thread_get_mach_voucher_t Reply_thread_get_mach_voucher; + __Reply__thread_set_mach_voucher_t Reply_thread_set_mach_voucher; + __Reply__thread_swap_mach_voucher_t Reply_thread_swap_mach_voucher; + __Reply__thread_convert_thread_state_t Reply_thread_convert_thread_state; + __Reply__thread_get_exception_ports_info_t Reply_thread_get_exception_ports_info; +}; +#endif /* !__RequestUnion__thread_act_subsystem__defined */ + +#ifndef subsystem_to_name_map_thread_act +#define subsystem_to_name_map_thread_act \ + { "thread_terminate", 3600 },\ + { "act_get_state", 3601 },\ + { "act_set_state", 3602 },\ + { "thread_get_state", 3603 },\ + { "thread_set_state", 3604 },\ + { "thread_suspend", 3605 },\ + { "thread_resume", 3606 },\ + { "thread_abort", 3607 },\ + { "thread_abort_safely", 3608 },\ + { "thread_depress_abort", 3609 },\ + { "thread_get_special_port", 3610 },\ + { "thread_set_special_port", 3611 },\ + { "thread_info", 3612 },\ + { "thread_set_exception_ports", 3613 },\ + { "thread_get_exception_ports", 3614 },\ + { "thread_swap_exception_ports", 3615 },\ + { "thread_policy", 3616 },\ + { "thread_policy_set", 3617 },\ + { "thread_policy_get", 3618 },\ + { "thread_sample", 3619 },\ + { "etap_trace_thread", 3620 },\ + { "thread_assign", 3621 },\ + { "thread_assign_default", 3622 },\ + { "thread_get_assignment", 3623 },\ + { "thread_set_policy", 3624 },\ + { "thread_get_mach_voucher", 3625 },\ + { "thread_set_mach_voucher", 3626 },\ + { "thread_swap_mach_voucher", 3627 },\ + { "thread_convert_thread_state", 3628 },\ + { "thread_get_exception_ports_info", 3630 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _thread_act_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/thread_policy.h b/lib/libc/include/any-macos.11-any/mach/thread_policy.h new file mode 100644 index 0000000000..e15504cff4 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/thread_policy.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_THREAD_POLICY_H_ +#define _MACH_THREAD_POLICY_H_ + +#include + +/* + * These are the calls for accessing the policy parameters + * of a particular thread. + * + * The extra 'get_default' parameter to the second call is + * IN/OUT as follows: + * 1) if asserted on the way in it indicates that the default + * values should be returned, not the ones currently set, in + * this case 'get_default' will always be asserted on return; + * 2) if unasserted on the way in, the current settings are + * desired and if still unasserted on return, then the info + * returned reflects the current settings, otherwise if + * 'get_default' returns asserted, it means that there are no + * current settings due to other parameters taking precedence, + * and the default ones are being returned instead. + */ + +typedef natural_t thread_policy_flavor_t; +typedef integer_t *thread_policy_t; + +/* + * kern_return_t thread_policy_set( + * thread_t thread, + * thread_policy_flavor_t flavor, + * thread_policy_t policy_info, + * mach_msg_type_number_t count); + * + * kern_return_t thread_policy_get( + * thread_t thread, + * thread_policy_flavor_t flavor, + * thread_policy_t policy_info, + * mach_msg_type_number_t *count, + * boolean_t *get_default); + */ + +/* + * Defined flavors. + */ +/* + * THREAD_STANDARD_POLICY: + * + * This is the standard (fair) scheduling mode, assigned to new + * threads. The thread will be given processor time in a manner + * which apportions approximately equal share to long running + * computations. + * + * Parameters: + * [none] + */ + +#define THREAD_STANDARD_POLICY 1 + +struct thread_standard_policy { + natural_t no_data; +}; + +typedef struct thread_standard_policy thread_standard_policy_data_t; +typedef struct thread_standard_policy *thread_standard_policy_t; + +#define THREAD_STANDARD_POLICY_COUNT 0 + +/* + * THREAD_EXTENDED_POLICY: + * + * Extended form of THREAD_STANDARD_POLICY, which supplies a + * hint indicating whether this is a long running computation. + * + * Parameters: + * + * timeshare: TRUE (the default) results in identical scheduling + * behavior as THREAD_STANDARD_POLICY. + */ + +#define THREAD_EXTENDED_POLICY 1 + +struct thread_extended_policy { + boolean_t timeshare; +}; + +typedef struct thread_extended_policy thread_extended_policy_data_t; +typedef struct thread_extended_policy *thread_extended_policy_t; + +#define THREAD_EXTENDED_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_extended_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_TIME_CONSTRAINT_POLICY: + * + * This scheduling mode is for threads which have real time + * constraints on their execution. + * + * Parameters: + * + * period: This is the nominal amount of time between separate + * processing arrivals, specified in absolute time units. A + * value of 0 indicates that there is no inherent periodicity in + * the computation. + * + * computation: This is the nominal amount of computation + * time needed during a separate processing arrival, specified + * in absolute time units. + * + * constraint: This is the maximum amount of real time that + * may elapse from the start of a separate processing arrival + * to the end of computation for logically correct functioning, + * specified in absolute time units. Must be (>= computation). + * Note that latency = (constraint - computation). + * + * preemptible: This indicates that the computation may be + * interrupted, subject to the constraint specified above. + */ + +#define THREAD_TIME_CONSTRAINT_POLICY 2 + +struct thread_time_constraint_policy { + uint32_t period; + uint32_t computation; + uint32_t constraint; + boolean_t preemptible; +}; + +typedef struct thread_time_constraint_policy \ + thread_time_constraint_policy_data_t; +typedef struct thread_time_constraint_policy \ + *thread_time_constraint_policy_t; + +#define THREAD_TIME_CONSTRAINT_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_time_constraint_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_PRECEDENCE_POLICY: + * + * This may be used to indicate the relative value of the + * computation compared to the other threads in the task. + * + * Parameters: + * + * importance: The importance is specified as a signed value. + */ + +#define THREAD_PRECEDENCE_POLICY 3 + +struct thread_precedence_policy { + integer_t importance; +}; + +typedef struct thread_precedence_policy thread_precedence_policy_data_t; +typedef struct thread_precedence_policy *thread_precedence_policy_t; + +#define THREAD_PRECEDENCE_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_precedence_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_AFFINITY_POLICY: + * + * This policy is experimental. + * This may be used to express affinity relationships + * between threads in the task. Threads with the same affinity tag will + * be scheduled to share an L2 cache if possible. That is, affinity tags + * are a hint to the scheduler for thread placement. + * + * The namespace of affinity tags is generally local to one task. However, + * a child task created after the assignment of affinity tags by its parent + * will share that namespace. In particular, a family of forked processes + * may be created with a shared affinity namespace. + * + * Parameters: + * tag: The affinity set identifier. + */ + +#define THREAD_AFFINITY_POLICY 4 + +struct thread_affinity_policy { + integer_t affinity_tag; +}; + +#define THREAD_AFFINITY_TAG_NULL 0 + +typedef struct thread_affinity_policy thread_affinity_policy_data_t; +typedef struct thread_affinity_policy *thread_affinity_policy_t; + +#define THREAD_AFFINITY_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_affinity_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_BACKGROUND_POLICY: + */ + +#define THREAD_BACKGROUND_POLICY 5 + +struct thread_background_policy { + integer_t priority; +}; + +#define THREAD_BACKGROUND_POLICY_DARWIN_BG 0x1000 + +typedef struct thread_background_policy thread_background_policy_data_t; +typedef struct thread_background_policy *thread_background_policy_t; + +#define THREAD_BACKGROUND_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_background_policy_data_t) / sizeof (integer_t))) + + +#define THREAD_LATENCY_QOS_POLICY 7 +typedef integer_t thread_latency_qos_t; + +struct thread_latency_qos_policy { + thread_latency_qos_t thread_latency_qos_tier; +}; + +typedef struct thread_latency_qos_policy thread_latency_qos_policy_data_t; +typedef struct thread_latency_qos_policy *thread_latency_qos_policy_t; + +#define THREAD_LATENCY_QOS_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_latency_qos_policy_data_t) / sizeof (integer_t))) + +#define THREAD_THROUGHPUT_QOS_POLICY 8 +typedef integer_t thread_throughput_qos_t; + +struct thread_throughput_qos_policy { + thread_throughput_qos_t thread_throughput_qos_tier; +}; + +typedef struct thread_throughput_qos_policy thread_throughput_qos_policy_data_t; +typedef struct thread_throughput_qos_policy *thread_throughput_qos_policy_t; + +#define THREAD_THROUGHPUT_QOS_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_throughput_qos_policy_data_t) / sizeof (integer_t))) + + + + +#endif /* _MACH_THREAD_POLICY_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/thread_state.h b/lib/libc/include/any-macos.11-any/mach/thread_state.h new file mode 100644 index 0000000000..33b38b8665 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/thread_state.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_THREAD_STATE_H_ +#define _MACH_THREAD_STATE_H_ + +#include +#include + +#ifndef KERNEL +/* + * Gets all register values in the target thread with pointer-like contents. + * + * There is no guarantee that the returned values are valid pointers, but all + * valid pointers will be returned. The order and count of the provided + * register values is unspecified and may change; registers with values that + * are not valid pointers may be omitted, so the number of pointers returned + * may vary from call to call. + * + * sp is an out parameter that will contain the stack pointer. + * length is an in/out parameter for the length of the values array. + * values is an array of pointers. + * + * This may only be called on threads in the current task. If the current + * platform defines a stack red zone, the stack pointer returned will be + * adjusted to account for red zone. + * + * If length is insufficient, KERN_INSUFFICIENT_BUFFER_SIZE will be returned + * and length set to the amount of memory required. Callers MUST NOT assume + * that any particular size of buffer will be sufficient and should retry with + * an appropriately sized buffer upon this error. + */ +__API_AVAILABLE(macosx(10.14), ios(12.0), tvos(9.0), watchos(5.0)) +kern_return_t thread_get_register_pointer_values(thread_t thread, + uintptr_t *sp, size_t *length, uintptr_t *values); +#endif + +#endif /* _MACH_THREAD_STATE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/vm_map.h b/lib/libc/include/any-macos.11-any/mach/vm_map.h new file mode 100644 index 0000000000..7906d76f63 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/vm_map.h @@ -0,0 +1,1503 @@ +#ifndef _vm_map_user_ +#define _vm_map_user_ + +/* Module vm_map */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef vm_map_MSG_COUNT +#define vm_map_MSG_COUNT 33 +#endif /* vm_map_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine vm_region */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t *size, + vm_region_flavor_t flavor, + vm_region_info_t info, + mach_msg_type_number_t *infoCnt, + mach_port_t *object_name +); + +/* Routine vm_allocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_allocate +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t size, + int flags +); + +/* Routine vm_deallocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_deallocate +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size +); + +/* Routine vm_protect */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_protect +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + boolean_t set_maximum, + vm_prot_t new_protection +); + +/* Routine vm_inherit */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_inherit +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_inherit_t new_inheritance +); + +/* Routine vm_read */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_read +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_offset_t *data, + mach_msg_type_number_t *dataCnt +); + +/* Routine vm_read_list */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_read_list +( + vm_map_t target_task, + vm_read_entry_t data_list, + natural_t count +); + +/* Routine vm_write */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_write +( + vm_map_t target_task, + vm_address_t address, + vm_offset_t data, + mach_msg_type_number_t dataCnt +); + +/* Routine vm_copy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_copy +( + vm_map_t target_task, + vm_address_t source_address, + vm_size_t size, + vm_address_t dest_address +); + +/* Routine vm_read_overwrite */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_read_overwrite +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_address_t data, + vm_size_t *outsize +); + +/* Routine vm_msync */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_msync +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_sync_t sync_flags +); + +/* Routine vm_behavior_set */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_behavior_set +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_behavior_t new_behavior +); + +/* Routine vm_map */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t size, + vm_address_t mask, + int flags, + mem_entry_name_port_t object, + vm_offset_t offset, + boolean_t copy, + vm_prot_t cur_protection, + vm_prot_t max_protection, + vm_inherit_t inheritance +); + +/* Routine vm_machine_attribute */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_machine_attribute +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_machine_attribute_t attribute, + vm_machine_attribute_val_t *value +); + +/* Routine vm_remap */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_remap +( + vm_map_t target_task, + vm_address_t *target_address, + vm_size_t size, + vm_address_t mask, + int flags, + vm_map_t src_task, + vm_address_t src_address, + boolean_t copy, + vm_prot_t *cur_protection, + vm_prot_t *max_protection, + vm_inherit_t inheritance +); + +/* Routine task_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_wire +( + vm_map_t target_task, + boolean_t must_wire +); + +/* Routine mach_make_memory_entry */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_make_memory_entry +( + vm_map_t target_task, + vm_size_t *size, + vm_offset_t offset, + vm_prot_t permission, + mem_entry_name_port_t *object_handle, + mem_entry_name_port_t parent_entry +); + +/* Routine vm_map_page_query */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map_page_query +( + vm_map_t target_map, + vm_offset_t offset, + integer_t *disposition, + integer_t *ref_count +); + +/* Routine mach_vm_region_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_region_info +( + vm_map_t task, + vm_address_t address, + vm_info_region_t *region, + vm_info_object_array_t *objects, + mach_msg_type_number_t *objectsCnt +); + +/* Routine vm_mapped_pages_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_mapped_pages_info +( + vm_map_t task, + page_address_array_t *pages, + mach_msg_type_number_t *pagesCnt +); + +/* Routine vm_region_recurse */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region_recurse +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t *size, + natural_t *nesting_depth, + vm_region_recurse_info_t info, + mach_msg_type_number_t *infoCnt +); + +/* Routine vm_region_recurse_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region_recurse_64 +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t *size, + natural_t *nesting_depth, + vm_region_recurse_info_t info, + mach_msg_type_number_t *infoCnt +); + +/* Routine mach_vm_region_info_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_region_info_64 +( + vm_map_t task, + vm_address_t address, + vm_info_region_64_t *region, + vm_info_object_array_t *objects, + mach_msg_type_number_t *objectsCnt +); + +/* Routine vm_region_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region_64 +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t *size, + vm_region_flavor_t flavor, + vm_region_info_t info, + mach_msg_type_number_t *infoCnt, + mach_port_t *object_name +); + +/* Routine mach_make_memory_entry_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_make_memory_entry_64 +( + vm_map_t target_task, + memory_object_size_t *size, + memory_object_offset_t offset, + vm_prot_t permission, + mach_port_t *object_handle, + mem_entry_name_port_t parent_entry +); + +/* Routine vm_map_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map_64 +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t size, + vm_address_t mask, + int flags, + mem_entry_name_port_t object, + memory_object_offset_t offset, + boolean_t copy, + vm_prot_t cur_protection, + vm_prot_t max_protection, + vm_inherit_t inheritance +); + +/* Routine vm_purgable_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_purgable_control +( + vm_map_t target_task, + vm_address_t address, + vm_purgable_t control, + int *state +); + +/* Routine vm_map_exec_lockdown */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map_exec_lockdown +( + vm_map_t target_task +); + +/* Routine vm_remap_new */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_remap_new +( + vm_map_t target_task, + vm_address_t *target_address, + vm_size_t size, + vm_address_t mask, + int flags, + vm_map_read_t src_task, + vm_address_t src_address, + boolean_t copy, + vm_prot_t *cur_protection, + vm_prot_t *max_protection, + vm_inherit_t inheritance +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__vm_map_subsystem__defined +#define __Request__vm_map_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_region_flavor_t flavor; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + int flags; + } __Request__vm_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + } __Request__vm_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + boolean_t set_maximum; + vm_prot_t new_protection; + } __Request__vm_protect_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_inherit_t new_inheritance; + } __Request__vm_inherit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + } __Request__vm_read_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_read_entry_t data_list; + natural_t count; + } __Request__vm_read_list_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t data; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + mach_msg_type_number_t dataCnt; + } __Request__vm_write_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t source_address; + vm_size_t size; + vm_address_t dest_address; + } __Request__vm_copy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_address_t data; + } __Request__vm_read_overwrite_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_sync_t sync_flags; + } __Request__vm_msync_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_behavior_t new_behavior; + } __Request__vm_behavior_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_address_t mask; + int flags; + vm_offset_t offset; + boolean_t copy; + vm_prot_t cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__vm_map_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_machine_attribute_t attribute; + vm_machine_attribute_val_t value; + } __Request__vm_machine_attribute_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t src_task; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t target_address; + vm_size_t size; + vm_address_t mask; + int flags; + vm_address_t src_address; + boolean_t copy; + vm_inherit_t inheritance; + } __Request__vm_remap_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + boolean_t must_wire; + } __Request__task_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t parent_entry; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_size_t size; + vm_offset_t offset; + vm_prot_t permission; + } __Request__mach_make_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_offset_t offset; + } __Request__vm_map_page_query_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + } __Request__mach_vm_region_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__vm_mapped_pages_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_recurse_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_recurse_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + } __Request__mach_vm_region_info_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_region_flavor_t flavor; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t parent_entry; + /* end of the kernel processed data */ + NDR_record_t NDR; + memory_object_size_t size; + memory_object_offset_t offset; + vm_prot_t permission; + } __Request__mach_make_memory_entry_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_address_t mask; + int flags; + memory_object_offset_t offset; + boolean_t copy; + vm_prot_t cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__vm_map_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_purgable_t control; + int state; + } __Request__vm_purgable_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__vm_map_exec_lockdown_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t src_task; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t target_address; + vm_size_t size; + vm_address_t mask; + int flags; + vm_address_t src_address; + boolean_t copy; + vm_prot_t cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__vm_remap_new_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__vm_map_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__vm_map_subsystem__defined +#define __RequestUnion__vm_map_subsystem__defined +union __RequestUnion__vm_map_subsystem { + __Request__vm_region_t Request_vm_region; + __Request__vm_allocate_t Request_vm_allocate; + __Request__vm_deallocate_t Request_vm_deallocate; + __Request__vm_protect_t Request_vm_protect; + __Request__vm_inherit_t Request_vm_inherit; + __Request__vm_read_t Request_vm_read; + __Request__vm_read_list_t Request_vm_read_list; + __Request__vm_write_t Request_vm_write; + __Request__vm_copy_t Request_vm_copy; + __Request__vm_read_overwrite_t Request_vm_read_overwrite; + __Request__vm_msync_t Request_vm_msync; + __Request__vm_behavior_set_t Request_vm_behavior_set; + __Request__vm_map_t Request_vm_map; + __Request__vm_machine_attribute_t Request_vm_machine_attribute; + __Request__vm_remap_t Request_vm_remap; + __Request__task_wire_t Request_task_wire; + __Request__mach_make_memory_entry_t Request_mach_make_memory_entry; + __Request__vm_map_page_query_t Request_vm_map_page_query; + __Request__mach_vm_region_info_t Request_mach_vm_region_info; + __Request__vm_mapped_pages_info_t Request_vm_mapped_pages_info; + __Request__vm_region_recurse_t Request_vm_region_recurse; + __Request__vm_region_recurse_64_t Request_vm_region_recurse_64; + __Request__mach_vm_region_info_64_t Request_mach_vm_region_info_64; + __Request__vm_region_64_t Request_vm_region_64; + __Request__mach_make_memory_entry_64_t Request_mach_make_memory_entry_64; + __Request__vm_map_64_t Request_vm_map_64; + __Request__vm_purgable_control_t Request_vm_purgable_control; + __Request__vm_map_exec_lockdown_t Request_vm_map_exec_lockdown; + __Request__vm_remap_new_t Request_vm_remap_new; +}; +#endif /* !__RequestUnion__vm_map_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__vm_map_subsystem__defined +#define __Reply__vm_map_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object_name; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + mach_msg_type_number_t infoCnt; + int info[10]; + } __Reply__vm_region_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_protect_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_inherit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t data; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t dataCnt; + } __Reply__vm_read_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_read_entry_t data_list; + } __Reply__vm_read_list_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_write_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_copy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_size_t outsize; + } __Reply__vm_read_overwrite_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_msync_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_behavior_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_map_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_machine_attribute_val_t value; + } __Reply__vm_machine_attribute_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t target_address; + vm_prot_t cur_protection; + vm_prot_t max_protection; + } __Reply__vm_remap_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object_handle; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_size_t size; + } __Reply__mach_make_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + integer_t disposition; + integer_t ref_count; + } __Reply__vm_map_page_query_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t objects; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_info_region_t region; + mach_msg_type_number_t objectsCnt; + } __Reply__mach_vm_region_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t pages; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t pagesCnt; + } __Reply__vm_mapped_pages_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + vm_size_t size; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + int info[19]; + } __Reply__vm_region_recurse_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + vm_size_t size; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + int info[19]; + } __Reply__vm_region_recurse_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_descriptor_t objects; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_info_region_64_t region; + mach_msg_type_number_t objectsCnt; + } __Reply__mach_vm_region_info_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object_name; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + mach_msg_type_number_t infoCnt; + int info[10]; + } __Reply__vm_region_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t object_handle; + /* end of the kernel processed data */ + NDR_record_t NDR; + memory_object_size_t size; + } __Reply__mach_make_memory_entry_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_map_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int state; + } __Reply__vm_purgable_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_map_exec_lockdown_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t target_address; + vm_prot_t cur_protection; + vm_prot_t max_protection; + } __Reply__vm_remap_new_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__vm_map_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__vm_map_subsystem__defined +#define __ReplyUnion__vm_map_subsystem__defined +union __ReplyUnion__vm_map_subsystem { + __Reply__vm_region_t Reply_vm_region; + __Reply__vm_allocate_t Reply_vm_allocate; + __Reply__vm_deallocate_t Reply_vm_deallocate; + __Reply__vm_protect_t Reply_vm_protect; + __Reply__vm_inherit_t Reply_vm_inherit; + __Reply__vm_read_t Reply_vm_read; + __Reply__vm_read_list_t Reply_vm_read_list; + __Reply__vm_write_t Reply_vm_write; + __Reply__vm_copy_t Reply_vm_copy; + __Reply__vm_read_overwrite_t Reply_vm_read_overwrite; + __Reply__vm_msync_t Reply_vm_msync; + __Reply__vm_behavior_set_t Reply_vm_behavior_set; + __Reply__vm_map_t Reply_vm_map; + __Reply__vm_machine_attribute_t Reply_vm_machine_attribute; + __Reply__vm_remap_t Reply_vm_remap; + __Reply__task_wire_t Reply_task_wire; + __Reply__mach_make_memory_entry_t Reply_mach_make_memory_entry; + __Reply__vm_map_page_query_t Reply_vm_map_page_query; + __Reply__mach_vm_region_info_t Reply_mach_vm_region_info; + __Reply__vm_mapped_pages_info_t Reply_vm_mapped_pages_info; + __Reply__vm_region_recurse_t Reply_vm_region_recurse; + __Reply__vm_region_recurse_64_t Reply_vm_region_recurse_64; + __Reply__mach_vm_region_info_64_t Reply_mach_vm_region_info_64; + __Reply__vm_region_64_t Reply_vm_region_64; + __Reply__mach_make_memory_entry_64_t Reply_mach_make_memory_entry_64; + __Reply__vm_map_64_t Reply_vm_map_64; + __Reply__vm_purgable_control_t Reply_vm_purgable_control; + __Reply__vm_map_exec_lockdown_t Reply_vm_map_exec_lockdown; + __Reply__vm_remap_new_t Reply_vm_remap_new; +}; +#endif /* !__RequestUnion__vm_map_subsystem__defined */ + +#ifndef subsystem_to_name_map_vm_map +#define subsystem_to_name_map_vm_map \ + { "vm_region", 3800 },\ + { "vm_allocate", 3801 },\ + { "vm_deallocate", 3802 },\ + { "vm_protect", 3803 },\ + { "vm_inherit", 3804 },\ + { "vm_read", 3805 },\ + { "vm_read_list", 3806 },\ + { "vm_write", 3807 },\ + { "vm_copy", 3808 },\ + { "vm_read_overwrite", 3809 },\ + { "vm_msync", 3810 },\ + { "vm_behavior_set", 3811 },\ + { "vm_map", 3812 },\ + { "vm_machine_attribute", 3813 },\ + { "vm_remap", 3814 },\ + { "task_wire", 3815 },\ + { "mach_make_memory_entry", 3816 },\ + { "vm_map_page_query", 3817 },\ + { "mach_vm_region_info", 3818 },\ + { "vm_mapped_pages_info", 3819 },\ + { "vm_region_recurse", 3821 },\ + { "vm_region_recurse_64", 3822 },\ + { "mach_vm_region_info_64", 3823 },\ + { "vm_region_64", 3824 },\ + { "mach_make_memory_entry_64", 3825 },\ + { "vm_map_64", 3826 },\ + { "vm_purgable_control", 3830 },\ + { "vm_map_exec_lockdown", 3831 },\ + { "vm_remap_new", 3832 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _vm_map_user_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/vm_prot.h b/lib/libc/include/any-macos.11-any/mach/vm_prot.h new file mode 100644 index 0000000000..08916dfa2a --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/vm_prot.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_prot.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * + * Virtual memory protection definitions. + * + */ + +#ifndef _MACH_VM_PROT_H_ +#define _MACH_VM_PROT_H_ + +/* + * Types defined: + * + * vm_prot_t VM protection values. + */ + +typedef int vm_prot_t; + +/* + * Protection values, defined as bits within the vm_prot_t type + */ + +#define VM_PROT_NONE ((vm_prot_t) 0x00) + +#define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */ +#define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */ +#define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */ + +/* + * The default protection for newly-created virtual memory + */ + +#define VM_PROT_DEFAULT (VM_PROT_READ|VM_PROT_WRITE) + +/* + * The maximum privileges possible, for parameter checking. + */ + +#define VM_PROT_ALL (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) + +/* + * An invalid protection value. + * Used only by memory_object_lock_request to indicate no change + * to page locks. Using -1 here is a bad idea because it + * looks like VM_PROT_ALL and then some. + */ + +#define VM_PROT_NO_CHANGE ((vm_prot_t) 0x08) + +/* + * When a caller finds that he cannot obtain write permission on a + * mapped entry, the following flag can be used. The entry will + * be made "needs copy" effectively copying the object (using COW), + * and write permission will be added to the maximum protections + * for the associated entry. + */ + +#define VM_PROT_COPY ((vm_prot_t) 0x10) + + +/* + * Another invalid protection value. + * Used only by memory_object_data_request upon an object + * which has specified a copy_call copy strategy. It is used + * when the kernel wants a page belonging to a copy of the + * object, and is only asking the object as a result of + * following a shadow chain. This solves the race between pages + * being pushed up by the memory manager and the kernel + * walking down the shadow chain. + */ + +#define VM_PROT_WANTS_COPY ((vm_prot_t) 0x10) + + +/* + * Another invalid protection value. + * Indicates that the other protection bits are to be applied as a mask + * against the actual protection bits of the map entry. + */ +#define VM_PROT_IS_MASK ((vm_prot_t) 0x40) + +/* + * Another invalid protection value to support execute-only protection. + * VM_PROT_STRIP_READ is a special marker that tells mprotect to not + * set VM_PROT_READ. We have to do it this way because existing code + * expects the system to set VM_PROT_READ if VM_PROT_EXECUTE is set. + * VM_PROT_EXECUTE_ONLY is just a convenience value to indicate that + * the memory should be executable and explicitly not readable. It will + * be ignored on platforms that do not support this type of protection. + */ +#define VM_PROT_STRIP_READ ((vm_prot_t) 0x80) +#define VM_PROT_EXECUTE_ONLY (VM_PROT_EXECUTE|VM_PROT_STRIP_READ) + + +#endif /* _MACH_VM_PROT_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach/vm_statistics.h b/lib/libc/include/any-macos.11-any/mach/vm_statistics.h new file mode 100644 index 0000000000..8311e45005 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach/vm_statistics.h @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_statistics.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young, David Golub + * + * Virtual memory statistics structure. + * + */ + +#ifndef _MACH_VM_STATISTICS_H_ +#define _MACH_VM_STATISTICS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * vm_statistics + * + * History: + * rev0 - original structure. + * rev1 - added purgable info (purgable_count and purges). + * rev2 - added speculative_count. + * + * Note: you cannot add any new fields to this structure. Add them below in + * vm_statistics64. + */ + +struct vm_statistics { + natural_t free_count; /* # of pages free */ + natural_t active_count; /* # of pages active */ + natural_t inactive_count; /* # of pages inactive */ + natural_t wire_count; /* # of pages wired down */ + natural_t zero_fill_count; /* # of zero fill pages */ + natural_t reactivations; /* # of pages reactivated */ + natural_t pageins; /* # of pageins */ + natural_t pageouts; /* # of pageouts */ + natural_t faults; /* # of faults */ + natural_t cow_faults; /* # of copy-on-writes */ + natural_t lookups; /* object cache lookups */ + natural_t hits; /* object cache hits */ + + /* added for rev1 */ + natural_t purgeable_count; /* # of pages purgeable */ + natural_t purges; /* # of pages purged */ + + /* added for rev2 */ + /* + * NB: speculative pages are already accounted for in "free_count", + * so "speculative_count" is the number of "free" pages that are + * used to hold data that was read speculatively from disk but + * haven't actually been used by anyone so far. + */ + natural_t speculative_count; /* # of pages speculative */ +}; + +/* Used by all architectures */ +typedef struct vm_statistics *vm_statistics_t; +typedef struct vm_statistics vm_statistics_data_t; + +/* + * vm_statistics64 + * + * History: + * rev0 - original structure. + * rev1 - added purgable info (purgable_count and purges). + * rev2 - added speculative_count. + * ---- + * rev3 - changed name to vm_statistics64. + * changed some fields in structure to 64-bit on + * arm, i386 and x86_64 architectures. + * rev4 - require 64-bit alignment for efficient access + * in the kernel. No change to reported data. + * + */ + +struct vm_statistics64 { + natural_t free_count; /* # of pages free */ + natural_t active_count; /* # of pages active */ + natural_t inactive_count; /* # of pages inactive */ + natural_t wire_count; /* # of pages wired down */ + uint64_t zero_fill_count; /* # of zero fill pages */ + uint64_t reactivations; /* # of pages reactivated */ + uint64_t pageins; /* # of pageins */ + uint64_t pageouts; /* # of pageouts */ + uint64_t faults; /* # of faults */ + uint64_t cow_faults; /* # of copy-on-writes */ + uint64_t lookups; /* object cache lookups */ + uint64_t hits; /* object cache hits */ + uint64_t purges; /* # of pages purged */ + natural_t purgeable_count; /* # of pages purgeable */ + /* + * NB: speculative pages are already accounted for in "free_count", + * so "speculative_count" is the number of "free" pages that are + * used to hold data that was read speculatively from disk but + * haven't actually been used by anyone so far. + */ + natural_t speculative_count; /* # of pages speculative */ + + /* added for rev1 */ + uint64_t decompressions; /* # of pages decompressed */ + uint64_t compressions; /* # of pages compressed */ + uint64_t swapins; /* # of pages swapped in (via compression segments) */ + uint64_t swapouts; /* # of pages swapped out (via compression segments) */ + natural_t compressor_page_count; /* # of pages used by the compressed pager to hold all the compressed data */ + natural_t throttled_count; /* # of pages throttled */ + natural_t external_page_count; /* # of pages that are file-backed (non-swap) */ + natural_t internal_page_count; /* # of pages that are anonymous */ + uint64_t total_uncompressed_pages_in_compressor; /* # of pages (uncompressed) held within the compressor. */ +} __attribute__((aligned(8))); + +typedef struct vm_statistics64 *vm_statistics64_t; +typedef struct vm_statistics64 vm_statistics64_data_t; + +kern_return_t vm_stats(void *info, unsigned int *count); + +/* + * VM_STATISTICS_TRUNCATE_TO_32_BIT + * + * This is used by host_statistics() to truncate and peg the 64-bit in-kernel values from + * vm_statistics64 to the 32-bit values of the older structure above (vm_statistics). + */ +#define VM_STATISTICS_TRUNCATE_TO_32_BIT(value) ((uint32_t)(((value) > UINT32_MAX ) ? UINT32_MAX : (value))) + +/* + * vm_extmod_statistics + * + * Structure to record modifications to a task by an + * external agent. + * + * History: + * rev0 - original structure. + */ + +struct vm_extmod_statistics { + int64_t task_for_pid_count; /* # of times task port was looked up */ + int64_t task_for_pid_caller_count; /* # of times this task called task_for_pid */ + int64_t thread_creation_count; /* # of threads created in task */ + int64_t thread_creation_caller_count; /* # of threads created by task */ + int64_t thread_set_state_count; /* # of register state sets in task */ + int64_t thread_set_state_caller_count; /* # of register state sets by task */ +} __attribute__((aligned(8))); + +typedef struct vm_extmod_statistics *vm_extmod_statistics_t; +typedef struct vm_extmod_statistics vm_extmod_statistics_data_t; + +typedef struct vm_purgeable_stat { + uint64_t count; + uint64_t size; +}vm_purgeable_stat_t; + +struct vm_purgeable_info { + vm_purgeable_stat_t fifo_data[8]; + vm_purgeable_stat_t obsolete_data; + vm_purgeable_stat_t lifo_data[8]; +}; + +typedef struct vm_purgeable_info *vm_purgeable_info_t; + +/* included for the vm_map_page_query call */ + +#define VM_PAGE_QUERY_PAGE_PRESENT 0x1 +#define VM_PAGE_QUERY_PAGE_FICTITIOUS 0x2 +#define VM_PAGE_QUERY_PAGE_REF 0x4 +#define VM_PAGE_QUERY_PAGE_DIRTY 0x8 +#define VM_PAGE_QUERY_PAGE_PAGED_OUT 0x10 +#define VM_PAGE_QUERY_PAGE_COPIED 0x20 +#define VM_PAGE_QUERY_PAGE_SPECULATIVE 0x40 +#define VM_PAGE_QUERY_PAGE_EXTERNAL 0x80 +#define VM_PAGE_QUERY_PAGE_CS_VALIDATED 0x100 +#define VM_PAGE_QUERY_PAGE_CS_TAINTED 0x200 +#define VM_PAGE_QUERY_PAGE_CS_NX 0x400 +#define VM_PAGE_QUERY_PAGE_REUSABLE 0x800 + + +/* + * VM allocation flags: + * + * VM_FLAGS_FIXED + * (really the absence of VM_FLAGS_ANYWHERE) + * Allocate new VM region at the specified virtual address, if possible. + * + * VM_FLAGS_ANYWHERE + * Allocate new VM region anywhere it would fit in the address space. + * + * VM_FLAGS_PURGABLE + * Create a purgable VM object for that new VM region. + * + * VM_FLAGS_4GB_CHUNK + * The new VM region will be chunked up into 4GB sized pieces. + * + * VM_FLAGS_NO_PMAP_CHECK + * (for DEBUG kernel config only, ignored for other configs) + * Do not check that there is no stale pmap mapping for the new VM region. + * This is useful for kernel memory allocations at bootstrap when building + * the initial kernel address space while some memory is already in use. + * + * VM_FLAGS_OVERWRITE + * The new VM region can replace existing VM regions if necessary + * (to be used in combination with VM_FLAGS_FIXED). + * + * VM_FLAGS_NO_CACHE + * Pages brought in to this VM region are placed on the speculative + * queue instead of the active queue. In other words, they are not + * cached so that they will be stolen first if memory runs low. + */ + +#define VM_FLAGS_FIXED 0x0000 +#define VM_FLAGS_ANYWHERE 0x0001 +#define VM_FLAGS_PURGABLE 0x0002 +#define VM_FLAGS_4GB_CHUNK 0x0004 +#define VM_FLAGS_RANDOM_ADDR 0x0008 +#define VM_FLAGS_NO_CACHE 0x0010 +#define VM_FLAGS_RESILIENT_CODESIGN 0x0020 +#define VM_FLAGS_RESILIENT_MEDIA 0x0040 +#define VM_FLAGS_PERMANENT 0x0080 +#define VM_FLAGS_OVERWRITE 0x4000 /* delete any existing mappings first */ +/* + * VM_FLAGS_SUPERPAGE_MASK + * 3 bits that specify whether large pages should be used instead of + * base pages (!=0), as well as the requested page size. + */ +#define VM_FLAGS_SUPERPAGE_MASK 0x70000 /* bits 0x10000, 0x20000, 0x40000 */ +#define VM_FLAGS_RETURN_DATA_ADDR 0x100000 /* Return address of target data, rather than base of page */ +#define VM_FLAGS_RETURN_4K_DATA_ADDR 0x800000 /* Return 4K aligned address of target data */ +#define VM_FLAGS_ALIAS_MASK 0xFF000000 +#define VM_GET_FLAGS_ALIAS(flags, alias) \ + (alias) = ((flags) & VM_FLAGS_ALIAS_MASK) >> 24 +#define VM_SET_FLAGS_ALIAS(flags, alias) \ + (flags) = (((flags) & ~VM_FLAGS_ALIAS_MASK) | \ + (((alias) & ~VM_FLAGS_ALIAS_MASK) << 24)) + +/* These are the flags that we accept from user-space */ +#define VM_FLAGS_USER_ALLOCATE (VM_FLAGS_FIXED | \ + VM_FLAGS_ANYWHERE | \ + VM_FLAGS_PURGABLE | \ + VM_FLAGS_4GB_CHUNK | \ + VM_FLAGS_RANDOM_ADDR | \ + VM_FLAGS_NO_CACHE | \ + VM_FLAGS_PERMANENT | \ + VM_FLAGS_OVERWRITE | \ + VM_FLAGS_SUPERPAGE_MASK | \ + VM_FLAGS_ALIAS_MASK) +#define VM_FLAGS_USER_MAP (VM_FLAGS_USER_ALLOCATE | \ + VM_FLAGS_RETURN_4K_DATA_ADDR | \ + VM_FLAGS_RETURN_DATA_ADDR) +#define VM_FLAGS_USER_REMAP (VM_FLAGS_FIXED | \ + VM_FLAGS_ANYWHERE | \ + VM_FLAGS_RANDOM_ADDR | \ + VM_FLAGS_OVERWRITE| \ + VM_FLAGS_RETURN_DATA_ADDR | \ + VM_FLAGS_RESILIENT_CODESIGN | \ + VM_FLAGS_RESILIENT_MEDIA) + +#define VM_FLAGS_SUPERPAGE_SHIFT 16 +#define SUPERPAGE_NONE 0 /* no superpages, if all bits are 0 */ +#define SUPERPAGE_SIZE_ANY 1 +#define VM_FLAGS_SUPERPAGE_NONE (SUPERPAGE_NONE << VM_FLAGS_SUPERPAGE_SHIFT) +#define VM_FLAGS_SUPERPAGE_SIZE_ANY (SUPERPAGE_SIZE_ANY << VM_FLAGS_SUPERPAGE_SHIFT) +#define SUPERPAGE_SIZE_2MB 2 +#define VM_FLAGS_SUPERPAGE_SIZE_2MB (SUPERPAGE_SIZE_2MB< +#include + +#include + +typedef vm_offset_t pointer_t; +typedef vm_offset_t vm_address_t; + +/* + * We use addr64_t for 64-bit addresses that are used on both + * 32 and 64-bit machines. On PPC, they are passed and returned as + * two adjacent 32-bit GPRs. We use addr64_t in places where + * common code must be useable both on 32 and 64-bit machines. + */ +typedef uint64_t addr64_t; /* Basic effective address */ + +/* + * We use reg64_t for addresses that are 32 bits on a 32-bit + * machine, and 64 bits on a 64-bit machine, but are always + * passed and returned in a single GPR on PPC. This type + * cannot be used in generic 32-bit c, since on a 64-bit + * machine the upper half of the register will be ignored + * by the c compiler in 32-bit mode. In c, we can only use the + * type in prototypes of functions that are written in and called + * from assembly language. This type is basically a comment. + */ +typedef uint32_t reg64_t; + +/* + * To minimize the use of 64-bit fields, we keep some physical + * addresses (that are page aligned) as 32-bit page numbers. + * This limits the physical address space to 16TB of RAM. + */ +typedef uint32_t ppnum_t; /* Physical page number */ +#define PPNUM_MAX UINT32_MAX + + + +typedef mach_port_t vm_map_t, vm_map_read_t, vm_map_inspect_t; + + +#define VM_MAP_NULL ((vm_map_t) 0) +#define VM_MAP_INSPECT_NULL ((vm_map_inspect_t) 0) +#define VM_MAP_READ_NULL ((vm_map_read_t) 0) + +/* + * Evolving definitions, likely to change. + */ + +typedef uint64_t vm_object_offset_t; +typedef uint64_t vm_object_size_t; + + + + +typedef mach_port_t upl_t; +typedef mach_port_t vm_named_entry_t; + + +#define UPL_NULL ((upl_t) 0) +#define VM_NAMED_ENTRY_NULL ((vm_named_entry_t) 0) + +#endif /* _MACH_VM_TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/mach_debug/mach_debug_types.h b/lib/libc/include/any-macos.11-any/mach_debug/mach_debug_types.h new file mode 100644 index 0000000000..a4a2f3d7c7 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/mach_debug/mach_debug_types.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Mach kernel debugging interface type declarations + */ + +#ifndef _MACH_DEBUG_MACH_DEBUG_TYPES_H_ +#define _MACH_DEBUG_MACH_DEBUG_TYPES_H_ + +#include +#include +#include +#include +#include +#include + +#define MACH_CORE_FILEHEADER_SIGNATURE 0x0063614d20646152ULL +#define MACH_CORE_FILEHEADER_MAXFILES 16 +#define MACH_CORE_FILEHEADER_NAMELEN 16 + +typedef char symtab_name_t[32]; + +struct mach_core_details { + uint64_t gzip_offset; + uint64_t gzip_length; + char core_name[MACH_CORE_FILEHEADER_NAMELEN]; +}; + +struct mach_core_fileheader { + uint64_t signature; + uint64_t log_offset; + uint64_t log_length; + uint64_t num_files; + struct mach_core_details files[MACH_CORE_FILEHEADER_MAXFILES]; +}; + +#define KOBJECT_DESCRIPTION_LENGTH 512 +typedef char kobject_description_t[KOBJECT_DESCRIPTION_LENGTH]; + +#endif /* _MACH_DEBUG_MACH_DEBUG_TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/machine/_mcontext.h b/lib/libc/include/any-macos.11-any/machine/_mcontext.h new file mode 100644 index 0000000000..12965510fa --- /dev/null +++ b/lib/libc/include/any-macos.11-any/machine/_mcontext.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2003-2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#if defined (__i386__) || defined (__x86_64__) +#include "i386/_mcontext.h" +#elif defined (__arm__) || defined (__arm64__) +#include "arm/_mcontext.h" +#else +#error architecture not supported +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/machine/_param.h b/lib/libc/include/any-macos.11-any/machine/_param.h new file mode 100644 index 0000000000..5fdf54345f --- /dev/null +++ b/lib/libc/include/any-macos.11-any/machine/_param.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2004-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#if defined (__i386__) || defined (__x86_64__) +#include +#elif defined (__arm__) || defined (__arm64__) +#include +#else +#error architecture not supported +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/machine/limits.h b/lib/libc/include/any-macos.11-any/machine/limits.h new file mode 100644 index 0000000000..7523f8806d --- /dev/null +++ b/lib/libc/include/any-macos.11-any/machine/limits.h @@ -0,0 +1,11 @@ +/* This is the `system' limits.h, independent of any particular + * compiler. GCC provides its own limits.h which can be found in + * /usr/lib/gcc, although it is not very informative. + * This file is public domain. */ +#if defined (__i386__) || defined(__x86_64__) +#include +#elif defined (__arm__) || defined (__arm64__) +#include +#else +#error architecture not supported +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/malloc/malloc.h b/lib/libc/include/any-macos.11-any/malloc/malloc.h new file mode 100644 index 0000000000..33013ccc54 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/malloc/malloc.h @@ -0,0 +1,314 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _MALLOC_MALLOC_H_ +#define _MALLOC_MALLOC_H_ + +#include +#include +#include +#include + +#if __has_feature(ptrauth_calls) +#include + +// Zone function pointer, type-diversified but not address-diversified (because +// the zone can be copied). Process-independent because the zone structure may +// be in the shared library cache. +#define MALLOC_ZONE_FN_PTR(fn) __ptrauth(ptrauth_key_process_independent_code, \ + FALSE, ptrauth_string_discriminator("malloc_zone_fn." #fn)) fn + +// Introspection function pointer, address- and type-diversified. +// Process-independent because the malloc_introspection_t structure that contains +// these pointers may be in the shared library cache. +#define MALLOC_INTROSPECT_FN_PTR(fn) __ptrauth(ptrauth_key_process_independent_code, \ + TRUE, ptrauth_string_discriminator("malloc_introspect_fn." #fn)) fn + +// Pointer to the introspection pointer table, type-diversified but not +// address-diversified (because the zone can be copied). +// Process-independent because the table pointer may be in the shared library cache. +#define MALLOC_INTROSPECT_TBL_PTR(ptr) __ptrauth(ptrauth_key_process_independent_data,\ + FALSE, ptrauth_string_discriminator("malloc_introspect_tbl")) ptr + +#endif // __has_feature(ptrauth_calls) + +#ifndef MALLOC_ZONE_FN_PTR +#define MALLOC_ZONE_FN_PTR(fn) fn +#define MALLOC_INTROSPECT_FN_PTR(fn) fn +#define MALLOC_INTROSPECT_TBL_PTR(ptr) ptr +#endif // MALLOC_ZONE_FN_PTR + +__BEGIN_DECLS +/********* Type definitions ************/ + +typedef struct _malloc_zone_t { + /* Only zone implementors should depend on the layout of this structure; + Regular callers should use the access functions below */ + void *reserved1; /* RESERVED FOR CFAllocator DO NOT USE */ + void *reserved2; /* RESERVED FOR CFAllocator DO NOT USE */ + size_t (* MALLOC_ZONE_FN_PTR(size))(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */ + void *(* MALLOC_ZONE_FN_PTR(malloc))(struct _malloc_zone_t *zone, size_t size); + void *(* MALLOC_ZONE_FN_PTR(calloc))(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */ + void *(* MALLOC_ZONE_FN_PTR(valloc))(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */ + void (* MALLOC_ZONE_FN_PTR(free))(struct _malloc_zone_t *zone, void *ptr); + void *(* MALLOC_ZONE_FN_PTR(realloc))(struct _malloc_zone_t *zone, void *ptr, size_t size); + void (* MALLOC_ZONE_FN_PTR(destroy))(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */ + const char *zone_name; + + /* Optional batch callbacks; these may be NULL */ + unsigned (* MALLOC_ZONE_FN_PTR(batch_malloc))(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */ + void (* MALLOC_ZONE_FN_PTR(batch_free))(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */ + + struct malloc_introspection_t * MALLOC_INTROSPECT_TBL_PTR(introspect); + unsigned version; + + /* aligned memory allocation. The callback may be NULL. Present in version >= 5. */ + void *(* MALLOC_ZONE_FN_PTR(memalign))(struct _malloc_zone_t *zone, size_t alignment, size_t size); + + /* free a pointer known to be in zone and known to have the given size. The callback may be NULL. Present in version >= 6.*/ + void (* MALLOC_ZONE_FN_PTR(free_definite_size))(struct _malloc_zone_t *zone, void *ptr, size_t size); + + /* Empty out caches in the face of memory pressure. The callback may be NULL. Present in version >= 8. */ + size_t (* MALLOC_ZONE_FN_PTR(pressure_relief))(struct _malloc_zone_t *zone, size_t goal); + + /* + * Checks whether an address might belong to the zone. May be NULL. Present in version >= 10. + * False positives are allowed (e.g. the pointer was freed, or it's in zone space that has + * not yet been allocated. False negatives are not allowed. + */ + boolean_t (* MALLOC_ZONE_FN_PTR(claimed_address))(struct _malloc_zone_t *zone, void *ptr); +} malloc_zone_t; + +/********* Creation and destruction ************/ + +extern malloc_zone_t *malloc_default_zone(void); + /* The initial zone */ + +extern malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags); + /* Creates a new zone with default behavior and registers it */ + +extern void malloc_destroy_zone(malloc_zone_t *zone); + /* Destroys zone and everything it allocated */ + +/********* Block creation and manipulation ************/ + +extern void *malloc_zone_malloc(malloc_zone_t *zone, size_t size) __alloc_size(2); + /* Allocates a new pointer of size size; zone must be non-NULL */ + +extern void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) __alloc_size(2,3); + /* Allocates a new pointer of size num_items * size; block is cleared; zone must be non-NULL */ + +extern void *malloc_zone_valloc(malloc_zone_t *zone, size_t size) __alloc_size(2); + /* Allocates a new pointer of size size; zone must be non-NULL; Pointer is guaranteed to be page-aligned and block is cleared */ + +extern void malloc_zone_free(malloc_zone_t *zone, void *ptr); + /* Frees pointer in zone; zone must be non-NULL */ + +extern void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) __alloc_size(3); + /* Enlarges block if necessary; zone must be non-NULL */ + +extern malloc_zone_t *malloc_zone_from_ptr(const void *ptr); + /* Returns the zone for a pointer, or NULL if not in any zone. + The ptr must have been returned from a malloc or realloc call. */ + +extern size_t malloc_size(const void *ptr); + /* Returns size of given ptr */ + +extern size_t malloc_good_size(size_t size); + /* Returns number of bytes greater than or equal to size that can be allocated without padding */ + +extern void *malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) __alloc_size(3) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); + /* + * Allocates a new pointer of size size whose address is an exact multiple of alignment. + * alignment must be a power of two and at least as large as sizeof(void *). + * zone must be non-NULL. + */ + +/********* Batch methods ************/ + +extern unsigned malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); + /* Allocates num blocks of the same size; Returns the number truly allocated (may be 0) */ + +extern void malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num); + /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process; This function will always free even if the zone has no batch callback */ + +/********* Functions for libcache ************/ + +extern malloc_zone_t *malloc_default_purgeable_zone(void) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); + /* Returns a pointer to the default purgeable_zone. */ + +extern void malloc_make_purgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); + /* Make an allocation from the purgeable zone purgeable if possible. */ + +extern int malloc_make_nonpurgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); + /* Makes an allocation from the purgeable zone nonpurgeable. + * Returns zero if the contents were not purged since the last + * call to malloc_make_purgeable, else returns non-zero. */ + +/********* Functions for zone implementors ************/ + +extern void malloc_zone_register(malloc_zone_t *zone); + /* Registers a custom malloc zone; Should typically be called after a + * malloc_zone_t has been filled in with custom methods by a client. See + * malloc_create_zone for creating additional malloc zones with the + * default allocation and free behavior. */ + +extern void malloc_zone_unregister(malloc_zone_t *zone); + /* De-registers a zone + Should typically be called before calling the zone destruction routine */ + +extern void malloc_set_zone_name(malloc_zone_t *zone, const char *name); + /* Sets the name of a zone */ + +extern const char *malloc_get_zone_name(malloc_zone_t *zone); + /* Returns the name of a zone */ + +size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); + /* malloc_zone_pressure_relief() advises the malloc subsystem that the process is under memory pressure and + * that the subsystem should make its best effort towards releasing (i.e. munmap()-ing) "goal" bytes from "zone". + * If "goal" is passed as zero, the malloc subsystem will attempt to achieve maximal pressure relief in "zone". + * If "zone" is passed as NULL, all zones are examined for pressure relief opportunities. + * malloc_zone_pressure_relief() returns the number of bytes released. + */ + +typedef struct { + vm_address_t address; + vm_size_t size; +} vm_range_t; + +typedef struct malloc_statistics_t { + unsigned blocks_in_use; + size_t size_in_use; + size_t max_size_in_use; /* high water mark of touched memory */ + size_t size_allocated; /* reserved in memory */ +} malloc_statistics_t; + +typedef kern_return_t memory_reader_t(task_t remote_task, vm_address_t remote_address, vm_size_t size, void **local_memory); + /* given a task, "reads" the memory at the given address and size +local_memory: set to a contiguous chunk of memory; validity of local_memory is assumed to be limited (until next call) */ + +#define MALLOC_PTR_IN_USE_RANGE_TYPE 1 /* for allocated pointers */ +#define MALLOC_PTR_REGION_RANGE_TYPE 2 /* for region containing pointers */ +#define MALLOC_ADMIN_REGION_RANGE_TYPE 4 /* for region used internally */ +#define MALLOC_ZONE_SPECIFIC_FLAGS 0xff00 /* bits reserved for zone-specific purposes */ + +typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned); + /* given a task and context, "records" the specified addresses */ + +/* Print function for the print_task() operation. */ +typedef void print_task_printer_t(const char *fmt, ...) __printflike(1,2); + +typedef struct malloc_introspection_t { + kern_return_t (* MALLOC_INTROSPECT_FN_PTR(enumerator))(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */ + size_t (* MALLOC_INTROSPECT_FN_PTR(good_size))(malloc_zone_t *zone, size_t size); + boolean_t (* MALLOC_INTROSPECT_FN_PTR(check))(malloc_zone_t *zone); /* Consistency checker */ + void (* MALLOC_INTROSPECT_FN_PTR(print))(malloc_zone_t *zone, boolean_t verbose); /* Prints zone */ + void (* MALLOC_INTROSPECT_FN_PTR(log))(malloc_zone_t *zone, void *address); /* Enables logging of activity */ + void (* MALLOC_INTROSPECT_FN_PTR(force_lock))(malloc_zone_t *zone); /* Forces locking zone */ + void (* MALLOC_INTROSPECT_FN_PTR(force_unlock))(malloc_zone_t *zone); /* Forces unlocking zone */ + void (* MALLOC_INTROSPECT_FN_PTR(statistics))(malloc_zone_t *zone, malloc_statistics_t *stats); /* Fills statistics */ + boolean_t (* MALLOC_INTROSPECT_FN_PTR(zone_locked))(malloc_zone_t *zone); /* Are any zone locks held */ + + /* Discharge checking. Present in version >= 7. */ + boolean_t (* MALLOC_INTROSPECT_FN_PTR(enable_discharge_checking))(malloc_zone_t *zone); + void (* MALLOC_INTROSPECT_FN_PTR(disable_discharge_checking))(malloc_zone_t *zone); + void (* MALLOC_INTROSPECT_FN_PTR(discharge))(malloc_zone_t *zone, void *memory); +#ifdef __BLOCKS__ + void (* MALLOC_INTROSPECT_FN_PTR(enumerate_discharged_pointers))(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)); + #else + void *enumerate_unavailable_without_blocks; +#endif /* __BLOCKS__ */ + void (* MALLOC_INTROSPECT_FN_PTR(reinit_lock))(malloc_zone_t *zone); /* Reinitialize zone locks, called only from atfork_child handler. Present in version >= 9. */ + void (* MALLOC_INTROSPECT_FN_PTR(print_task))(task_t task, unsigned level, vm_address_t zone_address, memory_reader_t reader, print_task_printer_t printer); /* debug print for another process. Present in version >= 11. */ + void (* MALLOC_INTROSPECT_FN_PTR(task_statistics))(task_t task, vm_address_t zone_address, memory_reader_t reader, malloc_statistics_t *stats); /* Present in version >= 12 */ +} malloc_introspection_t; + +// The value of "level" when passed to print_task() that corresponds to +// verbose passed to print() +#define MALLOC_VERBOSE_PRINT_LEVEL 2 + +extern void malloc_printf(const char *format, ...); + /* Convenience for logging errors and warnings; + No allocation is performed during execution of this function; + Only understands usual %p %d %s formats, and %y that expresses a number of bytes (5b,10KB,1MB...) + */ + +/********* Functions for performance tools ************/ + +extern kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count); + /* Fills addresses and count with the addresses of the zones in task; + Note that the validity of the addresses returned correspond to the validity of the memory returned by reader */ + +/********* Debug helpers ************/ + +extern void malloc_zone_print_ptr_info(void *ptr); + /* print to stdout if this pointer is in the malloc heap, free status, and size */ + +extern boolean_t malloc_zone_check(malloc_zone_t *zone); + /* Checks zone is well formed; if !zone, checks all zones */ + +extern void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose); + /* Prints summary on zone; if !zone, prints all zones */ + +extern void malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats); + /* Fills statistics for zone; if !zone, sums up all zones */ + +extern void malloc_zone_log(malloc_zone_t *zone, void *address); + /* Controls logging of all activity; if !zone, for all zones; + If address==0 nothing is logged; + If address==-1 all activity is logged; + Else only the activity regarding address is logged */ + +struct mstats { + size_t bytes_total; + size_t chunks_used; + size_t bytes_used; + size_t chunks_free; + size_t bytes_free; +}; + +extern struct mstats mstats(void); + +extern boolean_t malloc_zone_enable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Increment the discharge checking enabled counter for a zone. Returns true if the zone supports checking, false if it does not. */ + +extern void malloc_zone_disable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Decrement the discharge checking enabled counter for a zone. */ + +extern void malloc_zone_discharge(malloc_zone_t *zone, void *memory) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Register memory that the programmer expects to be freed soon. + zone may be NULL in which case the zone is determined using malloc_zone_from_ptr(). + If discharge checking is off for the zone this function is a no-op. */ + +#ifdef __BLOCKS__ +extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +/* Calls report_discharged for each block that was registered using malloc_zone_discharge() but has not yet been freed. + info is used to provide zone defined information about the memory block. + If zone is NULL then the enumeration covers all zones. */ +#else +extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +#endif /* __BLOCKS__ */ + +__END_DECLS + +#endif /* _MALLOC_MALLOC_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/net/if.h b/lib/libc/include/any-macos.11-any/net/if.h index 8f0fab7767..e77e7b8338 100644 --- a/lib/libc/include/any-macos.11-any/net/if.h +++ b/lib/libc/include/any-macos.11-any/net/if.h @@ -63,24 +63,21 @@ #ifndef _NET_IF_H_ #define _NET_IF_H_ +#include +#include + #define IF_NAMESIZE 16 #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#include #include #ifdef __APPLE__ #include -#include #include #include #endif -#ifndef IFNAMSIZ -#define IFNAMSIZ IF_NAMESIZE -#endif - struct if_clonereq { int ifcr_total; /* total cloners (out) */ int ifcr_count; /* room for this many in user buffer */ @@ -288,6 +285,9 @@ struct ifkpi { * remainder may be interface specific. */ struct ifreq { +#ifndef IFNAMSIZ +#define IFNAMSIZ IF_NAMESIZE +#endif char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ union { struct sockaddr ifru_addr; @@ -371,6 +371,7 @@ struct ifmediareq { #pragma pack() + #pragma pack(4) struct ifdrv { char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */ diff --git a/lib/libc/include/any-macos.11-any/net/if_var.h b/lib/libc/include/any-macos.11-any/net/if_var.h index a805983652..79e6a60368 100644 --- a/lib/libc/include/any-macos.11-any/net/if_var.h +++ b/lib/libc/include/any-macos.11-any/net/if_var.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2021 Apple Inc. All rights reserved. + * Copyright (c) 2000-2020 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -222,124 +222,6 @@ struct if_data64 { }; -#if defined (PRIVATE) || defined (DRIVERKIT_PRIVATE) -/* - * This structure is used to define the parameters for advisory notifications - * on an interface. - */ -#pragma pack(push, 1) -struct ifnet_interface_advisory { - /* The current structure version */ - uint8_t version; -#define IF_INTERFACE_ADVISORY_VERSION_1 0x1 -#define IF_INTERFACE_ADVISORY_VERSION_CURRENT IF_INTERFACE_ADVISORY_VERSION_1 - /* Specifies if the advisory is for transmit or receive path */ - uint8_t direction; -#define IF_INTERFACE_ADVISORY_DIRECTION_TX 0x1 -#define IF_INTERFACE_ADVISORY_DIRECTION_RX 0x2 - /* reserved for future use */ - uint16_t _reserved; - /* - * suggestion for data rate change to keep the latency low. - * unit: bits per second (bps) - * NOTE: if the interface cannot provide suggestions in terms of bps, - * it should use the following values: - * INT32_MAX : ramp up - * INT32_MIN : ramp down - * 0 : neutral - */ -#define IF_INTERFACE_ADVISORY_RATE_SUGGESTION_RAMP_UP INT32_MAX -#define IF_INTERFACE_ADVISORY_RATE_SUGGESTION_RAMP_DOWN INT32_MIN -#define IF_INTERFACE_ADVISORY_RATE_SUGGESTION_RAMP_NEUTRAL 0 - int32_t rate_trend_suggestion; - /* - * Time of the issue of advisory. - * Timestamp should be in the host domain. - * unit: mach absolute time - */ - uint64_t timestamp; - /* - * Maximum theoretical bandwidth of the interface. - * unit: bits per second (bps) - */ - uint64_t max_bandwidth; - /* - * Total bytes sent or received on the interface. - * wrap around possible and the application should account for that. - * unit: byte - */ - uint64_t total_byte_count; - /* - * average throughput observed at the driver stack. - * unit: bits per second (bps) - */ - uint64_t average_throughput; - /* - * flushable queue size at the driver. - * should be set to UINT32_MAX if not available. - * unit: byte - */ - uint32_t flushable_queue_size; - /* - * non flushable queue size at the driver. - * should be set to UINT32_MAX if not available. - * unit: byte - */ - uint32_t non_flushable_queue_size; - /* - * average delay observed at the interface. - * unit: milliseconds (ms) - */ - uint32_t average_delay; - /* - * Current frequency band (enumeration). - */ -#define IF_INTERFACE_ADVISORY_FREQ_BAND_NOT_AVAIL 0 -#define IF_INTERFACE_ADVISORY_FREQ_BAND_WIFI_24GHZ 1 -#define IF_INTERFACE_ADVISORY_FREQ_BAND_WIFI_5GHZ 2 -#define IF_INTERFACE_ADVISORY_FREQ_BAND_WIFI_6GHZ 3 - uint8_t frequency_band; - /* - * Intermittent WiFi state [true(1)/false(0)] - */ - uint8_t intermittent_state; - /* - * Estimated period for which intermittent state is expected to last. - * 1 tick -> 1 ms UNDEF => UINT16_MAX - */ - uint16_t estimated_intermittent_period; - /* - * Expected wifi outage period during intermittent state - * 1 tick -> 1 ms UNDEF => UINT16_MAX - */ - uint16_t single_outage_period; - - /* - * WiFi-BT coexistence, 1-ON, 0-OFF - */ - uint8_t bt_coex; - /* - * on scale of 1 to 5 - */ - uint8_t quality_score_delay; - /* - * on scale of 1 to 5 - */ - uint8_t quality_score_loss; - /* - * on scale of 1 to 5 - */ - uint8_t quality_score_channel; -} __attribute__((aligned(sizeof(uint64_t)))); -#pragma pack(pop) - -#else - -struct ifnet_interface_advisory; - -#endif /* defined (PRIVATE) || defined (DRIVERKIT_PRIVATE) */ - - #pragma pack() /* diff --git a/lib/libc/include/any-macos.11-any/net/net_kev.h b/lib/libc/include/any-macos.11-any/net/net_kev.h new file mode 100644 index 0000000000..0919e59ff2 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/net/net_kev.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016-2018 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _NET_NETKEV_H_ +#define _NET_NETKEV_H_ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + +/* Kernel event subclass identifiers for KEV_NETWORK_CLASS */ +#define KEV_INET_SUBCLASS 1 /* inet subclass */ +/* KEV_INET_SUBCLASS event codes */ +#define KEV_INET_NEW_ADDR 1 /* Userland configured IP address */ +#define KEV_INET_CHANGED_ADDR 2 /* Address changed event */ +#define KEV_INET_ADDR_DELETED 3 /* IPv6 address was deleted */ +#define KEV_INET_SIFDSTADDR 4 /* Dest. address was set */ +#define KEV_INET_SIFBRDADDR 5 /* Broadcast address was set */ +#define KEV_INET_SIFNETMASK 6 /* Netmask was set */ +#define KEV_INET_ARPCOLLISION 7 /* ARP collision detected */ +#ifdef __APPLE_API_PRIVATE +#define KEV_INET_PORTINUSE 8 /* use ken_in_portinuse */ +#endif +#define KEV_INET_ARPRTRFAILURE 9 /* ARP resolution failed for router */ +#define KEV_INET_ARPRTRALIVE 10 /* ARP resolution succeeded for router */ + +#define KEV_DL_SUBCLASS 2 /* Data Link subclass */ +/* + * Define Data-Link event subclass, and associated + * events. + */ +#define KEV_DL_SIFFLAGS 1 +#define KEV_DL_SIFMETRICS 2 +#define KEV_DL_SIFMTU 3 +#define KEV_DL_SIFPHYS 4 +#define KEV_DL_SIFMEDIA 5 +#define KEV_DL_SIFGENERIC 6 +#define KEV_DL_ADDMULTI 7 +#define KEV_DL_DELMULTI 8 +#define KEV_DL_IF_ATTACHED 9 +#define KEV_DL_IF_DETACHING 10 +#define KEV_DL_IF_DETACHED 11 +#define KEV_DL_LINK_OFF 12 +#define KEV_DL_LINK_ON 13 +#define KEV_DL_PROTO_ATTACHED 14 +#define KEV_DL_PROTO_DETACHED 15 +#define KEV_DL_LINK_ADDRESS_CHANGED 16 +#define KEV_DL_WAKEFLAGS_CHANGED 17 +#define KEV_DL_IF_IDLE_ROUTE_REFCNT 18 +#define KEV_DL_IFCAP_CHANGED 19 +#define KEV_DL_LINK_QUALITY_METRIC_CHANGED 20 +#define KEV_DL_NODE_PRESENCE 21 +#define KEV_DL_NODE_ABSENCE 22 +#define KEV_DL_MASTER_ELECTED 23 +#define KEV_DL_ISSUES 24 +#define KEV_DL_IFDELEGATE_CHANGED 25 +#define KEV_DL_AWDL_RESTRICTED 26 +#define KEV_DL_AWDL_UNRESTRICTED 27 +#define KEV_DL_RRC_STATE_CHANGED 28 +#define KEV_DL_QOS_MODE_CHANGED 29 +#define KEV_DL_LOW_POWER_MODE_CHANGED 30 + + +#define KEV_INET6_SUBCLASS 6 /* inet6 subclass */ +/* KEV_INET6_SUBCLASS event codes */ +#define KEV_INET6_NEW_USER_ADDR 1 /* Userland configured IPv6 address */ +#define KEV_INET6_CHANGED_ADDR 2 /* Address changed event (future) */ +#define KEV_INET6_ADDR_DELETED 3 /* IPv6 address was deleted */ +#define KEV_INET6_NEW_LL_ADDR 4 /* Autoconf LL address appeared */ +#define KEV_INET6_NEW_RTADV_ADDR 5 /* Autoconf address has appeared */ +#define KEV_INET6_DEFROUTER 6 /* Default router detected */ +#define KEV_INET6_REQUEST_NAT64_PREFIX 7 /* Asking for the NAT64-prefix */ + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#endif /* _NET_NETKEV_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/netinet6/in6.h b/lib/libc/include/any-macos.11-any/netinet6/in6.h new file mode 100644 index 0000000000..b912e8dbe7 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/netinet6/in6.h @@ -0,0 +1,681 @@ +/* + * Copyright (c) 2008-2020 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)in.h 8.3 (Berkeley) 1/3/94 + */ + +#ifndef __KAME_NETINET_IN_H_INCLUDED_ +#error "do not include netinet6/in6.h directly, include netinet/in.h. " \ + " see RFC2553" +#endif + +#ifndef _NETINET6_IN6_H_ +#define _NETINET6_IN6_H_ +#include + +#include +#include + +/* + * Identification of the network protocol stack + * for *BSD-current/release: http://www.kame.net/dev/cvsweb.cgi/kame/COVERAGE + * has the table of implementation/integration differences. + */ +#define __KAME__ +#define __KAME_VERSION "2009/apple-darwin" + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +/* + * Local port number conventions: + * + * Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root), + * unless a kernel is compiled with IPNOPRIVPORTS defined. + * + * When a user does a bind(2) or connect(2) with a port number of zero, + * a non-conflicting local port address is chosen. + * + * The default range is IPPORT_ANONMIN to IPPORT_ANONMAX, although + * that is settable by sysctl(3); net.inet.ip.anonportmin and + * net.inet.ip.anonportmax respectively. + * + * A user may set the IPPROTO_IP option IP_PORTRANGE to change this + * default assignment range. + * + * The value IP_PORTRANGE_DEFAULT causes the default behavior. + * + * The value IP_PORTRANGE_HIGH is the same as IP_PORTRANGE_DEFAULT, + * and exists only for FreeBSD compatibility purposes. + * + * The value IP_PORTRANGE_LOW changes the range to the "low" are + * that is (by convention) restricted to privileged processes. + * This convention is based on "vouchsafe" principles only. + * It is only secure if you trust the remote host to restrict these ports. + * The range is IPPORT_RESERVEDMIN to IPPORT_RESERVEDMAX. + */ + +#define IPV6PORT_RESERVED 1024 +#define IPV6PORT_ANONMIN 49152 +#define IPV6PORT_ANONMAX 65535 +#define IPV6PORT_RESERVEDMIN 600 +#define IPV6PORT_RESERVEDMAX (IPV6PORT_RESERVED-1) +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + +/* + * IPv6 address + */ +typedef struct in6_addr { + union { + __uint8_t __u6_addr8[16]; + __uint16_t __u6_addr16[8]; + __uint32_t __u6_addr32[4]; + } __u6_addr; /* 128-bit IP6 address */ +} in6_addr_t; + +#define s6_addr __u6_addr.__u6_addr8 + +#define INET6_ADDRSTRLEN 46 + +/* + * Socket address for IPv6 + */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SIN6_LEN +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +struct sockaddr_in6 { + __uint8_t sin6_len; /* length of this struct(sa_family_t) */ + sa_family_t sin6_family; /* AF_INET6 (sa_family_t) */ + in_port_t sin6_port; /* Transport layer port # (in_port_t) */ + __uint32_t sin6_flowinfo; /* IP6 flow information */ + struct in6_addr sin6_addr; /* IP6 address */ + __uint32_t sin6_scope_id; /* scope zone index */ +}; + + + + + +/* + * Definition of some useful macros to handle IP6 addresses + */ +#define IN6ADDR_ANY_INIT \ + {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}} +#define IN6ADDR_LOOPBACK_INIT \ + {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define IN6ADDR_NODELOCAL_ALLNODES_INIT \ + {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} +#define IN6ADDR_INTFACELOCAL_ALLNODES_INIT \ + {{{ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} +#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \ + {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}} +#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \ + {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}} +#define IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT \ + {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16 }}} +#define IN6ADDR_V4MAPPED_INIT \ + {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}} +#define IN6ADDR_MULTICAST_PREFIX IN6MASK8 +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + +extern const struct in6_addr in6addr_any; +extern const struct in6_addr in6addr_loopback; +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +extern const struct in6_addr in6addr_nodelocal_allnodes; +extern const struct in6_addr in6addr_linklocal_allnodes; +extern const struct in6_addr in6addr_linklocal_allrouters; +extern const struct in6_addr in6addr_linklocal_allv2routers; +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + +/* + * Equality + * NOTE: Some of kernel programming environment (for example, openbsd/sparc) + * does not supply memcmp(). For userland memcmp() is preferred as it is + * in ANSI standard. + */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define IN6_ARE_ADDR_EQUAL(a, b) \ + (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof (struct in6_addr)) \ + == 0) +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + + +/* + * Unspecified + */ +#define IN6_IS_ADDR_UNSPECIFIED(a) \ + ((*(const __uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[12]) == 0)) + +/* + * Loopback + */ +#define IN6_IS_ADDR_LOOPBACK(a) \ + ((*(const __uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[12]) == ntohl(1))) + +/* + * IPv4 compatible + */ +#define IN6_IS_ADDR_V4COMPAT(a) \ + ((*(const __uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[12]) != 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[12]) != ntohl(1))) + +/* + * Mapped + */ +#define IN6_IS_ADDR_V4MAPPED(a) \ + ((*(const __uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \ + (*(const __uint32_t *)(const void *)(&(a)->s6_addr[8]) == \ + ntohl(0x0000ffff))) + +/* + * 6to4 + */ +#define IN6_IS_ADDR_6TO4(x) (ntohs((x)->s6_addr16[0]) == 0x2002) + +/* + * KAME Scope Values + */ + +#define __IPV6_ADDR_SCOPE_NODELOCAL 0x01 +#define __IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 +#define __IPV6_ADDR_SCOPE_LINKLOCAL 0x02 +#define __IPV6_ADDR_SCOPE_SITELOCAL 0x05 +#define __IPV6_ADDR_SCOPE_ORGLOCAL 0x08 /* just used in this file */ +#define __IPV6_ADDR_SCOPE_GLOBAL 0x0e + +/* + * Unicast Scope + * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373). + */ +#define IN6_IS_ADDR_LINKLOCAL(a) \ + (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) +#define IN6_IS_ADDR_SITELOCAL(a) \ + (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) + +/* + * Multicast + */ +#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) + +#define IPV6_ADDR_MC_FLAGS(a) ((a)->s6_addr[1] & 0xf0) + +#define IPV6_ADDR_MC_FLAGS_TRANSIENT 0x10 +#define IPV6_ADDR_MC_FLAGS_PREFIX 0x20 +#define IPV6_ADDR_MC_FLAGS_UNICAST_BASED (IPV6_ADDR_MC_FLAGS_TRANSIENT | IPV6_ADDR_MC_FLAGS_PREFIX) + +#define IN6_IS_ADDR_UNICAST_BASED_MULTICAST(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (IPV6_ADDR_MC_FLAGS(a) == IPV6_ADDR_MC_FLAGS_UNICAST_BASED)) + +/* + * Unique Local IPv6 Unicast Addresses (per RFC 4193) + */ +#define IN6_IS_ADDR_UNIQUE_LOCAL(a) \ + (((a)->s6_addr[0] == 0xfc) || ((a)->s6_addr[0] == 0xfd)) + +#define __IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f) + +/* + * Multicast Scope + */ +#define IN6_IS_ADDR_MC_NODELOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL)) +#define IN6_IS_ADDR_MC_LINKLOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (IPV6_ADDR_MC_FLAGS(a) != IPV6_ADDR_MC_FLAGS_UNICAST_BASED) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL)) +#define IN6_IS_ADDR_MC_SITELOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL)) +#define IN6_IS_ADDR_MC_ORGLOCAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL)) +#define IN6_IS_ADDR_MC_GLOBAL(a) \ + (IN6_IS_ADDR_MULTICAST(a) && \ + (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL)) + + + + +/* + * Options for use with [gs]etsockopt at the IPV6 level. + * First word of comment is data type; bool is stored in int. + */ +/* no hdrincl */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +/* + * RFC 3542 define the following socket options in a manner incompatible + * with RFC 2292: + * IPV6_PKTINFO + * IPV6_HOPLIMIT + * IPV6_NEXTHOP + * IPV6_HOPOPTS + * IPV6_DSTOPTS + * IPV6_RTHDR + * + * To use the new IPv6 Sockets options introduced by RFC 3542 + * the constant __APPLE_USE_RFC_3542 must be defined before + * including + * + * To use the old IPv6 Sockets options from RFC 2292 + * the constant __APPLE_USE_RFC_2292 must be defined before + * including + * + * Note that eventually RFC 3542 is going to be the + * default and RFC 2292 will be obsolete. + */ + +#if defined(__APPLE_USE_RFC_3542) && defined(__APPLE_USE_RFC_2292) +#error "__APPLE_USE_RFC_3542 and __APPLE_USE_RFC_2292 cannot be both defined" +#endif + +#if 0 /* the followings are relic in IPv4 and hence are disabled */ +#define IPV6_OPTIONS 1 /* buf/ip6_opts; set/get IP6 options */ +#define IPV6_RECVOPTS 5 /* bool; receive all IP6 opts w/dgram */ +#define IPV6_RECVRETOPTS 6 /* bool; receive IP6 opts for response */ +#define IPV6_RECVDSTADDR 7 /* bool; receive IP6 dst addr w/dgram */ +#define IPV6_RETOPTS 8 /* ip6_opts; set/get IP6 options */ +#endif /* 0 */ +#define IPV6_SOCKOPT_RESERVED1 3 /* reserved for future use */ +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */ +#define IPV6_MULTICAST_IF 9 /* u_int; set/get IP6 multicast i/f */ +#define IPV6_MULTICAST_HOPS 10 /* int; set/get IP6 multicast hops */ +#define IPV6_MULTICAST_LOOP 11 /* u_int; set/get IP6 mcast loopback */ +#define IPV6_JOIN_GROUP 12 /* ip6_mreq; join a group membership */ +#define IPV6_LEAVE_GROUP 13 /* ip6_mreq; leave a group membership */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define IPV6_PORTRANGE 14 /* int; range to choose for unspec port */ +#define ICMP6_FILTER 18 /* icmp6_filter; icmp6 filter */ +#define IPV6_2292PKTINFO 19 /* bool; send/recv if, src/dst addr */ +#define IPV6_2292HOPLIMIT 20 /* bool; hop limit */ +#define IPV6_2292NEXTHOP 21 /* bool; next hop addr */ +#define IPV6_2292HOPOPTS 22 /* bool; hop-by-hop option */ +#define IPV6_2292DSTOPTS 23 /* bool; destinaion option */ +#define IPV6_2292RTHDR 24 /* ip6_rthdr: routing header */ + +/* buf/cmsghdr; set/get IPv6 options [obsoleted by RFC3542] */ +#define IPV6_2292PKTOPTIONS 25 + +#ifdef __APPLE_USE_RFC_2292 +#define IPV6_PKTINFO IPV6_2292PKTINFO +#define IPV6_HOPLIMIT IPV6_2292HOPLIMIT +#define IPV6_NEXTHOP IPV6_2292NEXTHOP +#define IPV6_HOPOPTS IPV6_2292HOPOPTS +#define IPV6_DSTOPTS IPV6_2292DSTOPTS +#define IPV6_RTHDR IPV6_2292RTHDR +#define IPV6_PKTOPTIONS IPV6_2292PKTOPTIONS +#endif /* __APPLE_USE_RFC_2292 */ + +#define IPV6_CHECKSUM 26 /* int; checksum offset for raw socket */ +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#define IPV6_V6ONLY 27 /* bool; only bind INET6 at wildcard bind */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define IPV6_BINDV6ONLY IPV6_V6ONLY + + +#if 1 /* IPSEC */ +#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */ +#endif /* 1 */ +#define IPV6_FAITH 29 /* deprecated */ + +#if 1 /* IPV6FIREWALL */ +#define IPV6_FW_ADD 30 /* add a firewall rule to chain */ +#define IPV6_FW_DEL 31 /* delete a firewall rule from chain */ +#define IPV6_FW_FLUSH 32 /* flush firewall rule chain */ +#define IPV6_FW_ZERO 33 /* clear single/all firewall counter(s) */ +#define IPV6_FW_GET 34 /* get entire firewall rule chain */ +#endif /* 1 */ + +/* + * APPLE: NOTE the value of those 2 options is kept unchanged from + * previous version of darwin/OS X for binary compatibility reasons + * and differ from FreeBSD (values 57 and 61). See below. + */ +#define IPV6_RECVTCLASS 35 /* bool; recv traffic class values */ +#define IPV6_TCLASS 36 /* int; send traffic class value */ + +#ifdef __APPLE_USE_RFC_3542 +/* new socket options introduced in RFC3542 */ +/* + * ip6_dest; send dst option before rthdr + * APPLE: Value purposely different than FreeBSD (35) to avoid + * collision with definition of IPV6_RECVTCLASS in previous + * darwin implementations + */ +#define IPV6_RTHDRDSTOPTS 57 + +/* + * bool; recv if, dst addr + * APPLE: Value purposely different than FreeBSD(36) to avoid + * collision with definition of IPV6_TCLASS in previous + * darwin implementations + */ +#define IPV6_RECVPKTINFO 61 + +#define IPV6_RECVHOPLIMIT 37 /* bool; recv hop limit */ +#define IPV6_RECVRTHDR 38 /* bool; recv routing header */ +#define IPV6_RECVHOPOPTS 39 /* bool; recv hop-by-hop option */ +#define IPV6_RECVDSTOPTS 40 /* bool; recv dst option after rthdr */ + +#define IPV6_USE_MIN_MTU 42 /* bool; send packets at the minimum MTU */ +#define IPV6_RECVPATHMTU 43 /* bool; notify an according MTU */ + +/* + * mtuinfo; get the current path MTU (sopt), 4 bytes int; + * MTU notification (cmsg) + */ +#define IPV6_PATHMTU 44 + +#if 0 /* obsoleted during 2292bis -> 3542 */ +/* no data; ND reachability confirm (cmsg only/not in of RFC3542) */ +#define IPV6_REACHCONF 45 +#endif +/* more new socket options introduced in RFC3542 */ +#define IPV6_3542PKTINFO 46 /* in6_pktinfo; send if, src addr */ +#define IPV6_3542HOPLIMIT 47 /* int; send hop limit */ +#define IPV6_3542NEXTHOP 48 /* sockaddr; next hop addr */ +#define IPV6_3542HOPOPTS 49 /* ip6_hbh; send hop-by-hop option */ +#define IPV6_3542DSTOPTS 50 /* ip6_dest; send dst option befor rthdr */ +#define IPV6_3542RTHDR 51 /* ip6_rthdr; send routing header */ + +#define IPV6_PKTINFO IPV6_3542PKTINFO +#define IPV6_HOPLIMIT IPV6_3542HOPLIMIT +#define IPV6_NEXTHOP IPV6_3542NEXTHOP +#define IPV6_HOPOPTS IPV6_3542HOPOPTS +#define IPV6_DSTOPTS IPV6_3542DSTOPTS +#define IPV6_RTHDR IPV6_3542RTHDR + +#define IPV6_AUTOFLOWLABEL 59 /* bool; attach flowlabel automagically */ + +#define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */ + +/* int; prefer temporary addresses as the source address. */ +#define IPV6_PREFER_TEMPADDR 63 + +/* + * The following option is private; do not use it from user applications. + * It is deliberately defined to the same value as IP_MSFILTER. + */ +#define IPV6_MSFILTER 74 /* struct __msfilterreq; */ +#endif /* __APPLE_USE_RFC_3542 */ + +#define IPV6_BOUND_IF 125 /* int; set/get bound interface */ + + +/* to define items, should talk with KAME guys first, for *BSD compatibility */ + +#define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. */ +#define IPV6_RTHDR_STRICT 1 /* this hop must be a neighbor. */ +#define IPV6_RTHDR_TYPE_0 0 /* IPv6 routing header type 0 */ + +/* + * Defaults and limits for options + */ +#define IPV6_DEFAULT_MULTICAST_HOPS 1 /* normally limit m'casts to 1 hop */ +#define IPV6_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ + +/* + * The im6o_membership vector for each socket is now dynamically allocated at + * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized + * according to a power-of-two increment. + */ +#define IPV6_MIN_MEMBERSHIPS 31 +#define IPV6_MAX_MEMBERSHIPS 4095 + +/* + * Default resource limits for IPv6 multicast source filtering. + * These may be modified by sysctl. + */ +#define IPV6_MAX_GROUP_SRC_FILTER 512 /* sources per group */ +#define IPV6_MAX_SOCK_SRC_FILTER 128 /* sources per socket/group */ + +/* + * Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP. + */ +struct ipv6_mreq { + struct in6_addr ipv6mr_multiaddr; + unsigned int ipv6mr_interface; +}; + +/* + * IPV6_2292PKTINFO: Packet information(RFC2292 sec 5) + */ +struct in6_pktinfo { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; + +/* + * Control structure for IPV6_RECVPATHMTU socket option. + */ +struct ip6_mtuinfo { + struct sockaddr_in6 ip6m_addr; /* or sockaddr_storage? */ + uint32_t ip6m_mtu; +}; + +/* + * Argument for IPV6_PORTRANGE: + * - which range to search when port is unspecified at bind() or connect() + */ +#define IPV6_PORTRANGE_DEFAULT 0 /* default range */ +#define IPV6_PORTRANGE_HIGH 1 /* "high" - request firewall bypass */ +#define IPV6_PORTRANGE_LOW 2 /* "low" - vouchsafe security */ + +/* + * Definitions for inet6 sysctl operations. + * + * Third level is protocol number. + * Fourth level is desired variable within that protocol. + */ +#define IPV6PROTO_MAXID (IPPROTO_PIM + 1) /* don't list to IPV6PROTO_MAX */ + +/* + * Names for IP sysctl objects + */ +#define IPV6CTL_FORWARDING 1 /* act as router */ +#define IPV6CTL_SENDREDIRECTS 2 /* may send redirects when forwarding */ +#define IPV6CTL_DEFHLIM 3 /* default Hop-Limit */ +#ifdef notyet +#define IPV6CTL_DEFMTU 4 /* default MTU */ +#endif +#define IPV6CTL_FORWSRCRT 5 /* forward source-routed dgrams */ +#define IPV6CTL_STATS 6 /* stats */ +#define IPV6CTL_MRTSTATS 7 /* multicast forwarding stats */ +#define IPV6CTL_MRTPROTO 8 /* multicast routing protocol */ +#define IPV6CTL_MAXFRAGPACKETS 9 /* max packets reassembly queue */ +#define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */ +#define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimume logging interval */ +#define IPV6CTL_ACCEPT_RTADV 12 +#define IPV6CTL_KEEPFAITH 13 /* deprecated */ +#define IPV6CTL_LOG_INTERVAL 14 +#define IPV6CTL_HDRNESTLIMIT 15 +#define IPV6CTL_DAD_COUNT 16 +#define IPV6CTL_AUTO_FLOWLABEL 17 +#define IPV6CTL_DEFMCASTHLIM 18 +#define IPV6CTL_GIF_HLIM 19 /* default HLIM for gif encap packet */ +#define IPV6CTL_KAME_VERSION 20 +#define IPV6CTL_USE_DEPRECATED 21 /* use deprec addr (RFC2462 5.5.4) */ +#define IPV6CTL_RR_PRUNE 22 /* walk timer for router renumbering */ +#if 0 /* obsolete */ +#define IPV6CTL_MAPPED_ADDR 23 +#endif +#define IPV6CTL_V6ONLY 24 +#define IPV6CTL_RTEXPIRE 25 /* cloned route expiration time */ +#define IPV6CTL_RTMINEXPIRE 26 /* min value for expiration time */ +#define IPV6CTL_RTMAXCACHE 27 /* trigger level for dynamic expire */ + +#define IPV6CTL_USETEMPADDR 32 /* use temporary addresses [RFC 4941] */ +#define IPV6CTL_TEMPPLTIME 33 /* preferred lifetime for tmpaddrs */ +#define IPV6CTL_TEMPVLTIME 34 /* valid lifetime for tmpaddrs */ +#define IPV6CTL_AUTO_LINKLOCAL 35 /* automatic link-local addr assign */ +#define IPV6CTL_RIP6STATS 36 /* raw_ip6 stats */ +#define IPV6CTL_PREFER_TEMPADDR 37 /* prefer temporary addr as src */ +#define IPV6CTL_ADDRCTLPOLICY 38 /* get/set address selection policy */ +#define IPV6CTL_USE_DEFAULTZONE 39 /* use default scope zone */ + +#define IPV6CTL_MAXFRAGS 41 /* max fragments */ +#define IPV6CTL_MCAST_PMTU 44 /* enable pMTU discovery for mcast? */ + +#define IPV6CTL_NEIGHBORGCTHRESH 46 +#define IPV6CTL_MAXIFPREFIXES 47 +#define IPV6CTL_MAXIFDEFROUTERS 48 +#define IPV6CTL_MAXDYNROUTES 49 +#define ICMPV6CTL_ND6_ONLINKNSRFC4861 50 + +/* New entries should be added here from current IPV6CTL_MAXID value. */ +/* to define items, should talk with KAME guys first, for *BSD compatibility */ +#define IPV6CTL_MAXID 51 + + + + + +__BEGIN_DECLS +struct cmsghdr; + +extern int inet6_option_space(int); +extern int inet6_option_init(void *, struct cmsghdr **, int); +extern int inet6_option_append(struct cmsghdr *, const __uint8_t *, int, int); +extern __uint8_t *inet6_option_alloc(struct cmsghdr *, int, int, int); +extern int inet6_option_next(const struct cmsghdr *, __uint8_t **); +extern int inet6_option_find(const struct cmsghdr *, __uint8_t **, int); + +extern size_t inet6_rthdr_space(int, int); +extern struct cmsghdr *inet6_rthdr_init(void *, int); +extern int inet6_rthdr_add(struct cmsghdr *, const struct in6_addr *, + unsigned int); +extern int inet6_rthdr_lasthop(struct cmsghdr *, unsigned int); +#if 0 /* not implemented yet */ +extern int inet6_rthdr_reverse(const struct cmsghdr *, struct cmsghdr *); +#endif +extern int inet6_rthdr_segments(const struct cmsghdr *); +extern struct in6_addr *inet6_rthdr_getaddr(struct cmsghdr *, int); +extern int inet6_rthdr_getflags(const struct cmsghdr *, int); + +extern int inet6_opt_init(void *, socklen_t); +extern int inet6_opt_append(void *, socklen_t, int, __uint8_t, socklen_t, + __uint8_t, void **); +extern int inet6_opt_finish(void *, socklen_t, int); +extern int inet6_opt_set_val(void *, int, void *, socklen_t); + +extern int inet6_opt_next(void *, socklen_t, int, __uint8_t *, socklen_t *, + void **); +extern int inet6_opt_find(void *, socklen_t, int, __uint8_t, socklen_t *, + void **); +extern int inet6_opt_get_val(void *, int, void *, socklen_t); +extern socklen_t inet6_rth_space(int, int); +extern void *inet6_rth_init(void *, socklen_t, int, int); +extern int inet6_rth_add(void *, const struct in6_addr *); +extern int inet6_rth_reverse(const void *, void *); +extern int inet6_rth_segments(const void *); +extern struct in6_addr *inet6_rth_getaddr(const void *, int); + +__END_DECLS +#endif /* PLATFORM_DriverKit */ +#endif /* !_NETINET6_IN6_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/objc/NSObjCRuntime.h b/lib/libc/include/any-macos.11-any/objc/NSObjCRuntime.h new file mode 100644 index 0000000000..c0d01f928e --- /dev/null +++ b/lib/libc/include/any-macos.11-any/objc/NSObjCRuntime.h @@ -0,0 +1,33 @@ +/* NSObjCRuntime.h + Copyright (c) 1994-2012, Apple Inc. All rights reserved. +*/ + +#ifndef _OBJC_NSOBJCRUNTIME_H_ +#define _OBJC_NSOBJCRUNTIME_H_ + +#include +#include + +#if __LP64__ || 0 || NS_BUILD_32_LIKE_64 +typedef long NSInteger; +typedef unsigned long NSUInteger; +#else +typedef int NSInteger; +typedef unsigned int NSUInteger; +#endif + +#define NSIntegerMax LONG_MAX +#define NSIntegerMin LONG_MIN +#define NSUIntegerMax ULONG_MAX + +#define NSINTEGER_DEFINED 1 + +#ifndef NS_DESIGNATED_INITIALIZER +#if __has_attribute(objc_designated_initializer) +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +#else +#define NS_DESIGNATED_INITIALIZER +#endif +#endif + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/objc/message.h b/lib/libc/include/any-macos.11-any/objc/message.h new file mode 100644 index 0000000000..3c9a5e0d08 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/objc/message.h @@ -0,0 +1,388 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OBJC_MESSAGE_H +#define _OBJC_MESSAGE_H + +#include +#include + +#ifndef OBJC_SUPER +#define OBJC_SUPER + +/// Specifies the superclass of an instance. +struct objc_super { + /// Specifies an instance of a class. + __unsafe_unretained _Nonnull id receiver; + + /// Specifies the particular superclass of the instance to message. +#if !defined(__cplusplus) && !__OBJC2__ + /* For compatibility with old objc-runtime.h header */ + __unsafe_unretained _Nonnull Class class; +#else + __unsafe_unretained _Nonnull Class super_class; +#endif + /* super_class is the first class to search */ +}; +#endif + + +/* Basic Messaging Primitives + * + * On some architectures, use objc_msgSend_stret for some struct return types. + * On some architectures, use objc_msgSend_fpret for some float return types. + * On some architectures, use objc_msgSend_fp2ret for some float return types. + * + * These functions must be cast to an appropriate function pointer type + * before being called. + */ +#if !OBJC_OLD_DISPATCH_PROTOTYPES +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +OBJC_EXPORT void +objc_msgSend(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); +#pragma clang diagnostic pop +#else +/** + * Sends a message with a simple return value to an instance of a class. + * + * @param self A pointer to the instance of the class that is to receive the message. + * @param op The selector of the method that handles the message. + * @param ... + * A variable argument list containing the arguments to the method. + * + * @return The return value of the method. + * + * @note When it encounters a method call, the compiler generates a call to one of the + * functions \c objc_msgSend, \c objc_msgSend_stret, \c objc_msgSendSuper, or \c objc_msgSendSuper_stret. + * Messages sent to an object’s superclass (using the \c super keyword) are sent using \c objc_msgSendSuper; + * other messages are sent using \c objc_msgSend. Methods that have data structures as return values + * are sent using \c objc_msgSendSuper_stret and \c objc_msgSend_stret. + */ +OBJC_EXPORT id _Nullable +objc_msgSend(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); +/** + * Sends a message with a simple return value to the superclass of an instance of a class. + * + * @param super A pointer to an \c objc_super data structure. Pass values identifying the + * context the message was sent to, including the instance of the class that is to receive the + * message and the superclass at which to start searching for the method implementation. + * @param op A pointer of type SEL. Pass the selector of the method that will handle the message. + * @param ... + * A variable argument list containing the arguments to the method. + * + * @return The return value of the method identified by \e op. + * + * @see objc_msgSend + */ +OBJC_EXPORT id _Nullable +objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); +#endif + + +/* Struct-returning Messaging Primitives + * + * Use these functions to call methods that return structs on the stack. + * On some architectures, some structures are returned in registers. + * Consult your local function call ABI documentation for details. + * + * These functions must be cast to an appropriate function pointer type + * before being called. + */ +#if !OBJC_OLD_DISPATCH_PROTOTYPES +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +OBJC_EXPORT void +objc_msgSend_stret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSendSuper_stret(void /* struct objc_super *super, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; +#pragma clang diagnostic pop +#else +/** + * Sends a message with a data-structure return value to an instance of a class. + * + * @see objc_msgSend + */ +OBJC_EXPORT void +objc_msgSend_stret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; + +/** + * Sends a message with a data-structure return value to the superclass of an instance of a class. + * + * @see objc_msgSendSuper + */ +OBJC_EXPORT void +objc_msgSendSuper_stret(struct objc_super * _Nonnull super, + SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; +#endif + + +/* Floating-point-returning Messaging Primitives + * + * Use these functions to call methods that return floating-point values + * on the stack. + * Consult your local function call ABI documentation for details. + * + * arm: objc_msgSend_fpret not used + * i386: objc_msgSend_fpret used for `float`, `double`, `long double`. + * x86-64: objc_msgSend_fpret used for `long double`. + * + * arm: objc_msgSend_fp2ret not used + * i386: objc_msgSend_fp2ret not used + * x86-64: objc_msgSend_fp2ret used for `_Complex long double`. + * + * These functions must be cast to an appropriate function pointer type + * before being called. + */ +#if !OBJC_OLD_DISPATCH_PROTOTYPES +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" + +# if defined(__i386__) + +OBJC_EXPORT void +objc_msgSend_fpret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.4, 2.0, 9.0, 1.0, 2.0); + +# elif defined(__x86_64__) + +OBJC_EXPORT void +objc_msgSend_fpret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_msgSend_fp2ret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +#pragma clang diagnostic pop +# endif + +// !OBJC_OLD_DISPATCH_PROTOTYPES +#else +// OBJC_OLD_DISPATCH_PROTOTYPES +# if defined(__i386__) + +/** + * Sends a message with a floating-point return value to an instance of a class. + * + * @see objc_msgSend + * @note On the i386 platform, the ABI for functions returning a floating-point value is + * incompatible with that for functions returning an integral type. On the i386 platform, therefore, + * you must use \c objc_msgSend_fpret for functions returning non-integral type. For \c float or + * \c long \c double return types, cast the function to an appropriate function pointer type first. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +OBJC_EXPORT double +objc_msgSend_fpret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.4, 2.0, 9.0, 1.0, 2.0); +#pragma clang diagnostic pop + +/* Use objc_msgSendSuper() for fp-returning messages to super. */ +/* See also objc_msgSendv_fpret() below. */ + +# elif defined(__x86_64__) +/** + * Sends a message with a floating-point return value to an instance of a class. + * + * @see objc_msgSend + */ +OBJC_EXPORT long double +objc_msgSend_fpret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +# if __STDC_VERSION__ >= 199901L +OBJC_EXPORT _Complex long double +objc_msgSend_fp2ret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); +# else +OBJC_EXPORT void objc_msgSend_fp2ret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); +# endif + +/* Use objc_msgSendSuper() for fp-returning messages to super. */ +/* See also objc_msgSendv_fpret() below. */ + +# endif + +// OBJC_OLD_DISPATCH_PROTOTYPES +#endif + + +/* Direct Method Invocation Primitives + * Use these functions to call the implementation of a given Method. + * This is faster than calling method_getImplementation() and method_getName(). + * + * The receiver must not be nil. + * + * These functions must be cast to an appropriate function pointer type + * before being called. + */ +#if !OBJC_OLD_DISPATCH_PROTOTYPES +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +OBJC_EXPORT void +method_invoke(void /* id receiver, Method m, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +method_invoke_stret(void /* id receiver, Method m, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; +#pragma clang diagnostic pop +#else +OBJC_EXPORT id _Nullable +method_invoke(id _Nullable receiver, Method _Nonnull m, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +method_invoke_stret(id _Nullable receiver, Method _Nonnull m, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; +#endif + + +/* Message Forwarding Primitives + * Use these functions to forward a message as if the receiver did not + * respond to it. + * + * The receiver must not be nil. + * + * class_getMethodImplementation() may return (IMP)_objc_msgForward. + * class_getMethodImplementation_stret() may return (IMP)_objc_msgForward_stret + * + * These functions must be cast to an appropriate function pointer type + * before being called. + * + * Before Mac OS X 10.6, _objc_msgForward must not be called directly + * but may be compared to other IMP values. + */ +#if !OBJC_OLD_DISPATCH_PROTOTYPES +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +OBJC_EXPORT void +_objc_msgForward(void /* id receiver, SEL sel, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +_objc_msgForward_stret(void /* id receiver, SEL sel, ... */ ) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; +#pragma clang diagnostic pop +#else +OBJC_EXPORT id _Nullable +_objc_msgForward(id _Nonnull receiver, SEL _Nonnull sel, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +_objc_msgForward_stret(id _Nonnull receiver, SEL _Nonnull sel, ...) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0) + OBJC_ARM64_UNAVAILABLE; +#endif + + +/* Variable-argument Messaging Primitives + * + * Use these functions to call methods with a list of arguments, such + * as the one passed to forward:: . + * + * The contents of the argument list are architecture-specific. + * Consult your local function call ABI documentation for details. + * + * These functions must be cast to an appropriate function pointer type + * before being called, except for objc_msgSendv_stret() which must not + * be cast to a struct-returning type. + */ + +typedef void* marg_list; + +OBJC_EXPORT id _Nullable +objc_msgSendv(id _Nullable self, SEL _Nonnull op, size_t arg_size, + marg_list _Nonnull arg_frame) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSendv_stret(void * _Nonnull stretAddr, id _Nullable self, + SEL _Nonnull op, size_t arg_size, + marg_list _Nullable arg_frame) + OBJC2_UNAVAILABLE; +/* Note that objc_msgSendv_stret() does not return a structure type, + * and should not be cast to do so. This is unlike objc_msgSend_stret() + * and objc_msgSendSuper_stret(). + */ +#if defined(__i386__) +OBJC_EXPORT double +objc_msgSendv_fpret(id _Nullable self, SEL _Nonnull op, + unsigned arg_size, marg_list _Nullable arg_frame) + OBJC2_UNAVAILABLE; +#endif + + +/* The following marg_list macros are of marginal utility. They + * are included for compatibility with the old objc-class.h header. */ + +#if !__OBJC2__ + +#define marg_prearg_size 0 + +#define marg_malloc(margs, method) \ + do { \ + margs = (marg_list *)malloc (marg_prearg_size + ((7 + method_getSizeOfArguments(method)) & ~7)); \ + } while (0) + +#define marg_free(margs) \ + do { \ + free(margs); \ + } while (0) + +#define marg_adjustedOffset(method, offset) \ + (marg_prearg_size + offset) + +#define marg_getRef(margs, offset, type) \ + ( (type *)((char *)margs + marg_adjustedOffset(method,offset) ) ) + +#define marg_getValue(margs, offset, type) \ + ( *marg_getRef(margs, offset, type) ) + +#define marg_setValue(margs, offset, type, value) \ + ( marg_getValue(margs, offset, type) = (value) ) + +#endif + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/objc/objc-api.h b/lib/libc/include/any-macos.11-any/objc/objc-api.h new file mode 100644 index 0000000000..7f905ae76c --- /dev/null +++ b/lib/libc/include/any-macos.11-any/objc/objc-api.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 1999-2006 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +// Copyright 1988-1996 NeXT Software, Inc. + +#ifndef _OBJC_OBJC_API_H_ +#define _OBJC_OBJC_API_H_ + +#include +#include +#include +#include + +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +#ifndef __has_extension +# define __has_extension __has_feature +#endif + +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif + +#if !__has_feature(nullability) +# ifndef _Nullable +# define _Nullable +# endif +# ifndef _Nonnull +# define _Nonnull +# endif +# ifndef _Null_unspecified +# define _Null_unspecified +# endif +#endif + + + +/* + * OBJC_API_VERSION 0 or undef: Tiger and earlier API only + * OBJC_API_VERSION 2: Leopard and later API available + */ +#if !defined(OBJC_API_VERSION) +# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_5 +# define OBJC_API_VERSION 0 +# else +# define OBJC_API_VERSION 2 +# endif +#endif + + +/* + * OBJC_NO_GC 1: GC is not supported + * OBJC_NO_GC undef: GC is supported. This SDK no longer supports this mode. + * + * OBJC_NO_GC_API undef: Libraries must export any symbols that + * dual-mode code may links to. + * OBJC_NO_GC_API 1: Libraries need not export GC-related symbols. + */ +#if defined(__OBJC_GC__) +# error Objective-C garbage collection is not supported. +#elif TARGET_OS_OSX + /* GC is unsupported. GC API symbols are exported. */ +# define OBJC_NO_GC 1 +# undef OBJC_NO_GC_API +#else + /* GC is unsupported. GC API symbols are not exported. */ +# define OBJC_NO_GC 1 +# define OBJC_NO_GC_API 1 +#endif + + +/* NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER == 1 + * marks -[NSObject init] as a designated initializer. */ +#if !defined(NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER) +# define NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER 1 +#endif + +/* The arm64 ABI requires proper casting to ensure arguments are passed + * * correctly. */ +#if defined(__arm64__) && !__swift__ +# undef OBJC_OLD_DISPATCH_PROTOTYPES +# define OBJC_OLD_DISPATCH_PROTOTYPES 0 +#endif + +/* OBJC_OLD_DISPATCH_PROTOTYPES == 0 enforces the rule that the dispatch + * functions must be cast to an appropriate function pointer type. */ +#if !defined(OBJC_OLD_DISPATCH_PROTOTYPES) +# if __swift__ + // Existing Swift code expects IMP to be Comparable. + // Variadic IMP is comparable via OpaquePointer; non-variadic IMP isn't. +# define OBJC_OLD_DISPATCH_PROTOTYPES 1 +# else +# define OBJC_OLD_DISPATCH_PROTOTYPES 0 +# endif +#endif + + +/* OBJC_AVAILABLE: shorthand for all-OS availability */ + +# if !defined(OBJC_AVAILABLE) +# define OBJC_AVAILABLE(x, i, t, w, b) \ + __OSX_AVAILABLE(x) __IOS_AVAILABLE(i) __TVOS_AVAILABLE(t) \ + __WATCHOS_AVAILABLE(w) +# endif + + + +/* OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE: Deprecated on OS X, + * unavailable everywhere else. */ + +# if !defined(OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE) +# define OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(_start, _dep, _msg) \ + __OSX_DEPRECATED(_start, _dep, _msg) \ + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE \ + __WATCHOS_UNAVAILABLE +# endif + + + +/* OBJC_OSX_AVAILABLE_OTHERS_UNAVAILABLE: Available on OS X, + * unavailable everywhere else. */ + +# if !defined(OBJC_OSX_AVAILABLE_OTHERS_UNAVAILABLE) +# define OBJC_OSX_AVAILABLE_OTHERS_UNAVAILABLE(vers) \ + __OSX_AVAILABLE(vers) \ + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE \ + __WATCHOS_UNAVAILABLE +# endif + + + +/* OBJC_ISA_AVAILABILITY: `isa` will be deprecated or unavailable + * in the future */ +#if !defined(OBJC_ISA_AVAILABILITY) +# if __OBJC2__ +# define OBJC_ISA_AVAILABILITY __attribute__((deprecated)) +# else +# define OBJC_ISA_AVAILABILITY /* still available */ +# endif +#endif + + +/* OBJC2_UNAVAILABLE: unavailable in objc 2.0, deprecated in Leopard */ +#if !defined(OBJC2_UNAVAILABLE) +# if __OBJC2__ +# define OBJC2_UNAVAILABLE UNAVAILABLE_ATTRIBUTE +# else + /* plain C code also falls here, but this is close enough */ +# define OBJC2_UNAVAILABLE \ + __OSX_DEPRECATED(10.5, 10.5, "not available in __OBJC2__") \ + __IOS_DEPRECATED(2.0, 2.0, "not available in __OBJC2__") \ + __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE +# endif +#endif + +/* OBJC_UNAVAILABLE: unavailable, with a message where supported */ +#if !defined(OBJC_UNAVAILABLE) +# if __has_extension(attribute_unavailable_with_message) +# define OBJC_UNAVAILABLE(_msg) __attribute__((unavailable(_msg))) +# else +# define OBJC_UNAVAILABLE(_msg) __attribute__((unavailable)) +# endif +#endif + +/* OBJC_DEPRECATED: deprecated, with a message where supported */ +#if !defined(OBJC_DEPRECATED) +# if __has_extension(attribute_deprecated_with_message) +# define OBJC_DEPRECATED(_msg) __attribute__((deprecated(_msg))) +# else +# define OBJC_DEPRECATED(_msg) __attribute__((deprecated)) +# endif +#endif + +/* OBJC_ARC_UNAVAILABLE: unavailable with -fobjc-arc */ +#if !defined(OBJC_ARC_UNAVAILABLE) +# if __has_feature(objc_arc) +# define OBJC_ARC_UNAVAILABLE OBJC_UNAVAILABLE("not available in automatic reference counting mode") +# else +# define OBJC_ARC_UNAVAILABLE +# endif +#endif + +/* OBJC_SWIFT_UNAVAILABLE: unavailable in Swift */ +#if !defined(OBJC_SWIFT_UNAVAILABLE) +# if __has_feature(attribute_availability_swift) +# define OBJC_SWIFT_UNAVAILABLE(_msg) __attribute__((availability(swift, unavailable, message=_msg))) +# else +# define OBJC_SWIFT_UNAVAILABLE(_msg) +# endif +#endif + +/* OBJC_ARM64_UNAVAILABLE: unavailable on arm64 (i.e. stret dispatch) */ +#if !defined(OBJC_ARM64_UNAVAILABLE) +# if defined(__arm64__) +# define OBJC_ARM64_UNAVAILABLE OBJC_UNAVAILABLE("not available in arm64") +# else +# define OBJC_ARM64_UNAVAILABLE +# endif +#endif + +/* OBJC_GC_UNAVAILABLE: unavailable with -fobjc-gc or -fobjc-gc-only */ +#if !defined(OBJC_GC_UNAVAILABLE) +# define OBJC_GC_UNAVAILABLE +#endif + +#if !defined(OBJC_EXTERN) +# if defined(__cplusplus) +# define OBJC_EXTERN extern "C" +# else +# define OBJC_EXTERN extern +# endif +#endif + +#if !defined(OBJC_VISIBLE) + +# define OBJC_VISIBLE __attribute__((visibility("default"))) + +#endif + +#if !defined(OBJC_EXPORT) +# define OBJC_EXPORT OBJC_EXTERN OBJC_VISIBLE +#endif + +#if !defined(OBJC_IMPORT) +# define OBJC_IMPORT extern +#endif + +#if !defined(OBJC_ROOT_CLASS) +# if __has_attribute(objc_root_class) +# define OBJC_ROOT_CLASS __attribute__((objc_root_class)) +# else +# define OBJC_ROOT_CLASS +# endif +#endif + +#ifndef __DARWIN_NULL +#define __DARWIN_NULL NULL +#endif + +#if !defined(OBJC_INLINE) +# define OBJC_INLINE __inline +#endif + +// Declares an enum type or option bits type as appropriate for each language. +#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) +#define OBJC_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#if (__cplusplus) +#define OBJC_OPTIONS(_type, _name) _type _name; enum : _type +#else +#define OBJC_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#endif +#else +#define OBJC_ENUM(_type, _name) _type _name; enum +#define OBJC_OPTIONS(_type, _name) _type _name; enum +#endif + +#if !defined(OBJC_RETURNS_RETAINED) +# if __OBJC__ && __has_attribute(ns_returns_retained) +# define OBJC_RETURNS_RETAINED __attribute__((ns_returns_retained)) +# else +# define OBJC_RETURNS_RETAINED +# endif +#endif + +/* OBJC_COLD: very rarely called, e.g. on error path */ +#if !defined(OBJC_COLD) +# if __OBJC__ && __has_attribute(cold) +# define OBJC_COLD __attribute__((cold)) +# else +# define OBJC_COLD +# endif +#endif + +/* OBJC_NORETURN: does not return normally, but may throw */ +#if !defined(OBJC_NORETURN) +# if __OBJC__ && __has_attribute(noreturn) +# define OBJC_NORETURN __attribute__((noreturn)) +# else +# define OBJC_NORETURN +# endif +#endif + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/objc/runtime.h b/lib/libc/include/any-macos.11-any/objc/runtime.h index 66a8af31ae..3e4440f632 100644 --- a/lib/libc/include/any-macos.11-any/objc/runtime.h +++ b/lib/libc/include/any-macos.11-any/objc/runtime.h @@ -52,6 +52,24 @@ typedef struct objc_category *Category; /// An opaque type that represents an Objective-C declared property. typedef struct objc_property *objc_property_t; +struct objc_class { + Class _Nonnull isa OBJC_ISA_AVAILABILITY; + +#if !__OBJC2__ + Class _Nullable super_class OBJC2_UNAVAILABLE; + const char * _Nonnull name OBJC2_UNAVAILABLE; + long version OBJC2_UNAVAILABLE; + long info OBJC2_UNAVAILABLE; + long instance_size OBJC2_UNAVAILABLE; + struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; + struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE; + struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE; +#endif + +} OBJC2_UNAVAILABLE; +/* Use `Class` instead of `struct objc_class *` */ + #endif #ifdef __OBJC__ @@ -1859,8 +1877,154 @@ _objc_realizeClassFromSwift(Class _Nullable cls, void * _Nullable previously) #define _C_VECTOR '!' #define _C_CONST 'r' + +/* Obsolete types */ + +#if !__OBJC2__ + +#define CLS_GETINFO(cls,infomask) ((cls)->info & (infomask)) +#define CLS_SETINFO(cls,infomask) ((cls)->info |= (infomask)) + +// class is not a metaclass +#define CLS_CLASS 0x1 +// class is a metaclass +#define CLS_META 0x2 +// class's +initialize method has completed +#define CLS_INITIALIZED 0x4 +// class is posing +#define CLS_POSING 0x8 +// unused +#define CLS_MAPPED 0x10 +// class and subclasses need cache flush during image loading +#define CLS_FLUSH_CACHE 0x20 +// method cache should grow when full +#define CLS_GROW_CACHE 0x40 +// unused +#define CLS_NEED_BIND 0x80 +// methodLists is array of method lists +#define CLS_METHOD_ARRAY 0x100 +// the JavaBridge constructs classes with these markers +#define CLS_JAVA_HYBRID 0x200 +#define CLS_JAVA_CLASS 0x400 +// thread-safe +initialize +#define CLS_INITIALIZING 0x800 +// bundle unloading +#define CLS_FROM_BUNDLE 0x1000 +// C++ ivar support +#define CLS_HAS_CXX_STRUCTORS 0x2000 +// Lazy method list arrays +#define CLS_NO_METHOD_ARRAY 0x4000 +// +load implementation +#define CLS_HAS_LOAD_METHOD 0x8000 +// objc_allocateClassPair API +#define CLS_CONSTRUCTING 0x10000 +// class compiled with bigger class structure +#define CLS_EXT 0x20000 + + +struct objc_method_description_list { + int count; + struct objc_method_description list[1]; +}; + + +struct objc_protocol_list { + struct objc_protocol_list * _Nullable next; + long count; + __unsafe_unretained Protocol * _Nullable list[1]; +}; + + +struct objc_category { + char * _Nonnull category_name OBJC2_UNAVAILABLE; + char * _Nonnull class_name OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable instance_methods OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable class_methods OBJC2_UNAVAILABLE; + struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE; +} OBJC2_UNAVAILABLE; + + +struct objc_ivar { + char * _Nullable ivar_name OBJC2_UNAVAILABLE; + char * _Nullable ivar_type OBJC2_UNAVAILABLE; + int ivar_offset OBJC2_UNAVAILABLE; +#ifdef __LP64__ + int space OBJC2_UNAVAILABLE; +#endif +} OBJC2_UNAVAILABLE; + +struct objc_ivar_list { + int ivar_count OBJC2_UNAVAILABLE; +#ifdef __LP64__ + int space OBJC2_UNAVAILABLE; +#endif + /* variable length structure */ + struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE; +} OBJC2_UNAVAILABLE; + + +struct objc_method { + SEL _Nonnull method_name OBJC2_UNAVAILABLE; + char * _Nullable method_types OBJC2_UNAVAILABLE; + IMP _Nonnull method_imp OBJC2_UNAVAILABLE; +} OBJC2_UNAVAILABLE; + +struct objc_method_list { + struct objc_method_list * _Nullable obsolete OBJC2_UNAVAILABLE; + + int method_count OBJC2_UNAVAILABLE; +#ifdef __LP64__ + int space OBJC2_UNAVAILABLE; +#endif + /* variable length structure */ + struct objc_method method_list[1] OBJC2_UNAVAILABLE; +} OBJC2_UNAVAILABLE; + + +typedef struct objc_symtab *Symtab OBJC2_UNAVAILABLE; + +struct objc_symtab { + unsigned long sel_ref_cnt OBJC2_UNAVAILABLE; + SEL _Nonnull * _Nullable refs OBJC2_UNAVAILABLE; + unsigned short cls_def_cnt OBJC2_UNAVAILABLE; + unsigned short cat_def_cnt OBJC2_UNAVAILABLE; + void * _Nullable defs[1] /* variable size */ OBJC2_UNAVAILABLE; +} OBJC2_UNAVAILABLE; + + +typedef struct objc_cache *Cache OBJC2_UNAVAILABLE; + +#define CACHE_BUCKET_NAME(B) ((B)->method_name) +#define CACHE_BUCKET_IMP(B) ((B)->method_imp) +#define CACHE_BUCKET_VALID(B) (B) +#ifndef __LP64__ +#define CACHE_HASH(sel, mask) (((uintptr_t)(sel)>>2) & (mask)) +#else +#define CACHE_HASH(sel, mask) (((unsigned int)((uintptr_t)(sel)>>3)) & (mask)) +#endif +struct objc_cache { + unsigned int mask /* total = mask + 1 */ OBJC2_UNAVAILABLE; + unsigned int occupied OBJC2_UNAVAILABLE; + Method _Nullable buckets[1] OBJC2_UNAVAILABLE; +}; + + +typedef struct objc_module *Module OBJC2_UNAVAILABLE; + +struct objc_module { + unsigned long version OBJC2_UNAVAILABLE; + unsigned long size OBJC2_UNAVAILABLE; + const char * _Nullable name OBJC2_UNAVAILABLE; + Symtab _Nullable symtab OBJC2_UNAVAILABLE; +} OBJC2_UNAVAILABLE; + +#else + struct objc_method_list; +#endif + + /* Obsolete functions */ OBJC_EXPORT IMP _Nullable @@ -1893,9 +2057,108 @@ OBJC_EXPORT id _Nullable object_copyFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z) OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.0, 10.5, "use object_copy instead"); +OBJC_EXPORT id _Nullable +object_realloc(id _Nullable anObject, size_t nBytes) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +object_reallocFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z) + OBJC2_UNAVAILABLE; + +#define OBSOLETE_OBJC_GETCLASSES 1 +OBJC_EXPORT void * _Nonnull +objc_getClasses(void) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_addClass(Class _Nonnull myClass) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_setClassHandler(int (* _Nullable )(const char * _Nonnull)) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_setMultithreaded(BOOL flag) + OBJC2_UNAVAILABLE; + OBJC_EXPORT id _Nullable class_createInstanceFromZone(Class _Nullable, size_t idxIvars, void * _Nullable z) OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.0, 10.5, "use class_createInstance instead"); +OBJC_EXPORT void +class_addMethods(Class _Nullable, struct objc_method_list * _Nonnull) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +class_removeMethods(Class _Nullable, struct objc_method_list * _Nonnull) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +_objc_resolve_categories_for_class(Class _Nonnull cls) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT Class _Nonnull +class_poseAs(Class _Nonnull imposter, Class _Nonnull original) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT unsigned int +method_getSizeOfArguments(Method _Nonnull m) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT unsigned +method_getArgumentInfo(struct objc_method * _Nonnull m, int arg, + const char * _Nullable * _Nonnull type, + int * _Nonnull offset) + UNAVAILABLE_ATTRIBUTE // This function was accidentally deleted in 10.9. + OBJC2_UNAVAILABLE; + +OBJC_EXPORT Class _Nullable +objc_getOrigClass(const char * _Nonnull name) + OBJC2_UNAVAILABLE; + +#define OBJC_NEXT_METHOD_LIST 1 +OBJC_EXPORT struct objc_method_list * _Nullable +class_nextMethodList(Class _Nullable, void * _Nullable * _Nullable) + OBJC2_UNAVAILABLE; +// usage for nextMethodList +// +// void *iterator = 0; +// struct objc_method_list *mlist; +// while ( mlist = class_nextMethodList( cls, &iterator ) ) +// ; + +OBJC_EXPORT id _Nullable +(* _Nonnull _alloc)(Class _Nullable, size_t) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _copy)(id _Nullable, size_t) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _realloc)(id _Nullable, size_t) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _dealloc)(id _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _zoneAlloc)(Class _Nullable, size_t, void * _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _zoneRealloc)(id _Nullable, size_t, void * _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _zoneCopy)(id _Nullable, size_t, void * _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +(* _Nonnull _error)(id _Nullable, const char * _Nonnull, va_list) + OBJC2_UNAVAILABLE; + #endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/os/base.h b/lib/libc/include/any-macos.11-any/os/base.h new file mode 100644 index 0000000000..a630138a10 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/os/base.h @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2008-2020 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_BASE__ +#define __OS_BASE__ + +#include + + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif +#ifndef __has_include +#define __has_include(x) 0 +#endif +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif +#ifndef __has_extension +#define __has_extension(x) 0 +#endif + +#undef OS_INLINE // +#if __GNUC__ +#define OS_NORETURN __attribute__((__noreturn__)) +#define OS_NOTHROW __attribute__((__nothrow__)) +#define OS_NONNULL1 __attribute__((__nonnull__(1))) +#define OS_NONNULL2 __attribute__((__nonnull__(2))) +#define OS_NONNULL3 __attribute__((__nonnull__(3))) +#define OS_NONNULL4 __attribute__((__nonnull__(4))) +#define OS_NONNULL5 __attribute__((__nonnull__(5))) +#define OS_NONNULL6 __attribute__((__nonnull__(6))) +#define OS_NONNULL7 __attribute__((__nonnull__(7))) +#define OS_NONNULL8 __attribute__((__nonnull__(8))) +#define OS_NONNULL9 __attribute__((__nonnull__(9))) +#define OS_NONNULL10 __attribute__((__nonnull__(10))) +#define OS_NONNULL11 __attribute__((__nonnull__(11))) +#define OS_NONNULL12 __attribute__((__nonnull__(12))) +#define OS_NONNULL13 __attribute__((__nonnull__(13))) +#define OS_NONNULL14 __attribute__((__nonnull__(14))) +#define OS_NONNULL15 __attribute__((__nonnull__(15))) +#define OS_NONNULL_ALL __attribute__((__nonnull__)) +#define OS_SENTINEL __attribute__((__sentinel__)) +#define OS_PURE __attribute__((__pure__)) +#define OS_CONST __attribute__((__const__)) +#define OS_WARN_RESULT __attribute__((__warn_unused_result__)) +#define OS_MALLOC __attribute__((__malloc__)) +#define OS_USED __attribute__((__used__)) +#define OS_UNUSED __attribute__((__unused__)) +#define OS_COLD __attribute__((__cold__)) +#define OS_WEAK __attribute__((__weak__)) +#define OS_WEAK_IMPORT __attribute__((__weak_import__)) +#define OS_NOINLINE __attribute__((__noinline__)) +#define OS_ALWAYS_INLINE __attribute__((__always_inline__)) +#define OS_TRANSPARENT_UNION __attribute__((__transparent_union__)) +#define OS_ALIGNED(n) __attribute__((__aligned__((n)))) +#define OS_FORMAT_PRINTF(x, y) __attribute__((__format__(printf,x,y))) +#define OS_EXPORT extern __attribute__((__visibility__("default"))) +#define OS_INLINE static __inline__ +#define OS_EXPECT(x, v) __builtin_expect((x), (v)) +#else +#define OS_NORETURN +#define OS_NOTHROW +#define OS_NONNULL1 +#define OS_NONNULL2 +#define OS_NONNULL3 +#define OS_NONNULL4 +#define OS_NONNULL5 +#define OS_NONNULL6 +#define OS_NONNULL7 +#define OS_NONNULL8 +#define OS_NONNULL9 +#define OS_NONNULL10 +#define OS_NONNULL11 +#define OS_NONNULL12 +#define OS_NONNULL13 +#define OS_NONNULL14 +#define OS_NONNULL15 +#define OS_NONNULL_ALL +#define OS_SENTINEL +#define OS_PURE +#define OS_CONST +#define OS_WARN_RESULT +#define OS_MALLOC +#define OS_USED +#define OS_UNUSED +#define OS_COLD +#define OS_WEAK +#define OS_WEAK_IMPORT +#define OS_NOINLINE +#define OS_ALWAYS_INLINE +#define OS_TRANSPARENT_UNION +#define OS_ALIGNED(n) +#define OS_FORMAT_PRINTF(x, y) +#define OS_EXPORT extern +#define OS_INLINE static inline +#define OS_EXPECT(x, v) (x) +#endif + +#if __has_attribute(noescape) +#define OS_NOESCAPE __attribute__((__noescape__)) +#else +#define OS_NOESCAPE +#endif + +#if defined(__cplusplus) && defined(__clang__) +#define OS_FALLTHROUGH [[clang::fallthrough]] +#elif __has_attribute(fallthrough) +#define OS_FALLTHROUGH __attribute__((__fallthrough__)) +#else +#define OS_FALLTHROUGH +#endif + +#if __has_feature(assume_nonnull) +#define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +#define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +#else +#define OS_ASSUME_NONNULL_BEGIN +#define OS_ASSUME_NONNULL_END +#endif + +#if __has_builtin(__builtin_assume) +#define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr) +#else +#define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr)) +#endif + +#if __has_extension(attribute_overloadable) +#define OS_OVERLOADABLE __attribute__((__overloadable__)) +#else +#define OS_OVERLOADABLE +#endif + +#if __has_attribute(enum_extensibility) +#define __OS_ENUM_ATTR __attribute__((enum_extensibility(open))) +#define __OS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed))) +#else +#define __OS_ENUM_ATTR +#define __OS_ENUM_ATTR_CLOSED +#endif // __has_attribute(enum_extensibility) + +#if __has_attribute(flag_enum) +/*! + * Compile with -Wflag-enum and -Wassign-enum to enforce at definition and + * assignment, respectively, i.e. -Wflag-enum prevents you from creating new + * enumeration values from illegal values within the enum definition, and + * -Wassign-enum prevents you from assigning illegal values to a variable of the + * enum type. + */ +#define __OS_OPTIONS_ATTR __attribute__((flag_enum)) +#else +#define __OS_OPTIONS_ATTR +#endif // __has_attribute(flag_enum) + +#if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || \ + __has_extension(cxx_strong_enums) +#define OS_ENUM(_name, _type, ...) \ + typedef enum : _type { __VA_ARGS__ } _name##_t +#define OS_CLOSED_ENUM(_name, _type, ...) \ + typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED _name##_t +#define OS_OPTIONS(_name, _type, ...) \ + typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR __OS_OPTIONS_ATTR _name##_t +#define OS_CLOSED_OPTIONS(_name, _type, ...) \ + typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR _name##_t +#else +/*! + * There is unfortunately no good way in plain C to have both fixed-type enums + * and enforcement for clang's enum_extensibility extensions. The primary goal + * of these macros is to allow you to define an enum and specify its width in a + * single statement, and for plain C that is accomplished by defining an + * anonymous enum and then separately typedef'ing the requested type name to the + * requested underlying integer type. So the type emitted actually has no + * relationship at all to the enum, and therefore while the compiler could + * enforce enum extensibility if you used the enum type, it cannot do so if you + * use the "_t" type resulting from this expression. + * + * But we still define a named enum type and decorate it appropriately for you, + * so if you really want the enum extensibility enforcement, you can use the + * enum type yourself, i.e. when compiling with a C compiler: + * + * OS_CLOSED_ENUM(my_type, uint64_t, + * FOO, + * BAR, + * BAZ, + * ); + * + * my_type_t mt = 98; // legal + * enum my_type emt = 98; // illegal + * + * But be aware that the underlying enum type's width is subject only to the C + * language's guarantees -- namely that it will be compatible with int, char, + * and unsigned char. It is not safe to rely on the size of this type. + * + * When compiling in ObjC or C++, both of the above assignments are illegal. + */ +#define __OS_ENUM_C_FALLBACK(_name, _type, ...) \ + typedef _type _name##_t; enum _name { __VA_ARGS__ } + +#define OS_ENUM(_name, _type, ...) \ + typedef _type _name##_t; enum { __VA_ARGS__ } +#define OS_CLOSED_ENUM(_name, _type, ...) \ + __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ + __OS_ENUM_ATTR_CLOSED +#define OS_OPTIONS(_name, _type, ...) \ + __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ + __OS_ENUM_ATTR __OS_OPTIONS_ATTR +#define OS_CLOSED_OPTIONS(_name, _type, ...) \ + __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ + __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR +#endif // __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) + +#if __has_feature(attribute_availability_swift) +// equivalent to __SWIFT_UNAVAILABLE from Availability.h +#define OS_SWIFT_UNAVAILABLE(_msg) \ + __attribute__((__availability__(swift, unavailable, message=_msg))) +#else +#define OS_SWIFT_UNAVAILABLE(_msg) +#endif + +#if __has_attribute(swift_private) +# define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__)) +#else +# define OS_REFINED_FOR_SWIFT +#endif + +#if __has_attribute(swift_name) +# define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) +#else +# define OS_SWIFT_NAME(_name) +#endif + +#define __OS_STRINGIFY(s) #s +#define OS_STRINGIFY(s) __OS_STRINGIFY(s) +#define __OS_CONCAT(x, y) x ## y +#define OS_CONCAT(x, y) __OS_CONCAT(x, y) + +#ifdef __GNUC__ +#define os_prevent_tail_call_optimization() __asm__("") +#define os_is_compile_time_constant(expr) __builtin_constant_p(expr) +#define os_compiler_barrier() __asm__ __volatile__("" ::: "memory") +#else +#define os_prevent_tail_call_optimization() do { } while (0) +#define os_is_compile_time_constant(expr) 0 +#define os_compiler_barrier() do { } while (0) +#endif + +#if __has_attribute(not_tail_called) +#define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) +#else +#define OS_NOT_TAIL_CALLED +#endif + + +typedef void (*os_function_t)(void *_Nullable); + +#ifdef __BLOCKS__ +/*! + * @typedef os_block_t + * + * @abstract + * Generic type for a block taking no arguments and returning no value. + * + * @discussion + * When not building with Objective-C ARC, a block object allocated on or + * copied to the heap must be released with a -[release] message or the + * Block_release() function. + * + * The declaration of a block literal allocates storage on the stack. + * Therefore, this is an invalid construct: + * + * os_block_t block; + * if (x) { + * block = ^{ printf("true\n"); }; + * } else { + * block = ^{ printf("false\n"); }; + * } + * block(); // unsafe!!! + * + * + * What is happening behind the scenes: + * + * if (x) { + * struct Block __tmp_1 = ...; // setup details + * block = &__tmp_1; + * } else { + * struct Block __tmp_2 = ...; // setup details + * block = &__tmp_2; + * } + * + * + * As the example demonstrates, the address of a stack variable is escaping the + * scope in which it is allocated. That is a classic C bug. + * + * Instead, the block literal must be copied to the heap with the Block_copy() + * function or by sending it a -[copy] message. + */ +typedef void (^os_block_t)(void); +#endif + + + +#endif // __OS_BASE__ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/pthread.h b/lib/libc/include/any-macos.11-any/pthread.h new file mode 100644 index 0000000000..b9ffcbc983 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/pthread.h @@ -0,0 +1,592 @@ +/* + * Copyright (c) 2000-2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * MkLinux + */ + +/* + * POSIX Threads - IEEE 1003.1c + */ + +#ifndef _PTHREAD_H +#define _PTHREAD_H + +#include <_types.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(__cplusplus) + +#include +#include + +#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE || __cplusplus */ + +/* + * These symbols indicate which [optional] features are available + * They can be tested at compile time via '#ifdef XXX' + * The way to check for pthreads is like so: + + * #include + * #ifdef _POSIX_THREADS + * #include + * #endif + + */ + +/* These will be moved to unistd.h */ + +/* + * Note: These data structures are meant to be opaque. Only enough + * structure is exposed to support initializers. + * All of the typedefs will be moved to + */ + +#include +#include + +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull begin") +#endif +__BEGIN_DECLS +/* + * Threads + */ + + +/* + * Cancel cleanup handler management. Note, since these are implemented as macros, + * they *MUST* occur in matched pairs! + */ + +#define pthread_cleanup_push(func, val) \ + { \ + struct __darwin_pthread_handler_rec __handler; \ + pthread_t __self = pthread_self(); \ + __handler.__routine = func; \ + __handler.__arg = val; \ + __handler.__next = __self->__cleanup_stack; \ + __self->__cleanup_stack = &__handler; + +#define pthread_cleanup_pop(execute) \ + /* Note: 'handler' must be in this same lexical context! */ \ + __self->__cleanup_stack = __handler.__next; \ + if (execute) (__handler.__routine)(__handler.__arg); \ + } + +/* + * Thread attributes + */ + +#define PTHREAD_CREATE_JOINABLE 1 +#define PTHREAD_CREATE_DETACHED 2 + +#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 2 + +#define PTHREAD_CANCEL_ENABLE 0x01 /* Cancel takes place at next cancellation point */ +#define PTHREAD_CANCEL_DISABLE 0x00 /* Cancel postponed */ +#define PTHREAD_CANCEL_DEFERRED 0x02 /* Cancel waits until cancellation point */ +#define PTHREAD_CANCEL_ASYNCHRONOUS 0x00 /* Cancel occurs immediately */ + +/* Value returned from pthread_join() when a thread is canceled */ +#define PTHREAD_CANCELED ((void *) 1) + +/* We only support PTHREAD_SCOPE_SYSTEM */ +#define PTHREAD_SCOPE_SYSTEM 1 +#define PTHREAD_SCOPE_PROCESS 2 + +#define PTHREAD_PROCESS_SHARED 1 +#define PTHREAD_PROCESS_PRIVATE 2 + +/* + * Mutex protocol attributes + */ +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +/* + * Mutex type attributes + */ +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL + +/* + * Mutex policy attributes + */ +#define PTHREAD_MUTEX_POLICY_FAIRSHARE_NP 1 +#define PTHREAD_MUTEX_POLICY_FIRSTFIT_NP 3 + +/* + * RWLock variables + */ +#define PTHREAD_RWLOCK_INITIALIZER {_PTHREAD_RWLOCK_SIG_init, {0}} + +/* + * Mutex variables + */ +#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}} + +/* */ +#if ((__MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) || defined(__DRIVERKIT_VERSION_MIN_REQUIRED) +# if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) +# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}} +# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}} +# endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ +#endif + +/* */ +#define _PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT \ + defined(SWIFT_CLASS_EXTRA) && (!defined(SWIFT_SDK_OVERLAY_PTHREAD_EPOCH) || (SWIFT_SDK_OVERLAY_PTHREAD_EPOCH < 1)) + +/* + * Condition variable attributes + */ + +/* + * Condition variables + */ + +#define PTHREAD_COND_INITIALIZER {_PTHREAD_COND_SIG_init, {0}} + +/* + * Initialization control (once) variables + */ + +#define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}} + +/* + * Prototypes for all PTHREAD interfaces + */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_atfork(void (* _Nullable)(void), void (* _Nullable)(void), + void (* _Nullable)(void)); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_destroy(pthread_attr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getdetachstate(const pthread_attr_t *, int *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getguardsize(const pthread_attr_t * __restrict, size_t * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getinheritsched(const pthread_attr_t * __restrict, int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getschedparam(const pthread_attr_t * __restrict, + struct sched_param * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getschedpolicy(const pthread_attr_t * __restrict, int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getscope(const pthread_attr_t * __restrict, int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getstack(const pthread_attr_t * __restrict, + void * _Nullable * _Nonnull __restrict, size_t * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getstackaddr(const pthread_attr_t * __restrict, + void * _Nullable * _Nonnull __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_getstacksize(const pthread_attr_t * __restrict, size_t * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_init(pthread_attr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setdetachstate(pthread_attr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setguardsize(pthread_attr_t *, size_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setinheritsched(pthread_attr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setschedparam(pthread_attr_t * __restrict, + const struct sched_param * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setschedpolicy(pthread_attr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setscope(pthread_attr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setstack(pthread_attr_t *, void *, size_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setstackaddr(pthread_attr_t *, void *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_attr_setstacksize(pthread_attr_t *, size_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cancel(pthread_t) __DARWIN_ALIAS(pthread_cancel); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_broadcast(pthread_cond_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_destroy(pthread_cond_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_init( + pthread_cond_t * __restrict, + const pthread_condattr_t * _Nullable __restrict) + __DARWIN_ALIAS(pthread_cond_init); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_signal(pthread_cond_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_timedwait( + pthread_cond_t * __restrict, pthread_mutex_t * __restrict, + const struct timespec * _Nullable __restrict) + __DARWIN_ALIAS_C(pthread_cond_timedwait); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_wait(pthread_cond_t * __restrict, + pthread_mutex_t * __restrict) __DARWIN_ALIAS_C(pthread_cond_wait); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_condattr_destroy(pthread_condattr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_condattr_init(pthread_condattr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_condattr_getpshared(const pthread_condattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_condattr_setpshared(pthread_condattr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT +int pthread_create(pthread_t _Nullable * _Nonnull __restrict, + const pthread_attr_t * _Nullable __restrict, + void * _Nullable (* _Nonnull)(void * _Nullable), + void * _Nullable __restrict); +#else +int pthread_create(pthread_t * __restrict, + const pthread_attr_t * _Nullable __restrict, + void *(* _Nonnull)(void *), void * _Nullable __restrict); +#endif // _PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_detach(pthread_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_equal(pthread_t _Nullable, pthread_t _Nullable); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +void pthread_exit(void * _Nullable) __dead2; + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_getconcurrency(void); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_getschedparam(pthread_t , int * _Nullable __restrict, + struct sched_param * _Nullable __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +void* _Nullable pthread_getspecific(pthread_key_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_join(pthread_t , void * _Nullable * _Nullable) + __DARWIN_ALIAS_C(pthread_join); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_key_create(pthread_key_t *, void (* _Nullable)(void *)); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_key_delete(pthread_key_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_destroy(pthread_mutex_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_init(pthread_mutex_t * __restrict, + const pthread_mutexattr_t * _Nullable __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_lock(pthread_mutex_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_trylock(pthread_mutex_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutex_unlock(pthread_mutex_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_destroy(pthread_mutexattr_t *) __DARWIN_ALIAS(pthread_mutexattr_destroy); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.13.4), ios(11.3), watchos(4.3), tvos(11.3)) +int pthread_mutexattr_getpolicy_np(const pthread_mutexattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_init(pthread_mutexattr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_mutexattr_settype(pthread_mutexattr_t *, int); + +__API_AVAILABLE(macos(10.7), ios(5.0)) +int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *, int); + +__SWIFT_UNAVAILABLE_MSG("Use lazily initialized globals instead") +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_once(pthread_once_t *, void (* _Nonnull)(void)); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_destroy(pthread_rwlock_t * ) __DARWIN_ALIAS(pthread_rwlock_destroy); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_init(pthread_rwlock_t * __restrict, + const pthread_rwlockattr_t * _Nullable __restrict) + __DARWIN_ALIAS(pthread_rwlock_init); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_rdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_rdlock); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_tryrdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_tryrdlock); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_trywrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_trywrlock); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_wrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_wrlock); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlock_unlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_unlock); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict, + int * __restrict); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlockattr_init(pthread_rwlockattr_t *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +pthread_t pthread_self(void); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_setcancelstate(int , int * _Nullable) + __DARWIN_ALIAS(pthread_setcancelstate); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_setcanceltype(int , int * _Nullable) + __DARWIN_ALIAS(pthread_setcanceltype); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_setconcurrency(int); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_setschedparam(pthread_t, int, const struct sched_param *); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_setspecific(pthread_key_t , const void * _Nullable); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +void pthread_testcancel(void) __DARWIN_ALIAS(pthread_testcancel); + +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(__cplusplus) + +/* returns non-zero if pthread_create or cthread_fork have been called */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_is_threaded_np(void); + +__API_AVAILABLE(macos(10.6), ios(3.2)) +int pthread_threadid_np(pthread_t _Nullable,__uint64_t* _Nullable); + +/*SPI to set and get pthread name*/ +__API_AVAILABLE(macos(10.6), ios(3.2)) +int pthread_getname_np(pthread_t,char*,size_t); + +__API_AVAILABLE(macos(10.6), ios(3.2)) +int pthread_setname_np(const char*); + +/* returns non-zero if the current thread is the main thread */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_main_np(void); + +/* return the mach thread bound to the pthread */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +mach_port_t pthread_mach_thread_np(pthread_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +size_t pthread_get_stacksize_np(pthread_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +void* pthread_get_stackaddr_np(pthread_t); + +/* Like pthread_cond_signal(), but only wake up the specified pthread */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_signal_thread_np(pthread_cond_t *, pthread_t _Nullable); + +/* Like pthread_cond_timedwait, but use a relative timeout */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_cond_timedwait_relative_np(pthread_cond_t *, pthread_mutex_t *, + const struct timespec * _Nullable); + +/* Like pthread_create(), but leaves the thread suspended */ +__API_AVAILABLE(macos(10.4), ios(2.0)) +#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT +int pthread_create_suspended_np( + pthread_t _Nullable * _Nonnull, const pthread_attr_t * _Nullable, + void * _Nullable (* _Nonnull)(void * _Nullable), void * _Nullable); +#else +int pthread_create_suspended_np(pthread_t *, const pthread_attr_t * _Nullable, + void *(* _Nonnull)(void *), void * _Nullable); +#endif + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_kill(pthread_t, int); + +__API_AVAILABLE(macos(10.5), ios(2.0)) +_Nullable pthread_t pthread_from_mach_thread_np(mach_port_t); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +int pthread_sigmask(int, const sigset_t * _Nullable, sigset_t * _Nullable) + __DARWIN_ALIAS(pthread_sigmask); + +__API_AVAILABLE(macos(10.4), ios(2.0)) +void pthread_yield_np(void); + +__API_AVAILABLE(macos(11.0)) +__API_UNAVAILABLE(ios, tvos, watchos, driverkit) +void pthread_jit_write_protect_np(int enabled); + +__API_AVAILABLE(macos(11.0)) +__API_UNAVAILABLE(ios, tvos, watchos, driverkit) +int pthread_jit_write_protect_supported_np(void); + +/*! + * @function pthread_cpu_number_np + * + * @param cpu_number_out + * The CPU number that the thread was running on at the time of query. + * This cpu number is in the interval [0, ncpus) (from sysctlbyname("hw.ncpu")) + * + * @result + * This function returns 0 or the value of errno if an error occurred. + * + * @note + * Optimizations of per-CPU datastructures based on the result of this function + * still require synchronization since it is not guaranteed that the thread will + * still be on the same CPU by the time the function returns. + */ +__API_AVAILABLE(macos(11.0), ios(14.2), tvos(14.2), watchos(7.1)) +int +pthread_cpu_number_np(size_t *cpu_number_out); + +#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE || __cplusplus */ +__END_DECLS +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull end") +#endif + +#endif /* _PTHREAD_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/base.h b/lib/libc/include/any-macos.11-any/simd/base.h new file mode 100644 index 0000000000..fdc2e3c879 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/base.h @@ -0,0 +1,122 @@ +/*! @header + * This header defines macros used in the implementation of + * types and functions. Even though they are exposed in a public header, + * the macros defined in this header are implementation details, and you + * should not use or rely on them. They may be changed or removed entirely + * in a future release. + * + * @copyright 2016-2017 Apple, Inc. All rights reserved. + * @unsorted */ + +#ifndef SIMD_BASE +#define SIMD_BASE + +/* Define __has_attribute and __has_include if they aren't available */ +# ifndef __has_attribute +# define __has_attribute(__x) 0 +# endif +# ifndef __has_include +# define __has_include(__x) 0 +# endif +# ifndef __has_feature +# define __has_feature(__x) 0 +# endif + +# if __has_attribute(__ext_vector_type__) && __has_attribute(__overloadable__) +# define SIMD_COMPILER_HAS_REQUIRED_FEATURES 1 +# else +/* Your compiler is missing one or more features that are hard requirements + * for any support. None of the types or functions defined by + * the simd headers will be available. */ +# define SIMD_COMPILER_HAS_REQUIRED_FEATURES 0 +# endif + +# if SIMD_COMPILER_HAS_REQUIRED_FEATURES +# if __has_include() +# include +/* A number of new features are added in newer releases; most of these are + * inline in the header, which makes them available even when targeting older + * OS versions. Those that make external calls, however, are only available + * when targeting the release in which they became available. Because of the + * way in which simd functions are overloaded, the usual weak-linking tricks + * do not work; these functions are simply unavailable when targeting older + * versions of the library. */ +# if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13 || \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0 || \ + __WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_4_0 || \ + __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_11_0 || \ + __DRIVERKIT_VERSION_MIN_REQUIRED >= __DRIVERKIT_19_0 +# define SIMD_LIBRARY_VERSION 3 +# elif __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12 || \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0 || \ + __WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0 || \ + __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0 +# define SIMD_LIBRARY_VERSION 2 +# elif __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 +# define SIMD_LIBRARY_VERSION 1 +# else +# define SIMD_LIBRARY_VERSION 0 +# endif +# else /* !__has_include() */ +# define SIMD_LIBRARY_VERSION 3 +# define __API_AVAILABLE(...) /* Nothing */ +# endif + +/* The simd types interoperate with the native simd intrinsic types for each + * architecture; the headers that define those types and operations are + * automatically included with simd.h */ +# if defined __ARM_NEON__ +# include +# elif defined __i386__ || defined __x86_64__ +# include +# endif + +/* Define a number of function attributes used by the simd functions. */ +# if __has_attribute(__always_inline__) +# define SIMD_INLINE __attribute__((__always_inline__)) +# else +# define SIMD_INLINE inline +# endif + +# if __has_attribute(__const__) +# define SIMD_CONST __attribute__((__const__)) +# else +# define SIMD_CONST /* nothing */ +# endif + +# if __has_attribute(__nodebug__) +# define SIMD_NODEBUG __attribute__((__nodebug__)) +# else +# define SIMD_NODEBUG /* nothing */ +# endif + +# if __has_attribute(__deprecated__) +# define SIMD_DEPRECATED(message) __attribute__((__deprecated__(message))) +# else +# define SIMD_DEPRECATED(message) /* nothing */ +# endif + +#define SIMD_OVERLOAD __attribute__((__overloadable__)) +#define SIMD_CPPFUNC SIMD_INLINE SIMD_CONST SIMD_NODEBUG +#define SIMD_CFUNC SIMD_CPPFUNC SIMD_OVERLOAD +#define SIMD_NOINLINE SIMD_CONST SIMD_NODEBUG SIMD_OVERLOAD +#define SIMD_NONCONST SIMD_INLINE SIMD_NODEBUG SIMD_OVERLOAD +#define __SIMD_INLINE__ SIMD_CPPFUNC +#define __SIMD_ATTRIBUTES__ SIMD_CFUNC +#define __SIMD_OVERLOAD__ SIMD_OVERLOAD + +#if defined __cplusplus +/*! @abstract A boolean scalar. */ +typedef bool simd_bool; +#else +/*! @abstract A boolean scalar. */ +typedef _Bool simd_bool; +#endif +/*! @abstract A boolean scalar. + * @discussion This type is deprecated; In C or Objective-C sources, use + * `_Bool` instead. In C++ sources, use `bool`. */ +typedef simd_bool __SIMD_BOOLEAN_TYPE__; + +# endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* defined SIMD_BASE */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/common.h b/lib/libc/include/any-macos.11-any/simd/common.h new file mode 100644 index 0000000000..5408c535fd --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/common.h @@ -0,0 +1,4458 @@ +/*! @header + * The interfaces declared in this header provide "common" elementwise + * operations that are neither math nor logic functions. These are available + * only for floating-point vectors and scalars, except for min, max, abs, + * clamp, and the reduce operations, which also support integer vectors. + * + * simd_abs(x) Absolute value of x. Also available as fabs + * for floating-point vectors. If x is the + * smallest signed integer, x is returned. + * + * simd_max(x,y) Returns the maximum of x and y. Also available + * as fmax for floating-point vectors. + * + * simd_min(x,y) Returns the minimum of x and y. Also available + * as fmin for floating-point vectors. + * + * simd_clamp(x,min,max) x clamped to the range [min, max]. + * + * simd_sign(x) -1 if x is less than zero, 0 if x is zero or + * NaN, and +1 if x is greater than zero. + * + * simd_mix(x,y,t) If t is not in the range [0,1], the result is + * undefined. Otherwise the result is x+(y-x)*t, + * which linearly interpolates between x and y. + * + * simd_recip(x) An approximation to 1/x. If x is very near the + * limits of representable values, or is infinity + * or NaN, the result is undefined. There are + * two variants of this function: + * + * simd_precise_recip(x) + * + * and + * + * simd_fast_recip(x). + * + * The "precise" variant is accurate to a few ULPs, + * whereas the "fast" variant may have as little + * as 11 bits of accuracy in float and about 22 + * bits in double. + * + * The function simd_recip(x) resolves to + * simd_precise_recip(x) ordinarily, but to + * simd_fast_recip(x) when used in a translation + * unit compiled with -ffast-math (when + * -ffast-math is in effect, you may still use the + * precise version of this function by calling it + * explicitly by name). + * + * simd_rsqrt(x) An approximation to 1/sqrt(x). If x is + * infinity or NaN, the result is undefined. + * There are two variants of this function: + * + * simd_precise_rsqrt(x) + * + * and + * + * simd_fast_rsqrt(x). + * + * The "precise" variant is accurate to a few ULPs, + * whereas the "fast" variant may have as little + * as 11 bits of accuracy in float and about 22 + * bits in double. + * + * The function simd_rsqrt(x) resolves to + * simd_precise_rsqrt(x) ordinarily, but to + * simd_fast_rsqrt(x) when used in a translation + * unit compiled with -ffast-math (when + * -ffast-math is in effect, you may still use the + * precise version of this function by calling it + * explicitly by name). + * + * simd_fract(x) The "fractional part" of x, which lies strictly + * in the range [0, 0x1.fffffep-1]. + * + * simd_step(edge,x) 0 if x < edge, and 1 otherwise. + * + * simd_smoothstep(edge0,edge1,x) 0 if x <= edge0, 1 if x >= edge1, and + * a Hermite interpolation between 0 and 1 if + * edge0 < x < edge1. + * + * simd_reduce_add(x) Sum of the elements of x. + * + * simd_reduce_min(x) Minimum of the elements of x. + * + * simd_reduce_max(x) Maximum of the elements of x. + * + * simd_equal(x,y) True if and only if every lane of x is equal + * to the corresponding lane of y. + * + * The following common functions are available in the simd:: namespace: + * + * C++ Function Equivalent C Function + * -------------------------------------------------------------------- + * simd::abs(x) simd_abs(x) + * simd::max(x,y) simd_max(x,y) + * simd::min(x,y) simd_min(x,y) + * simd::clamp(x,min,max) simd_clamp(x,min,max) + * simd::sign(x) simd_sign(x) + * simd::mix(x,y,t) simd_mix(x,y,t) + * simd::recip(x) simd_recip(x) + * simd::rsqrt(x) simd_rsqrt(x) + * simd::fract(x) simd_fract(x) + * simd::step(edge,x) simd_step(edge,x) + * simd::smoothstep(e0,e1,x) simd_smoothstep(e0,e1,x) + * simd::reduce_add(x) simd_reduce_add(x) + * simd::reduce_max(x) simd_reduce_max(x) + * simd::reduce_min(x) simd_reduce_min(x) + * simd::equal(x,y) simd_equal(x,y) + * + * simd::precise::recip(x) simd_precise_recip(x) + * simd::precise::rsqrt(x) simd_precise_rsqrt(x) + * + * simd::fast::recip(x) simd_fast_recip(x) + * simd::fast::rsqrt(x) simd_fast_rsqrt(x) + * + * @copyright 2014-2017 Apple, Inc. All rights reserved. + * @unsorted */ + +#ifndef SIMD_COMMON_HEADER +#define SIMD_COMMON_HEADER + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char2 simd_abs(simd_char2 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char3 simd_abs(simd_char3 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char4 simd_abs(simd_char4 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char8 simd_abs(simd_char8 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char16 simd_abs(simd_char16 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char32 simd_abs(simd_char32 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_char64 simd_abs(simd_char64 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_short2 simd_abs(simd_short2 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_short3 simd_abs(simd_short3 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_short4 simd_abs(simd_short4 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_short8 simd_abs(simd_short8 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_short16 simd_abs(simd_short16 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_short32 simd_abs(simd_short32 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_int2 simd_abs(simd_int2 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_int3 simd_abs(simd_int3 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_int4 simd_abs(simd_int4 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_int8 simd_abs(simd_int8 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_int16 simd_abs(simd_int16 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_float2 simd_abs(simd_float2 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_float3 simd_abs(simd_float3 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_float4 simd_abs(simd_float4 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_float8 simd_abs(simd_float8 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_float16 simd_abs(simd_float16 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_long2 simd_abs(simd_long2 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_long3 simd_abs(simd_long3 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_long4 simd_abs(simd_long4 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_long8 simd_abs(simd_long8 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_double2 simd_abs(simd_double2 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_double3 simd_abs(simd_double3 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_double4 simd_abs(simd_double4 x); +/*! @abstract The elementwise absolute value of x. */ +static inline SIMD_CFUNC simd_double8 simd_abs(simd_double8 x); +/*! @abstract The elementwise absolute value of x. + * @discussion Deprecated. Use simd_abs(x) instead. */ +#define vector_abs simd_abs + +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char2 simd_max(simd_char2 x, simd_char2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char3 simd_max(simd_char3 x, simd_char3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char4 simd_max(simd_char4 x, simd_char4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char8 simd_max(simd_char8 x, simd_char8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char16 simd_max(simd_char16 x, simd_char16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char32 simd_max(simd_char32 x, simd_char32 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_char64 simd_max(simd_char64 x, simd_char64 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar2 simd_max(simd_uchar2 x, simd_uchar2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar3 simd_max(simd_uchar3 x, simd_uchar3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar4 simd_max(simd_uchar4 x, simd_uchar4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar8 simd_max(simd_uchar8 x, simd_uchar8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar16 simd_max(simd_uchar16 x, simd_uchar16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar32 simd_max(simd_uchar32 x, simd_uchar32 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uchar64 simd_max(simd_uchar64 x, simd_uchar64 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_short2 simd_max(simd_short2 x, simd_short2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_short3 simd_max(simd_short3 x, simd_short3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_short4 simd_max(simd_short4 x, simd_short4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_short8 simd_max(simd_short8 x, simd_short8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_short16 simd_max(simd_short16 x, simd_short16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_short32 simd_max(simd_short32 x, simd_short32 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ushort2 simd_max(simd_ushort2 x, simd_ushort2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ushort3 simd_max(simd_ushort3 x, simd_ushort3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ushort4 simd_max(simd_ushort4 x, simd_ushort4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ushort8 simd_max(simd_ushort8 x, simd_ushort8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ushort16 simd_max(simd_ushort16 x, simd_ushort16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ushort32 simd_max(simd_ushort32 x, simd_ushort32 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_int2 simd_max(simd_int2 x, simd_int2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_int3 simd_max(simd_int3 x, simd_int3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_int4 simd_max(simd_int4 x, simd_int4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_int8 simd_max(simd_int8 x, simd_int8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_int16 simd_max(simd_int16 x, simd_int16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uint2 simd_max(simd_uint2 x, simd_uint2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uint3 simd_max(simd_uint3 x, simd_uint3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uint4 simd_max(simd_uint4 x, simd_uint4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uint8 simd_max(simd_uint8 x, simd_uint8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_uint16 simd_max(simd_uint16 x, simd_uint16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC float simd_max(float x, float y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_float2 simd_max(simd_float2 x, simd_float2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_float3 simd_max(simd_float3 x, simd_float3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_float4 simd_max(simd_float4 x, simd_float4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_float8 simd_max(simd_float8 x, simd_float8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_float16 simd_max(simd_float16 x, simd_float16 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_long2 simd_max(simd_long2 x, simd_long2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_long3 simd_max(simd_long3 x, simd_long3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_long4 simd_max(simd_long4 x, simd_long4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_long8 simd_max(simd_long8 x, simd_long8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ulong2 simd_max(simd_ulong2 x, simd_ulong2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ulong3 simd_max(simd_ulong3 x, simd_ulong3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ulong4 simd_max(simd_ulong4 x, simd_ulong4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_ulong8 simd_max(simd_ulong8 x, simd_ulong8 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC double simd_max(double x, double y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_double2 simd_max(simd_double2 x, simd_double2 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_double3 simd_max(simd_double3 x, simd_double3 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_double4 simd_max(simd_double4 x, simd_double4 y); +/*! @abstract The elementwise maximum of x and y. */ +static inline SIMD_CFUNC simd_double8 simd_max(simd_double8 x, simd_double8 y); +/*! @abstract The elementwise maximum of x and y. + * @discussion Deprecated. Use simd_max(x,y) instead. */ +#define vector_max simd_max + +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char2 simd_min(simd_char2 x, simd_char2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char3 simd_min(simd_char3 x, simd_char3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char4 simd_min(simd_char4 x, simd_char4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char8 simd_min(simd_char8 x, simd_char8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char16 simd_min(simd_char16 x, simd_char16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char32 simd_min(simd_char32 x, simd_char32 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_char64 simd_min(simd_char64 x, simd_char64 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar2 simd_min(simd_uchar2 x, simd_uchar2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar3 simd_min(simd_uchar3 x, simd_uchar3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar4 simd_min(simd_uchar4 x, simd_uchar4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar8 simd_min(simd_uchar8 x, simd_uchar8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar16 simd_min(simd_uchar16 x, simd_uchar16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar32 simd_min(simd_uchar32 x, simd_uchar32 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uchar64 simd_min(simd_uchar64 x, simd_uchar64 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_short2 simd_min(simd_short2 x, simd_short2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_short3 simd_min(simd_short3 x, simd_short3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_short4 simd_min(simd_short4 x, simd_short4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_short8 simd_min(simd_short8 x, simd_short8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_short16 simd_min(simd_short16 x, simd_short16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_short32 simd_min(simd_short32 x, simd_short32 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ushort2 simd_min(simd_ushort2 x, simd_ushort2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ushort3 simd_min(simd_ushort3 x, simd_ushort3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ushort4 simd_min(simd_ushort4 x, simd_ushort4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ushort8 simd_min(simd_ushort8 x, simd_ushort8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ushort16 simd_min(simd_ushort16 x, simd_ushort16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ushort32 simd_min(simd_ushort32 x, simd_ushort32 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_int2 simd_min(simd_int2 x, simd_int2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_int3 simd_min(simd_int3 x, simd_int3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_int4 simd_min(simd_int4 x, simd_int4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_int8 simd_min(simd_int8 x, simd_int8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_int16 simd_min(simd_int16 x, simd_int16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uint2 simd_min(simd_uint2 x, simd_uint2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uint3 simd_min(simd_uint3 x, simd_uint3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uint4 simd_min(simd_uint4 x, simd_uint4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uint8 simd_min(simd_uint8 x, simd_uint8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_uint16 simd_min(simd_uint16 x, simd_uint16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC float simd_min(float x, float y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_float2 simd_min(simd_float2 x, simd_float2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_float3 simd_min(simd_float3 x, simd_float3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_float4 simd_min(simd_float4 x, simd_float4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_float8 simd_min(simd_float8 x, simd_float8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_float16 simd_min(simd_float16 x, simd_float16 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_long2 simd_min(simd_long2 x, simd_long2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_long3 simd_min(simd_long3 x, simd_long3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_long4 simd_min(simd_long4 x, simd_long4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_long8 simd_min(simd_long8 x, simd_long8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ulong2 simd_min(simd_ulong2 x, simd_ulong2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ulong3 simd_min(simd_ulong3 x, simd_ulong3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ulong4 simd_min(simd_ulong4 x, simd_ulong4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_ulong8 simd_min(simd_ulong8 x, simd_ulong8 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC double simd_min(double x, double y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_double2 simd_min(simd_double2 x, simd_double2 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_double3 simd_min(simd_double3 x, simd_double3 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_double4 simd_min(simd_double4 x, simd_double4 y); +/*! @abstract The elementwise minimum of x and y. */ +static inline SIMD_CFUNC simd_double8 simd_min(simd_double8 x, simd_double8 y); +/*! @abstract The elementwise minimum of x and y. + * @discussion Deprecated. Use simd_min(x,y) instead. */ +#define vector_min simd_min + + +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char2 simd_clamp(simd_char2 x, simd_char2 min, simd_char2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char3 simd_clamp(simd_char3 x, simd_char3 min, simd_char3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char4 simd_clamp(simd_char4 x, simd_char4 min, simd_char4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char8 simd_clamp(simd_char8 x, simd_char8 min, simd_char8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char16 simd_clamp(simd_char16 x, simd_char16 min, simd_char16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char32 simd_clamp(simd_char32 x, simd_char32 min, simd_char32 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_char64 simd_clamp(simd_char64 x, simd_char64 min, simd_char64 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar2 simd_clamp(simd_uchar2 x, simd_uchar2 min, simd_uchar2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar3 simd_clamp(simd_uchar3 x, simd_uchar3 min, simd_uchar3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar4 simd_clamp(simd_uchar4 x, simd_uchar4 min, simd_uchar4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar8 simd_clamp(simd_uchar8 x, simd_uchar8 min, simd_uchar8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar16 simd_clamp(simd_uchar16 x, simd_uchar16 min, simd_uchar16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar32 simd_clamp(simd_uchar32 x, simd_uchar32 min, simd_uchar32 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uchar64 simd_clamp(simd_uchar64 x, simd_uchar64 min, simd_uchar64 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_short2 simd_clamp(simd_short2 x, simd_short2 min, simd_short2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_short3 simd_clamp(simd_short3 x, simd_short3 min, simd_short3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_short4 simd_clamp(simd_short4 x, simd_short4 min, simd_short4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_short8 simd_clamp(simd_short8 x, simd_short8 min, simd_short8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_short16 simd_clamp(simd_short16 x, simd_short16 min, simd_short16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_short32 simd_clamp(simd_short32 x, simd_short32 min, simd_short32 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ushort2 simd_clamp(simd_ushort2 x, simd_ushort2 min, simd_ushort2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ushort3 simd_clamp(simd_ushort3 x, simd_ushort3 min, simd_ushort3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ushort4 simd_clamp(simd_ushort4 x, simd_ushort4 min, simd_ushort4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ushort8 simd_clamp(simd_ushort8 x, simd_ushort8 min, simd_ushort8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ushort16 simd_clamp(simd_ushort16 x, simd_ushort16 min, simd_ushort16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ushort32 simd_clamp(simd_ushort32 x, simd_ushort32 min, simd_ushort32 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_int2 simd_clamp(simd_int2 x, simd_int2 min, simd_int2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_int3 simd_clamp(simd_int3 x, simd_int3 min, simd_int3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_int4 simd_clamp(simd_int4 x, simd_int4 min, simd_int4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_int8 simd_clamp(simd_int8 x, simd_int8 min, simd_int8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_int16 simd_clamp(simd_int16 x, simd_int16 min, simd_int16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uint2 simd_clamp(simd_uint2 x, simd_uint2 min, simd_uint2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uint3 simd_clamp(simd_uint3 x, simd_uint3 min, simd_uint3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uint4 simd_clamp(simd_uint4 x, simd_uint4 min, simd_uint4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uint8 simd_clamp(simd_uint8 x, simd_uint8 min, simd_uint8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_uint16 simd_clamp(simd_uint16 x, simd_uint16 min, simd_uint16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC float simd_clamp(float x, float min, float max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_float2 simd_clamp(simd_float2 x, simd_float2 min, simd_float2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_float3 simd_clamp(simd_float3 x, simd_float3 min, simd_float3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_float4 simd_clamp(simd_float4 x, simd_float4 min, simd_float4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_float8 simd_clamp(simd_float8 x, simd_float8 min, simd_float8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_float16 simd_clamp(simd_float16 x, simd_float16 min, simd_float16 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_long2 simd_clamp(simd_long2 x, simd_long2 min, simd_long2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_long3 simd_clamp(simd_long3 x, simd_long3 min, simd_long3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_long4 simd_clamp(simd_long4 x, simd_long4 min, simd_long4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_long8 simd_clamp(simd_long8 x, simd_long8 min, simd_long8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ulong2 simd_clamp(simd_ulong2 x, simd_ulong2 min, simd_ulong2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ulong3 simd_clamp(simd_ulong3 x, simd_ulong3 min, simd_ulong3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ulong4 simd_clamp(simd_ulong4 x, simd_ulong4 min, simd_ulong4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_ulong8 simd_clamp(simd_ulong8 x, simd_ulong8 min, simd_ulong8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC double simd_clamp(double x, double min, double max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_double2 simd_clamp(simd_double2 x, simd_double2 min, simd_double2 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_double3 simd_clamp(simd_double3 x, simd_double3 min, simd_double3 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_double4 simd_clamp(simd_double4 x, simd_double4 min, simd_double4 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Note that if you want to clamp all lanes to the same range, + * you can use a scalar value for min and max. */ +static inline SIMD_CFUNC simd_double8 simd_clamp(simd_double8 x, simd_double8 min, simd_double8 max); +/*! @abstract x clamped to the range [min, max]. + * @discussion Deprecated. Use simd_clamp(x,min,max) instead. */ +#define vector_clamp simd_clamp + +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC float simd_sign(float x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_float2 simd_sign(simd_float2 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_float3 simd_sign(simd_float3 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_float4 simd_sign(simd_float4 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_float8 simd_sign(simd_float8 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_float16 simd_sign(simd_float16 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC double simd_sign(double x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_double2 simd_sign(simd_double2 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_double3 simd_sign(simd_double3 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_double4 simd_sign(simd_double4 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. */ +static inline SIMD_CFUNC simd_double8 simd_sign(simd_double8 x); +/*! @abstract -1 if x is negative, +1 if x is positive, and 0 otherwise. + * @discussion Deprecated. Use simd_sign(x) instead. */ +#define vector_sign simd_sign + +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC float simd_mix(float x, float y, float t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_float2 simd_mix(simd_float2 x, simd_float2 y, simd_float2 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_float3 simd_mix(simd_float3 x, simd_float3 y, simd_float3 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_float4 simd_mix(simd_float4 x, simd_float4 y, simd_float4 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_float8 simd_mix(simd_float8 x, simd_float8 y, simd_float8 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_float16 simd_mix(simd_float16 x, simd_float16 y, simd_float16 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC double simd_mix(double x, double y, double t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_double2 simd_mix(simd_double2 x, simd_double2 y, simd_double2 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_double3 simd_mix(simd_double3 x, simd_double3 y, simd_double3 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_double4 simd_mix(simd_double4 x, simd_double4 y, simd_double4 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 */ +static inline SIMD_CFUNC simd_double8 simd_mix(simd_double8 x, simd_double8 y, simd_double8 t); +/*! @abstract Linearly interpolates between x and y, taking the value x when + * t=0 and y when t=1 + * @discussion Deprecated. Use simd_mix(x, y, t) instead. */ +#define vector_mix simd_mix + +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC float simd_precise_recip(float x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_float2 simd_precise_recip(simd_float2 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_float3 simd_precise_recip(simd_float3 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_float4 simd_precise_recip(simd_float4 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_float8 simd_precise_recip(simd_float8 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_float16 simd_precise_recip(simd_float16 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC double simd_precise_recip(double x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_double2 simd_precise_recip(simd_double2 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_double3 simd_precise_recip(simd_double3 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_double4 simd_precise_recip(simd_double4 x); +/*! @abstract A good approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * a few units in the last place (ULPs). */ +static inline SIMD_CFUNC simd_double8 simd_precise_recip(simd_double8 x); +/*! @abstract A good approximation to 1/x. + * @discussion Deprecated. Use simd_precise_recip(x) instead. */ +#define vector_precise_recip simd_precise_recip + +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC float simd_fast_recip(float x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_float2 simd_fast_recip(simd_float2 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_float3 simd_fast_recip(simd_float3 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_float4 simd_fast_recip(simd_float4 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_float8 simd_fast_recip(simd_float8 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_float16 simd_fast_recip(simd_float16 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC double simd_fast_recip(double x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_double2 simd_fast_recip(simd_double2 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_double3 simd_fast_recip(simd_double3 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_double4 simd_fast_recip(simd_double4 x); +/*! @abstract A fast approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow; otherwise this function is accurate to + * at least 11 bits for float and 22 bits for double. */ +static inline SIMD_CFUNC simd_double8 simd_fast_recip(simd_double8 x); +/*! @abstract A fast approximation to 1/x. + * @discussion Deprecated. Use simd_fast_recip(x) instead. */ +#define vector_fast_recip simd_fast_recip + +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC float simd_recip(float x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float2 simd_recip(simd_float2 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float3 simd_recip(simd_float3 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float4 simd_recip(simd_float4 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float8 simd_recip(simd_float8 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float16 simd_recip(simd_float16 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC double simd_recip(double x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double2 simd_recip(simd_double2 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double3 simd_recip(simd_double3 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double4 simd_recip(simd_double4 x); +/*! @abstract An approximation to 1/x. + * @discussion If x is very close to the limits of representation, the + * result may overflow or underflow. This function maps to + * simd_fast_recip(x) if -ffast-math is specified, and to + * simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double8 simd_recip(simd_double8 x); +/*! @abstract An approximation to 1/x. + * @discussion Deprecated. Use simd_recip(x) instead. */ +#define vector_recip simd_recip + +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC float simd_precise_rsqrt(float x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_float2 simd_precise_rsqrt(simd_float2 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_float3 simd_precise_rsqrt(simd_float3 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_float4 simd_precise_rsqrt(simd_float4 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_float8 simd_precise_rsqrt(simd_float8 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_float16 simd_precise_rsqrt(simd_float16 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC double simd_precise_rsqrt(double x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_double2 simd_precise_rsqrt(simd_double2 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_double3 simd_precise_rsqrt(simd_double3 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_double4 simd_precise_rsqrt(simd_double4 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion This function is accurate to a few units in the last place + * (ULPs). */ +static inline SIMD_CFUNC simd_double8 simd_precise_rsqrt(simd_double8 x); +/*! @abstract A good approximation to 1/sqrt(x). + * @discussion Deprecated. Use simd_precise_rsqrt(x) instead. */ +#define vector_precise_rsqrt simd_precise_rsqrt + +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC float simd_fast_rsqrt(float x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_float2 simd_fast_rsqrt(simd_float2 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_float3 simd_fast_rsqrt(simd_float3 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_float4 simd_fast_rsqrt(simd_float4 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_float8 simd_fast_rsqrt(simd_float8 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_float16 simd_fast_rsqrt(simd_float16 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC double simd_fast_rsqrt(double x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_double2 simd_fast_rsqrt(simd_double2 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_double3 simd_fast_rsqrt(simd_double3 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_double4 simd_fast_rsqrt(simd_double4 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion This function is accurate to at least 11 bits for float and + * 22 bits for double. */ +static inline SIMD_CFUNC simd_double8 simd_fast_rsqrt(simd_double8 x); +/*! @abstract A fast approximation to 1/sqrt(x). + * @discussion Deprecated. Use simd_fast_rsqrt(x) instead. */ +#define vector_fast_rsqrt simd_fast_rsqrt + +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC float simd_rsqrt(float x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float2 simd_rsqrt(simd_float2 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float3 simd_rsqrt(simd_float3 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float4 simd_rsqrt(simd_float4 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float8 simd_rsqrt(simd_float8 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_float16 simd_rsqrt(simd_float16 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC double simd_rsqrt(double x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double2 simd_rsqrt(simd_double2 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double3 simd_rsqrt(simd_double3 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double4 simd_rsqrt(simd_double4 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion This function maps to simd_fast_recip(x) if -ffast-math is + * specified, and to simd_precise_recip(x) otherwise. */ +static inline SIMD_CFUNC simd_double8 simd_rsqrt(simd_double8 x); +/*! @abstract An approximation to 1/sqrt(x). + * @discussion Deprecated. Use simd_rsqrt(x) instead. */ +#define vector_rsqrt simd_rsqrt + +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC float simd_fract(float x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_float2 simd_fract(simd_float2 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_float3 simd_fract(simd_float3 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_float4 simd_fract(simd_float4 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_float8 simd_fract(simd_float8 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_float16 simd_fract(simd_float16 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC double simd_fract(double x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_double2 simd_fract(simd_double2 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_double3 simd_fract(simd_double3 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_double4 simd_fract(simd_double4 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion floor(x) + fract(x) is *approximately* equal to x. If x is + * positive and finite, then the two values are exactly equal. */ +static inline SIMD_CFUNC simd_double8 simd_fract(simd_double8 x); +/*! @abstract The "fractional part" of x, lying in the range [0, 1). + * @discussion Deprecated. Use simd_fract(x) instead. */ +#define vector_fract simd_fract + +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC float simd_step(float edge, float x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_float2 simd_step(simd_float2 edge, simd_float2 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_float3 simd_step(simd_float3 edge, simd_float3 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_float4 simd_step(simd_float4 edge, simd_float4 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_float8 simd_step(simd_float8 edge, simd_float8 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_float16 simd_step(simd_float16 edge, simd_float16 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC double simd_step(double edge, double x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_double2 simd_step(simd_double2 edge, simd_double2 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_double3 simd_step(simd_double3 edge, simd_double3 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_double4 simd_step(simd_double4 edge, simd_double4 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Use a scalar value for edge if you want to apply the same + * threshold to all lanes. */ +static inline SIMD_CFUNC simd_double8 simd_step(simd_double8 edge, simd_double8 x); +/*! @abstract 0 if x < edge, and 1 otherwise. + * @discussion Deprecated. Use simd_step(edge, x) instead. */ +#define vector_step simd_step + +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC float simd_smoothstep(float edge0, float edge1, float x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_float2 simd_smoothstep(simd_float2 edge0, simd_float2 edge1, simd_float2 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_float3 simd_smoothstep(simd_float3 edge0, simd_float3 edge1, simd_float3 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_float4 simd_smoothstep(simd_float4 edge0, simd_float4 edge1, simd_float4 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_float8 simd_smoothstep(simd_float8 edge0, simd_float8 edge1, simd_float8 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_float16 simd_smoothstep(simd_float16 edge0, simd_float16 edge1, simd_float16 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC double simd_smoothstep(double edge0, double edge1, double x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_double2 simd_smoothstep(simd_double2 edge0, simd_double2 edge1, simd_double2 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_double3 simd_smoothstep(simd_double3 edge0, simd_double3 edge1, simd_double3 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_double4 simd_smoothstep(simd_double4 edge0, simd_double4 edge1, simd_double4 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion You can use a scalar value for edge0 and edge1 if you want + * to clamp all lanes at the same points. */ +static inline SIMD_CFUNC simd_double8 simd_smoothstep(simd_double8 edge0, simd_double8 edge1, simd_double8 x); +/*! @abstract Interpolates smoothly between 0 at edge0 and 1 at edge1 + * @discussion Deprecated. Use simd_smoothstep(edge0, edge1, x) instead. */ +#define vector_smoothstep simd_smoothstep + +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char32 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC char simd_reduce_add(simd_char64 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar32 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar64 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC short simd_reduce_add(simd_short2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC short simd_reduce_add(simd_short3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC short simd_reduce_add(simd_short4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC short simd_reduce_add(simd_short8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC short simd_reduce_add(simd_short16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC short simd_reduce_add(simd_short32 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort32 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC int simd_reduce_add(simd_int2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC int simd_reduce_add(simd_int3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC int simd_reduce_add(simd_int4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC int simd_reduce_add(simd_int8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC int simd_reduce_add(simd_int16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC float simd_reduce_add(simd_float2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC float simd_reduce_add(simd_float3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC float simd_reduce_add(simd_float4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC float simd_reduce_add(simd_float8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC float simd_reduce_add(simd_float16 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong8 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC double simd_reduce_add(simd_double2 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC double simd_reduce_add(simd_double3 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC double simd_reduce_add(simd_double4 x); +/*! @abstract Sum of elements in x. + * @discussion This computation may overflow; especial for 8-bit types you + * may need to convert to a wider type before reducing. */ +static inline SIMD_CFUNC double simd_reduce_add(simd_double8 x); +/*! @abstract Sum of elements in x. + * @discussion Deprecated. Use simd_add(x) instead. */ +#define vector_reduce_add simd_reduce_add + +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char32 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_min(simd_char64 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar32 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar64 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_min(simd_short2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_min(simd_short3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_min(simd_short4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_min(simd_short8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_min(simd_short16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_min(simd_short32 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort32 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_min(simd_int2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_min(simd_int3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_min(simd_int4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_min(simd_int8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_min(simd_int16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_min(simd_float2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_min(simd_float3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_min(simd_float4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_min(simd_float8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_min(simd_float16 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong8 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_min(simd_double2 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_min(simd_double3 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_min(simd_double4 x); +/*! @abstract Minimum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_min(simd_double8 x); +/*! @abstract Minimum of elements in x. + * @discussion Deprecated. Use simd_min(x) instead. */ +#define vector_reduce_min simd_reduce_min + +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char32 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC char simd_reduce_max(simd_char64 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar32 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar64 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_max(simd_short2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_max(simd_short3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_max(simd_short4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_max(simd_short8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_max(simd_short16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC short simd_reduce_max(simd_short32 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort32 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_max(simd_int2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_max(simd_int3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_max(simd_int4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_max(simd_int8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC int simd_reduce_max(simd_int16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_max(simd_float2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_max(simd_float3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_max(simd_float4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_max(simd_float8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC float simd_reduce_max(simd_float16 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong8 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_max(simd_double2 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_max(simd_double3 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_max(simd_double4 x); +/*! @abstract Maximum of elements in x. */ +static inline SIMD_CFUNC double simd_reduce_max(simd_double8 x); +/*! @abstract Maximum of elements in x. + * @discussion Deprecated. Use simd_max(x) instead. */ +#define vector_reduce_max simd_reduce_max + +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char2 x, simd_char2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char3 x, simd_char3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char4 x, simd_char4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char8 x, simd_char8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char16 x, simd_char16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char32 x, simd_char32 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_char64 x, simd_char64 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar2 x, simd_uchar2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar3 x, simd_uchar3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar4 x, simd_uchar4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar8 x, simd_uchar8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar16 x, simd_uchar16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar32 x, simd_uchar32 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uchar64 x, simd_uchar64 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_short2 x, simd_short2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_short3 x, simd_short3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_short4 x, simd_short4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_short8 x, simd_short8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_short16 x, simd_short16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_short32 x, simd_short32 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ushort2 x, simd_ushort2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ushort3 x, simd_ushort3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ushort4 x, simd_ushort4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ushort8 x, simd_ushort8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ushort16 x, simd_ushort16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ushort32 x, simd_ushort32 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_int2 x, simd_int2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_int3 x, simd_int3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_int4 x, simd_int4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_int8 x, simd_int8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_int16 x, simd_int16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uint2 x, simd_uint2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uint3 x, simd_uint3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uint4 x, simd_uint4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uint8 x, simd_uint8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_uint16 x, simd_uint16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_float2 x, simd_float2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_float3 x, simd_float3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_float4 x, simd_float4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_float8 x, simd_float8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_float16 x, simd_float16 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_long2 x, simd_long2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_long3 x, simd_long3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_long4 x, simd_long4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_long8 x, simd_long8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ulong2 x, simd_ulong2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ulong3 x, simd_ulong3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ulong4 x, simd_ulong4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_ulong8 x, simd_ulong8 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_double2 x, simd_double2 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_double3 x, simd_double3 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_double4 x, simd_double4 y) { + return simd_all(x == y); +} +/*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. */ +static inline SIMD_CFUNC simd_bool simd_equal(simd_double8 x, simd_double8 y) { + return simd_all(x == y); +} + +#ifdef __cplusplus +} /* extern "C" */ + +namespace simd { + /*! @abstract The lanewise absolute value of x. */ + template static SIMD_CPPFUNC typeN abs(const typeN x) { return ::simd_abs(x); } + /*! @abstract The lanewise maximum of x and y. */ + template static SIMD_CPPFUNC typeN max(const typeN x, const typeN y) { return ::simd_max(x,y); } + /*! @abstract The lanewise minimum of x and y. */ + template static SIMD_CPPFUNC typeN min(const typeN x, const typeN y) { return ::simd_min(x,y); } + /*! @abstract x clamped to the interval [min, max]. */ + template static SIMD_CPPFUNC typeN clamp(const typeN x, const typeN min, const typeN max) { return ::simd_clamp(x,min,max); } + /*! @abstract -1 if x < 0, +1 if x > 0, and 0 otherwise. */ + template static SIMD_CPPFUNC fptypeN sign(const fptypeN x) { return ::simd_sign(x); } + /*! @abstract Linearly interpolates between x and y, taking the value x when t=0 and y when t=1 */ + template static SIMD_CPPFUNC fptypeN mix(const fptypeN x, const fptypeN y, const fptypeN t) { return ::simd_mix(x,y,t); } + /*! @abstract An approximation to 1/x. */ + template static SIMD_CPPFUNC fptypeN recip(const fptypeN x) { return simd_recip(x); } + /*! @abstract An approximation to 1/sqrt(x). */ + template static SIMD_CPPFUNC fptypeN rsqrt(const fptypeN x) { return simd_rsqrt(x); } + /*! @abstract The "fracional part" of x, in the range [0,1). */ + template static SIMD_CPPFUNC fptypeN fract(const fptypeN x) { return ::simd_fract(x); } + /*! @abstract 0 if x < edge, 1 otherwise. */ + template static SIMD_CPPFUNC fptypeN step(const fptypeN edge, const fptypeN x) { return ::simd_step(edge,x); } + /*! @abstract smoothly interpolates from 0 at edge0 to 1 at edge1. */ + template static SIMD_CPPFUNC fptypeN smoothstep(const fptypeN edge0, const fptypeN edge1, const fptypeN x) { return ::simd_smoothstep(edge0,edge1,x); } + /*! @abstract True if and only if each lane of x is equal to the + * corresponding lane of y. + * + * @discussion This isn't operator== because that's already defined by + * the compiler to return a lane mask. */ + template static SIMD_CPPFUNC simd_bool equal(const fptypeN x, const fptypeN y) { return ::simd_equal(x, y); } +#if __cpp_decltype_auto + /* If you are targeting an earlier version of the C++ standard that lacks + decltype_auto support, you may use the C-style simd_reduce_* functions + instead. */ + /*! @abstract The sum of the elements in x. May overflow. */ + template static SIMD_CPPFUNC auto reduce_add(typeN x) { return ::simd_reduce_add(x); } + /*! @abstract The least element in x. */ + template static SIMD_CPPFUNC auto reduce_min(typeN x) { return ::simd_reduce_min(x); } + /*! @abstract The greatest element in x. */ + template static SIMD_CPPFUNC auto reduce_max(typeN x) { return ::simd_reduce_max(x); } +#endif + namespace precise { + /*! @abstract An approximation to 1/x. */ + template static SIMD_CPPFUNC fptypeN recip(const fptypeN x) { return ::simd_precise_recip(x); } + /*! @abstract An approximation to 1/sqrt(x). */ + template static SIMD_CPPFUNC fptypeN rsqrt(const fptypeN x) { return ::simd_precise_rsqrt(x); } + } + namespace fast { + /*! @abstract An approximation to 1/x. */ + template static SIMD_CPPFUNC fptypeN recip(const fptypeN x) { return ::simd_fast_recip(x); } + /*! @abstract An approximation to 1/sqrt(x). */ + template static SIMD_CPPFUNC fptypeN rsqrt(const fptypeN x) { return ::simd_fast_rsqrt(x); } + } +} + +extern "C" { +#endif /* __cplusplus */ + +#pragma mark - Implementation + +static inline SIMD_CFUNC simd_char2 simd_abs(simd_char2 x) { + return simd_make_char2(simd_abs(simd_make_char8_undef(x))); +} + +static inline SIMD_CFUNC simd_char3 simd_abs(simd_char3 x) { + return simd_make_char3(simd_abs(simd_make_char8_undef(x))); +} + +static inline SIMD_CFUNC simd_char4 simd_abs(simd_char4 x) { + return simd_make_char4(simd_abs(simd_make_char8_undef(x))); +} + +static inline SIMD_CFUNC simd_char8 simd_abs(simd_char8 x) { +#if defined __arm__ || defined __arm64__ + return vabs_s8(x); +#else + return simd_make_char8(simd_abs(simd_make_char16_undef(x))); +#endif +} + +static inline SIMD_CFUNC simd_char16 simd_abs(simd_char16 x) { +#if defined __arm__ || defined __arm64__ + return vabsq_s8(x); +#elif defined __SSE4_1__ + return (simd_char16) _mm_abs_epi8((__m128i)x); +#else + simd_char16 mask = x >> 7; return (x ^ mask) - mask; +#endif +} + +static inline SIMD_CFUNC simd_char32 simd_abs(simd_char32 x) { +#if defined __AVX2__ + return _mm256_abs_epi8(x); +#else + return simd_make_char32(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_char64 simd_abs(simd_char64 x) { +#if defined __AVX512BW__ + return _mm512_abs_epi8(x); +#else + return simd_make_char64(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_short2 simd_abs(simd_short2 x) { + return simd_make_short2(simd_abs(simd_make_short4_undef(x))); +} + +static inline SIMD_CFUNC simd_short3 simd_abs(simd_short3 x) { + return simd_make_short3(simd_abs(simd_make_short4_undef(x))); +} + +static inline SIMD_CFUNC simd_short4 simd_abs(simd_short4 x) { +#if defined __arm__ || defined __arm64__ + return vabs_s16(x); +#else + return simd_make_short4(simd_abs(simd_make_short8_undef(x))); +#endif +} + +static inline SIMD_CFUNC simd_short8 simd_abs(simd_short8 x) { +#if defined __arm__ || defined __arm64__ + return vabsq_s16(x); +#elif defined __SSE4_1__ + return (simd_short8) _mm_abs_epi16((__m128i)x); +#else + simd_short8 mask = x >> 15; return (x ^ mask) - mask; +#endif +} + +static inline SIMD_CFUNC simd_short16 simd_abs(simd_short16 x) { +#if defined __AVX2__ + return _mm256_abs_epi16(x); +#else + return simd_make_short16(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_short32 simd_abs(simd_short32 x) { +#if defined __AVX512BW__ + return _mm512_abs_epi16(x); +#else + return simd_make_short32(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_int2 simd_abs(simd_int2 x) { +#if defined __arm__ || defined __arm64__ + return vabs_s32(x); +#else + return simd_make_int2(simd_abs(simd_make_int4_undef(x))); +#endif +} + +static inline SIMD_CFUNC simd_int3 simd_abs(simd_int3 x) { + return simd_make_int3(simd_abs(simd_make_int4_undef(x))); +} + +static inline SIMD_CFUNC simd_int4 simd_abs(simd_int4 x) { +#if defined __arm__ || defined __arm64__ + return vabsq_s32(x); +#elif defined __SSE4_1__ + return (simd_int4) _mm_abs_epi32((__m128i)x); +#else + simd_int4 mask = x >> 31; return (x ^ mask) - mask; +#endif +} + +static inline SIMD_CFUNC simd_int8 simd_abs(simd_int8 x) { +#if defined __AVX2__ + return _mm256_abs_epi32(x); +#else + return simd_make_int8(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_int16 simd_abs(simd_int16 x) { +#if defined __AVX512F__ + return _mm512_abs_epi32(x); +#else + return simd_make_int16(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_abs(simd_float2 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_float3 simd_abs(simd_float3 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_float4 simd_abs(simd_float4 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_float8 simd_abs(simd_float8 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_float16 simd_abs(simd_float16 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_long2 simd_abs(simd_long2 x) { +#if defined __arm64__ + return vabsq_s64(x); +#elif defined __SSE4_1__ + return (simd_long2) _mm_abs_epi64((__m128i)x); +#else + simd_long2 mask = x >> 63; return (x ^ mask) - mask; +#endif +} + +static inline SIMD_CFUNC simd_long3 simd_abs(simd_long3 x) { + return simd_make_long3(simd_abs(simd_make_long4_undef(x))); +} + +static inline SIMD_CFUNC simd_long4 simd_abs(simd_long4 x) { +#if defined __AVX2__ + return _mm256_abs_epi64(x); +#else + return simd_make_long4(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_long8 simd_abs(simd_long8 x) { +#if defined __AVX512F__ + return _mm512_abs_epi64(x); +#else + return simd_make_long8(simd_abs(x.lo), simd_abs(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_double2 simd_abs(simd_double2 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_double3 simd_abs(simd_double3 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_double4 simd_abs(simd_double4 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_double8 simd_abs(simd_double8 x) { + return __tg_fabs(x); +} + +static inline SIMD_CFUNC simd_char2 simd_min(simd_char2 x, simd_char2 y) { + return simd_make_char2(simd_min(simd_make_char8_undef(x), simd_make_char8_undef(y))); +} + +static inline SIMD_CFUNC simd_char3 simd_min(simd_char3 x, simd_char3 y) { + return simd_make_char3(simd_min(simd_make_char8_undef(x), simd_make_char8_undef(y))); +} + +static inline SIMD_CFUNC simd_char4 simd_min(simd_char4 x, simd_char4 y) { + return simd_make_char4(simd_min(simd_make_char8_undef(x), simd_make_char8_undef(y))); +} + +static inline SIMD_CFUNC simd_char8 simd_min(simd_char8 x, simd_char8 y) { +#if defined __arm__ || defined __arm64__ + return vmin_s8(x, y); +#else + return simd_make_char8(simd_min(simd_make_char16_undef(x), simd_make_char16_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_char16 simd_min(simd_char16 x, simd_char16 y) { +#if defined __arm__ || defined __arm64__ + return vminq_s8(x, y); +#elif defined __SSE4_1__ + return (simd_char16) _mm_min_epi8((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_char32 simd_min(simd_char32 x, simd_char32 y) { +#if defined __AVX2__ + return _mm256_min_epi8(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_char64 simd_min(simd_char64 x, simd_char64 y) { +#if defined __AVX512BW__ + return _mm512_min_epi8(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_uchar2 simd_min(simd_uchar2 x, simd_uchar2 y) { + return simd_make_uchar2(simd_min(simd_make_uchar8_undef(x), simd_make_uchar8_undef(y))); +} + +static inline SIMD_CFUNC simd_uchar3 simd_min(simd_uchar3 x, simd_uchar3 y) { + return simd_make_uchar3(simd_min(simd_make_uchar8_undef(x), simd_make_uchar8_undef(y))); +} + +static inline SIMD_CFUNC simd_uchar4 simd_min(simd_uchar4 x, simd_uchar4 y) { + return simd_make_uchar4(simd_min(simd_make_uchar8_undef(x), simd_make_uchar8_undef(y))); +} + +static inline SIMD_CFUNC simd_uchar8 simd_min(simd_uchar8 x, simd_uchar8 y) { +#if defined __arm__ || defined __arm64__ + return vmin_u8(x, y); +#else + return simd_make_uchar8(simd_min(simd_make_uchar16_undef(x), simd_make_uchar16_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_uchar16 simd_min(simd_uchar16 x, simd_uchar16 y) { +#if defined __arm__ || defined __arm64__ + return vminq_u8(x, y); +#elif defined __SSE4_1__ + return (simd_uchar16) _mm_min_epu8((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_uchar32 simd_min(simd_uchar32 x, simd_uchar32 y) { +#if defined __AVX2__ + return _mm256_min_epu8(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_uchar64 simd_min(simd_uchar64 x, simd_uchar64 y) { +#if defined __AVX512BW__ + return _mm512_min_epu8(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_short2 simd_min(simd_short2 x, simd_short2 y) { + return simd_make_short2(simd_min(simd_make_short4_undef(x), simd_make_short4_undef(y))); +} + +static inline SIMD_CFUNC simd_short3 simd_min(simd_short3 x, simd_short3 y) { + return simd_make_short3(simd_min(simd_make_short4_undef(x), simd_make_short4_undef(y))); +} + +static inline SIMD_CFUNC simd_short4 simd_min(simd_short4 x, simd_short4 y) { +#if defined __arm__ || defined __arm64__ + return vmin_s16(x, y); +#else + return simd_make_short4(simd_min(simd_make_short8_undef(x), simd_make_short8_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_short8 simd_min(simd_short8 x, simd_short8 y) { +#if defined __arm__ || defined __arm64__ + return vminq_s16(x, y); +#elif defined __SSE4_1__ + return (simd_short8) _mm_min_epi16((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_short16 simd_min(simd_short16 x, simd_short16 y) { +#if defined __AVX2__ + return _mm256_min_epi16(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_short32 simd_min(simd_short32 x, simd_short32 y) { +#if defined __AVX512BW__ + return _mm512_min_epi16(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_ushort2 simd_min(simd_ushort2 x, simd_ushort2 y) { + return simd_make_ushort2(simd_min(simd_make_ushort4_undef(x), simd_make_ushort4_undef(y))); +} + +static inline SIMD_CFUNC simd_ushort3 simd_min(simd_ushort3 x, simd_ushort3 y) { + return simd_make_ushort3(simd_min(simd_make_ushort4_undef(x), simd_make_ushort4_undef(y))); +} + +static inline SIMD_CFUNC simd_ushort4 simd_min(simd_ushort4 x, simd_ushort4 y) { +#if defined __arm__ || defined __arm64__ + return vmin_u16(x, y); +#else + return simd_make_ushort4(simd_min(simd_make_ushort8_undef(x), simd_make_ushort8_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_ushort8 simd_min(simd_ushort8 x, simd_ushort8 y) { +#if defined __arm__ || defined __arm64__ + return vminq_u16(x, y); +#elif defined __SSE4_1__ + return (simd_ushort8) _mm_min_epu16((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_ushort16 simd_min(simd_ushort16 x, simd_ushort16 y) { +#if defined __AVX2__ + return _mm256_min_epu16(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_ushort32 simd_min(simd_ushort32 x, simd_ushort32 y) { +#if defined __AVX512BW__ + return _mm512_min_epu16(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_int2 simd_min(simd_int2 x, simd_int2 y) { +#if defined __arm__ || defined __arm64__ + return vmin_s32(x, y); +#else + return simd_make_int2(simd_min(simd_make_int4_undef(x), simd_make_int4_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_int3 simd_min(simd_int3 x, simd_int3 y) { + return simd_make_int3(simd_min(simd_make_int4_undef(x), simd_make_int4_undef(y))); +} + +static inline SIMD_CFUNC simd_int4 simd_min(simd_int4 x, simd_int4 y) { +#if defined __arm__ || defined __arm64__ + return vminq_s32(x, y); +#elif defined __SSE4_1__ + return (simd_int4) _mm_min_epi32((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_int8 simd_min(simd_int8 x, simd_int8 y) { +#if defined __AVX2__ + return _mm256_min_epi32(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_int16 simd_min(simd_int16 x, simd_int16 y) { +#if defined __AVX512F__ + return _mm512_min_epi32(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_uint2 simd_min(simd_uint2 x, simd_uint2 y) { +#if defined __arm__ || defined __arm64__ + return vmin_u32(x, y); +#else + return simd_make_uint2(simd_min(simd_make_uint4_undef(x), simd_make_uint4_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_uint3 simd_min(simd_uint3 x, simd_uint3 y) { + return simd_make_uint3(simd_min(simd_make_uint4_undef(x), simd_make_uint4_undef(y))); +} + +static inline SIMD_CFUNC simd_uint4 simd_min(simd_uint4 x, simd_uint4 y) { +#if defined __arm__ || defined __arm64__ + return vminq_u32(x, y); +#elif defined __SSE4_1__ + return (simd_uint4) _mm_min_epu32((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_uint8 simd_min(simd_uint8 x, simd_uint8 y) { +#if defined __AVX2__ + return _mm256_min_epu32(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_uint16 simd_min(simd_uint16 x, simd_uint16 y) { +#if defined __AVX512F__ + return _mm512_min_epu32(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC float simd_min(float x, float y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_float2 simd_min(simd_float2 x, simd_float2 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_float3 simd_min(simd_float3 x, simd_float3 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_float4 simd_min(simd_float4 x, simd_float4 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_float8 simd_min(simd_float8 x, simd_float8 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_float16 simd_min(simd_float16 x, simd_float16 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_long2 simd_min(simd_long2 x, simd_long2 y) { +#if defined __AVX512VL__ + return _mm_min_epi64(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_long3 simd_min(simd_long3 x, simd_long3 y) { + return simd_make_long3(simd_min(simd_make_long4_undef(x), simd_make_long4_undef(y))); +} + +static inline SIMD_CFUNC simd_long4 simd_min(simd_long4 x, simd_long4 y) { +#if defined __AVX512VL__ + return _mm256_min_epi64(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_long8 simd_min(simd_long8 x, simd_long8 y) { +#if defined __AVX512F__ + return _mm512_min_epi64(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_ulong2 simd_min(simd_ulong2 x, simd_ulong2 y) { +#if defined __AVX512VL__ + return _mm_min_epu64(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_ulong3 simd_min(simd_ulong3 x, simd_ulong3 y) { + return simd_make_ulong3(simd_min(simd_make_ulong4_undef(x), simd_make_ulong4_undef(y))); +} + +static inline SIMD_CFUNC simd_ulong4 simd_min(simd_ulong4 x, simd_ulong4 y) { +#if defined __AVX512VL__ + return _mm256_min_epu64(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC simd_ulong8 simd_min(simd_ulong8 x, simd_ulong8 y) { +#if defined __AVX512F__ + return _mm512_min_epu64(x, y); +#else + return simd_bitselect(x, y, y < x); +#endif +} + +static inline SIMD_CFUNC double simd_min(double x, double y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_double2 simd_min(simd_double2 x, simd_double2 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_double3 simd_min(simd_double3 x, simd_double3 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_double4 simd_min(simd_double4 x, simd_double4 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_double8 simd_min(simd_double8 x, simd_double8 y) { + return __tg_fmin(x,y); +} + +static inline SIMD_CFUNC simd_char2 simd_max(simd_char2 x, simd_char2 y) { + return simd_make_char2(simd_max(simd_make_char8_undef(x), simd_make_char8_undef(y))); +} + +static inline SIMD_CFUNC simd_char3 simd_max(simd_char3 x, simd_char3 y) { + return simd_make_char3(simd_max(simd_make_char8_undef(x), simd_make_char8_undef(y))); +} + +static inline SIMD_CFUNC simd_char4 simd_max(simd_char4 x, simd_char4 y) { + return simd_make_char4(simd_max(simd_make_char8_undef(x), simd_make_char8_undef(y))); +} + +static inline SIMD_CFUNC simd_char8 simd_max(simd_char8 x, simd_char8 y) { +#if defined __arm__ || defined __arm64__ + return vmax_s8(x, y); +#else + return simd_make_char8(simd_max(simd_make_char16_undef(x), simd_make_char16_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_char16 simd_max(simd_char16 x, simd_char16 y) { +#if defined __arm__ || defined __arm64__ + return vmaxq_s8(x, y); +#elif defined __SSE4_1__ + return (simd_char16) _mm_max_epi8((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_char32 simd_max(simd_char32 x, simd_char32 y) { +#if defined __AVX2__ + return _mm256_max_epi8(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_char64 simd_max(simd_char64 x, simd_char64 y) { +#if defined __AVX512BW__ + return _mm512_max_epi8(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_uchar2 simd_max(simd_uchar2 x, simd_uchar2 y) { + return simd_make_uchar2(simd_max(simd_make_uchar8_undef(x), simd_make_uchar8_undef(y))); +} + +static inline SIMD_CFUNC simd_uchar3 simd_max(simd_uchar3 x, simd_uchar3 y) { + return simd_make_uchar3(simd_max(simd_make_uchar8_undef(x), simd_make_uchar8_undef(y))); +} + +static inline SIMD_CFUNC simd_uchar4 simd_max(simd_uchar4 x, simd_uchar4 y) { + return simd_make_uchar4(simd_max(simd_make_uchar8_undef(x), simd_make_uchar8_undef(y))); +} + +static inline SIMD_CFUNC simd_uchar8 simd_max(simd_uchar8 x, simd_uchar8 y) { +#if defined __arm__ || defined __arm64__ + return vmax_u8(x, y); +#else + return simd_make_uchar8(simd_max(simd_make_uchar16_undef(x), simd_make_uchar16_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_uchar16 simd_max(simd_uchar16 x, simd_uchar16 y) { +#if defined __arm__ || defined __arm64__ + return vmaxq_u8(x, y); +#elif defined __SSE4_1__ + return (simd_uchar16) _mm_max_epu8((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_uchar32 simd_max(simd_uchar32 x, simd_uchar32 y) { +#if defined __AVX2__ + return _mm256_max_epu8(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_uchar64 simd_max(simd_uchar64 x, simd_uchar64 y) { +#if defined __AVX512BW__ + return _mm512_max_epu8(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_short2 simd_max(simd_short2 x, simd_short2 y) { + return simd_make_short2(simd_max(simd_make_short4_undef(x), simd_make_short4_undef(y))); +} + +static inline SIMD_CFUNC simd_short3 simd_max(simd_short3 x, simd_short3 y) { + return simd_make_short3(simd_max(simd_make_short4_undef(x), simd_make_short4_undef(y))); +} + +static inline SIMD_CFUNC simd_short4 simd_max(simd_short4 x, simd_short4 y) { +#if defined __arm__ || defined __arm64__ + return vmax_s16(x, y); +#else + return simd_make_short4(simd_max(simd_make_short8_undef(x), simd_make_short8_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_short8 simd_max(simd_short8 x, simd_short8 y) { +#if defined __arm__ || defined __arm64__ + return vmaxq_s16(x, y); +#elif defined __SSE4_1__ + return (simd_short8) _mm_max_epi16((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_short16 simd_max(simd_short16 x, simd_short16 y) { +#if defined __AVX2__ + return _mm256_max_epi16(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_short32 simd_max(simd_short32 x, simd_short32 y) { +#if defined __AVX512BW__ + return _mm512_max_epi16(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_ushort2 simd_max(simd_ushort2 x, simd_ushort2 y) { + return simd_make_ushort2(simd_max(simd_make_ushort4_undef(x), simd_make_ushort4_undef(y))); +} + +static inline SIMD_CFUNC simd_ushort3 simd_max(simd_ushort3 x, simd_ushort3 y) { + return simd_make_ushort3(simd_max(simd_make_ushort4_undef(x), simd_make_ushort4_undef(y))); +} + +static inline SIMD_CFUNC simd_ushort4 simd_max(simd_ushort4 x, simd_ushort4 y) { +#if defined __arm__ || defined __arm64__ + return vmax_u16(x, y); +#else + return simd_make_ushort4(simd_max(simd_make_ushort8_undef(x), simd_make_ushort8_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_ushort8 simd_max(simd_ushort8 x, simd_ushort8 y) { +#if defined __arm__ || defined __arm64__ + return vmaxq_u16(x, y); +#elif defined __SSE4_1__ + return (simd_ushort8) _mm_max_epu16((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_ushort16 simd_max(simd_ushort16 x, simd_ushort16 y) { +#if defined __AVX2__ + return _mm256_max_epu16(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_ushort32 simd_max(simd_ushort32 x, simd_ushort32 y) { +#if defined __AVX512BW__ + return _mm512_max_epu16(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_int2 simd_max(simd_int2 x, simd_int2 y) { +#if defined __arm__ || defined __arm64__ + return vmax_s32(x, y); +#else + return simd_make_int2(simd_max(simd_make_int4_undef(x), simd_make_int4_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_int3 simd_max(simd_int3 x, simd_int3 y) { + return simd_make_int3(simd_max(simd_make_int4_undef(x), simd_make_int4_undef(y))); +} + +static inline SIMD_CFUNC simd_int4 simd_max(simd_int4 x, simd_int4 y) { +#if defined __arm__ || defined __arm64__ + return vmaxq_s32(x, y); +#elif defined __SSE4_1__ + return (simd_int4) _mm_max_epi32((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_int8 simd_max(simd_int8 x, simd_int8 y) { +#if defined __AVX2__ + return _mm256_max_epi32(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_int16 simd_max(simd_int16 x, simd_int16 y) { +#if defined __AVX512F__ + return _mm512_max_epi32(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_uint2 simd_max(simd_uint2 x, simd_uint2 y) { +#if defined __arm__ || defined __arm64__ + return vmax_u32(x, y); +#else + return simd_make_uint2(simd_max(simd_make_uint4_undef(x), simd_make_uint4_undef(y))); +#endif + +} + +static inline SIMD_CFUNC simd_uint3 simd_max(simd_uint3 x, simd_uint3 y) { + return simd_make_uint3(simd_max(simd_make_uint4_undef(x), simd_make_uint4_undef(y))); +} + +static inline SIMD_CFUNC simd_uint4 simd_max(simd_uint4 x, simd_uint4 y) { +#if defined __arm__ || defined __arm64__ + return vmaxq_u32(x, y); +#elif defined __SSE4_1__ + return (simd_uint4) _mm_max_epu32((__m128i)x, (__m128i)y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_uint8 simd_max(simd_uint8 x, simd_uint8 y) { +#if defined __AVX2__ + return _mm256_max_epu32(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_uint16 simd_max(simd_uint16 x, simd_uint16 y) { +#if defined __AVX512F__ + return _mm512_max_epu32(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC float simd_max(float x, float y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_float2 simd_max(simd_float2 x, simd_float2 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_float3 simd_max(simd_float3 x, simd_float3 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_float4 simd_max(simd_float4 x, simd_float4 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_float8 simd_max(simd_float8 x, simd_float8 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_float16 simd_max(simd_float16 x, simd_float16 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_long2 simd_max(simd_long2 x, simd_long2 y) { +#if defined __AVX512VL__ + return _mm_max_epi64(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_long3 simd_max(simd_long3 x, simd_long3 y) { + return simd_make_long3(simd_max(simd_make_long4_undef(x), simd_make_long4_undef(y))); +} + +static inline SIMD_CFUNC simd_long4 simd_max(simd_long4 x, simd_long4 y) { +#if defined __AVX512VL__ + return _mm256_max_epi64(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_long8 simd_max(simd_long8 x, simd_long8 y) { +#if defined __AVX512F__ + return _mm512_max_epi64(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_ulong2 simd_max(simd_ulong2 x, simd_ulong2 y) { +#if defined __AVX512VL__ + return _mm_max_epu64(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_ulong3 simd_max(simd_ulong3 x, simd_ulong3 y) { + return simd_make_ulong3(simd_max(simd_make_ulong4_undef(x), simd_make_ulong4_undef(y))); +} + +static inline SIMD_CFUNC simd_ulong4 simd_max(simd_ulong4 x, simd_ulong4 y) { +#if defined __AVX512VL__ + return _mm256_max_epu64(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC simd_ulong8 simd_max(simd_ulong8 x, simd_ulong8 y) { +#if defined __AVX512F__ + return _mm512_max_epu64(x, y); +#else + return simd_bitselect(x, y, x < y); +#endif +} + +static inline SIMD_CFUNC double simd_max(double x, double y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_double2 simd_max(simd_double2 x, simd_double2 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_double3 simd_max(simd_double3 x, simd_double3 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_double4 simd_max(simd_double4 x, simd_double4 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_double8 simd_max(simd_double8 x, simd_double8 y) { + return __tg_fmax(x,y); +} + +static inline SIMD_CFUNC simd_char2 simd_clamp(simd_char2 x, simd_char2 min, simd_char2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_char3 simd_clamp(simd_char3 x, simd_char3 min, simd_char3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_char4 simd_clamp(simd_char4 x, simd_char4 min, simd_char4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_char8 simd_clamp(simd_char8 x, simd_char8 min, simd_char8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_char16 simd_clamp(simd_char16 x, simd_char16 min, simd_char16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_char32 simd_clamp(simd_char32 x, simd_char32 min, simd_char32 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_char64 simd_clamp(simd_char64 x, simd_char64 min, simd_char64 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar2 simd_clamp(simd_uchar2 x, simd_uchar2 min, simd_uchar2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar3 simd_clamp(simd_uchar3 x, simd_uchar3 min, simd_uchar3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar4 simd_clamp(simd_uchar4 x, simd_uchar4 min, simd_uchar4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar8 simd_clamp(simd_uchar8 x, simd_uchar8 min, simd_uchar8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar16 simd_clamp(simd_uchar16 x, simd_uchar16 min, simd_uchar16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar32 simd_clamp(simd_uchar32 x, simd_uchar32 min, simd_uchar32 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uchar64 simd_clamp(simd_uchar64 x, simd_uchar64 min, simd_uchar64 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_short2 simd_clamp(simd_short2 x, simd_short2 min, simd_short2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_short3 simd_clamp(simd_short3 x, simd_short3 min, simd_short3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_short4 simd_clamp(simd_short4 x, simd_short4 min, simd_short4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_short8 simd_clamp(simd_short8 x, simd_short8 min, simd_short8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_short16 simd_clamp(simd_short16 x, simd_short16 min, simd_short16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_short32 simd_clamp(simd_short32 x, simd_short32 min, simd_short32 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ushort2 simd_clamp(simd_ushort2 x, simd_ushort2 min, simd_ushort2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ushort3 simd_clamp(simd_ushort3 x, simd_ushort3 min, simd_ushort3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ushort4 simd_clamp(simd_ushort4 x, simd_ushort4 min, simd_ushort4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ushort8 simd_clamp(simd_ushort8 x, simd_ushort8 min, simd_ushort8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ushort16 simd_clamp(simd_ushort16 x, simd_ushort16 min, simd_ushort16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ushort32 simd_clamp(simd_ushort32 x, simd_ushort32 min, simd_ushort32 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_int2 simd_clamp(simd_int2 x, simd_int2 min, simd_int2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_int3 simd_clamp(simd_int3 x, simd_int3 min, simd_int3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_int4 simd_clamp(simd_int4 x, simd_int4 min, simd_int4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_int8 simd_clamp(simd_int8 x, simd_int8 min, simd_int8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_int16 simd_clamp(simd_int16 x, simd_int16 min, simd_int16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uint2 simd_clamp(simd_uint2 x, simd_uint2 min, simd_uint2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uint3 simd_clamp(simd_uint3 x, simd_uint3 min, simd_uint3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uint4 simd_clamp(simd_uint4 x, simd_uint4 min, simd_uint4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uint8 simd_clamp(simd_uint8 x, simd_uint8 min, simd_uint8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_uint16 simd_clamp(simd_uint16 x, simd_uint16 min, simd_uint16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC float simd_clamp(float x, float min, float max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_float2 simd_clamp(simd_float2 x, simd_float2 min, simd_float2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_float3 simd_clamp(simd_float3 x, simd_float3 min, simd_float3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_float4 simd_clamp(simd_float4 x, simd_float4 min, simd_float4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_float8 simd_clamp(simd_float8 x, simd_float8 min, simd_float8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_float16 simd_clamp(simd_float16 x, simd_float16 min, simd_float16 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_long2 simd_clamp(simd_long2 x, simd_long2 min, simd_long2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_long3 simd_clamp(simd_long3 x, simd_long3 min, simd_long3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_long4 simd_clamp(simd_long4 x, simd_long4 min, simd_long4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_long8 simd_clamp(simd_long8 x, simd_long8 min, simd_long8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ulong2 simd_clamp(simd_ulong2 x, simd_ulong2 min, simd_ulong2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ulong3 simd_clamp(simd_ulong3 x, simd_ulong3 min, simd_ulong3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ulong4 simd_clamp(simd_ulong4 x, simd_ulong4 min, simd_ulong4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_ulong8 simd_clamp(simd_ulong8 x, simd_ulong8 min, simd_ulong8 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC double simd_clamp(double x, double min, double max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_double2 simd_clamp(simd_double2 x, simd_double2 min, simd_double2 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_double3 simd_clamp(simd_double3 x, simd_double3 min, simd_double3 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_double4 simd_clamp(simd_double4 x, simd_double4 min, simd_double4 max) { + return simd_min(simd_max(x, min), max); +} + +static inline SIMD_CFUNC simd_double8 simd_clamp(simd_double8 x, simd_double8 min, simd_double8 max) { + return simd_min(simd_max(x, min), max); +} + + +static inline SIMD_CFUNC float simd_sign(float x) { + return (x == 0 | x != x) ? 0 : copysign(1,x); +} + +static inline SIMD_CFUNC simd_float2 simd_sign(simd_float2 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_float3 simd_sign(simd_float3 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_float4 simd_sign(simd_float4 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_float8 simd_sign(simd_float8 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_float16 simd_sign(simd_float16 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC double simd_sign(double x) { + return (x == 0 | x != x) ? 0 : copysign(1,x); +} + +static inline SIMD_CFUNC simd_double2 simd_sign(simd_double2 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_double3 simd_sign(simd_double3 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_double4 simd_sign(simd_double4 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC simd_double8 simd_sign(simd_double8 x) { + return simd_bitselect(__tg_copysign(1,x), 0, x == 0 | x != x); +} + +static inline SIMD_CFUNC float simd_mix(float x, float y, float t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_float2 simd_mix(simd_float2 x, simd_float2 y, simd_float2 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_float3 simd_mix(simd_float3 x, simd_float3 y, simd_float3 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_float4 simd_mix(simd_float4 x, simd_float4 y, simd_float4 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_float8 simd_mix(simd_float8 x, simd_float8 y, simd_float8 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_float16 simd_mix(simd_float16 x, simd_float16 y, simd_float16 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC double simd_mix(double x, double y, double t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_double2 simd_mix(simd_double2 x, simd_double2 y, simd_double2 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_double3 simd_mix(simd_double3 x, simd_double3 y, simd_double3 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_double4 simd_mix(simd_double4 x, simd_double4 y, simd_double4 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC simd_double8 simd_mix(simd_double8 x, simd_double8 y, simd_double8 t) { + return x + t*(y - x); +} + +static inline SIMD_CFUNC float simd_recip(float x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_recip(simd_float2 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float3 simd_recip(simd_float3 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float4 simd_recip(simd_float4 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float8 simd_recip(simd_float8 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float16 simd_recip(simd_float16 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC double simd_recip(double x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_double2 simd_recip(simd_double2 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_double3 simd_recip(simd_double3 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_double4 simd_recip(simd_double4 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_double8 simd_recip(simd_double8 x) { +#if __FAST_MATH__ + return simd_fast_recip(x); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC float simd_fast_recip(float x) { +#if defined __AVX512VL__ + simd_float4 x4 = simd_make_float4(x); + return ((simd_float4)_mm_rcp14_ss(x4, x4)).x; +#elif defined __SSE__ + return ((simd_float4)_mm_rcp_ss(simd_make_float4(x))).x; +#elif defined __ARM_NEON__ + return simd_fast_recip(simd_make_float2_undef(x)).x; +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_fast_recip(simd_float2 x) { +#if defined __SSE__ + return simd_make_float2(simd_fast_recip(simd_make_float4_undef(x))); +#elif defined __ARM_NEON__ + simd_float2 r = vrecpe_f32(x); + return r * vrecps_f32(x, r); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float3 simd_fast_recip(simd_float3 x) { + return simd_make_float3(simd_fast_recip(simd_make_float4_undef(x))); +} + +static inline SIMD_CFUNC simd_float4 simd_fast_recip(simd_float4 x) { +#if defined __AVX512VL__ + return _mm_rcp14_ps(x); +#elif defined __SSE__ + return _mm_rcp_ps(x); +#elif defined __ARM_NEON__ + simd_float4 r = vrecpeq_f32(x); + return r * vrecpsq_f32(x, r); +#else + return simd_precise_recip(x); +#endif +} + +static inline SIMD_CFUNC simd_float8 simd_fast_recip(simd_float8 x) { +#if defined __AVX512VL__ + return _mm256_rcp14_ps(x); +#elif defined __AVX__ + return _mm256_rcp_ps(x); +#else + return simd_make_float8(simd_fast_recip(x.lo), simd_fast_recip(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_float16 simd_fast_recip(simd_float16 x) { +#if defined __AVX512F__ + return _mm512_rcp14_ps(x); +#else + return simd_make_float16(simd_fast_recip(x.lo), simd_fast_recip(x.hi)); +#endif +} + +static inline SIMD_CFUNC double simd_fast_recip(double x) { + return simd_precise_recip(x); +} + +static inline SIMD_CFUNC simd_double2 simd_fast_recip(simd_double2 x) { + return simd_precise_recip(x); +} + +static inline SIMD_CFUNC simd_double3 simd_fast_recip(simd_double3 x) { + return simd_precise_recip(x); +} + +static inline SIMD_CFUNC simd_double4 simd_fast_recip(simd_double4 x) { + return simd_precise_recip(x); +} + +static inline SIMD_CFUNC simd_double8 simd_fast_recip(simd_double8 x) { + return simd_precise_recip(x); +} + +static inline SIMD_CFUNC float simd_precise_recip(float x) { +#if defined __SSE__ + float r = simd_fast_recip(x); + return r*(2 - (x == 0 ? -INFINITY : x)*r); +#elif defined __ARM_NEON__ + return simd_precise_recip(simd_make_float2_undef(x)).x; +#else + return 1/x; +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_precise_recip(simd_float2 x) { +#if defined __SSE__ + return simd_make_float2(simd_precise_recip(simd_make_float4_undef(x))); +#elif defined __ARM_NEON__ + simd_float2 r = simd_fast_recip(x); + return r*vrecps_f32(x, r); +#else + return 1/x; +#endif +} + +static inline SIMD_CFUNC simd_float3 simd_precise_recip(simd_float3 x) { + return simd_make_float3(simd_precise_recip(simd_make_float4_undef(x))); +} + +static inline SIMD_CFUNC simd_float4 simd_precise_recip(simd_float4 x) { +#if defined __SSE__ + simd_float4 r = simd_fast_recip(x); + return r*(2 - simd_bitselect(x, -INFINITY, x == 0)*r); +#elif defined __ARM_NEON__ + simd_float4 r = simd_fast_recip(x); + return r*vrecpsq_f32(x, r); +#else + return 1/x; +#endif +} + +static inline SIMD_CFUNC simd_float8 simd_precise_recip(simd_float8 x) { +#if defined __AVX__ + simd_float8 r = simd_fast_recip(x); + return r*(2 - simd_bitselect(x, -INFINITY, x == 0)*r); +#else + return simd_make_float8(simd_precise_recip(x.lo), simd_precise_recip(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_float16 simd_precise_recip(simd_float16 x) { +#if defined __AVX512F__ + simd_float16 r = simd_fast_recip(x); + return r*(2 - simd_bitselect(x, -INFINITY, x == 0)*r); +#else + return simd_make_float16(simd_precise_recip(x.lo), simd_precise_recip(x.hi)); +#endif +} + +static inline SIMD_CFUNC double simd_precise_recip(double x) { + return 1/x; +} + +static inline SIMD_CFUNC simd_double2 simd_precise_recip(simd_double2 x) { + return 1/x; +} + +static inline SIMD_CFUNC simd_double3 simd_precise_recip(simd_double3 x) { + return 1/x; +} + +static inline SIMD_CFUNC simd_double4 simd_precise_recip(simd_double4 x) { + return 1/x; +} + +static inline SIMD_CFUNC simd_double8 simd_precise_recip(simd_double8 x) { + return 1/x; +} + +static inline SIMD_CFUNC float simd_rsqrt(float x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_rsqrt(simd_float2 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float3 simd_rsqrt(simd_float3 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float4 simd_rsqrt(simd_float4 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float8 simd_rsqrt(simd_float8 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float16 simd_rsqrt(simd_float16 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC double simd_rsqrt(double x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_double2 simd_rsqrt(simd_double2 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_double3 simd_rsqrt(simd_double3 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_double4 simd_rsqrt(simd_double4 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_double8 simd_rsqrt(simd_double8 x) { +#if __FAST_MATH__ + return simd_fast_rsqrt(x); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC float simd_fast_rsqrt(float x) { +#if defined __AVX512VL__ + simd_float4 x4 = simd_make_float4(x); + return ((simd_float4)_mm_rsqrt14_ss(x4, x4)).x; +#elif defined __SSE__ + return ((simd_float4)_mm_rsqrt_ss(simd_make_float4(x))).x; +#elif defined __ARM_NEON__ + return simd_fast_rsqrt(simd_make_float2_undef(x)).x; +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_fast_rsqrt(simd_float2 x) { +#if defined __SSE__ + return simd_make_float2(simd_fast_rsqrt(simd_make_float4_undef(x))); +#elif defined __ARM_NEON__ + simd_float2 r = vrsqrte_f32(x); + return r * vrsqrts_f32(x, r*r); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float3 simd_fast_rsqrt(simd_float3 x) { + return simd_make_float3(simd_fast_rsqrt(simd_make_float4_undef(x))); +} + +static inline SIMD_CFUNC simd_float4 simd_fast_rsqrt(simd_float4 x) { +#if defined __AVX512VL__ + return _mm_rsqrt14_ps(x); +#elif defined __SSE__ + return _mm_rsqrt_ps(x); +#elif defined __ARM_NEON__ + simd_float4 r = vrsqrteq_f32(x); + return r * vrsqrtsq_f32(x, r*r); +#else + return simd_precise_rsqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float8 simd_fast_rsqrt(simd_float8 x) { +#if defined __AVX512VL__ + return _mm256_rsqrt14_ps(x); +#elif defined __AVX__ + return _mm256_rsqrt_ps(x); +#else + return simd_make_float8(simd_fast_rsqrt(x.lo), simd_fast_rsqrt(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_float16 simd_fast_rsqrt(simd_float16 x) { +#if defined __AVX512F__ + return _mm512_rsqrt14_ps(x); +#else + return simd_make_float16(simd_fast_rsqrt(x.lo), simd_fast_rsqrt(x.hi)); +#endif +} + +static inline SIMD_CFUNC double simd_fast_rsqrt(double x) { + return simd_precise_rsqrt(x); +} + +static inline SIMD_CFUNC simd_double2 simd_fast_rsqrt(simd_double2 x) { + return simd_precise_rsqrt(x); +} + +static inline SIMD_CFUNC simd_double3 simd_fast_rsqrt(simd_double3 x) { + return simd_precise_rsqrt(x); +} + +static inline SIMD_CFUNC simd_double4 simd_fast_rsqrt(simd_double4 x) { + return simd_precise_rsqrt(x); +} + +static inline SIMD_CFUNC simd_double8 simd_fast_rsqrt(simd_double8 x) { + return simd_precise_rsqrt(x); +} + +static inline SIMD_CFUNC float simd_precise_rsqrt(float x) { +#if defined __SSE__ + float r = simd_fast_rsqrt(x); + return r*(1.5f - 0.5f*(r == INFINITY ? -INFINITY : x)*r*r); +#elif defined __ARM_NEON__ + return simd_precise_rsqrt(simd_make_float2_undef(x)).x; +#else + return 1/sqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float2 simd_precise_rsqrt(simd_float2 x) { +#if defined __SSE__ + return simd_make_float2(simd_precise_rsqrt(simd_make_float4_undef(x))); +#elif defined __ARM_NEON__ + simd_float2 r = simd_fast_rsqrt(x); + return r*vrsqrts_f32(x, r*r); +#else + return 1/__tg_sqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float3 simd_precise_rsqrt(simd_float3 x) { + return simd_make_float3(simd_precise_rsqrt(simd_make_float4_undef(x))); +} + +static inline SIMD_CFUNC simd_float4 simd_precise_rsqrt(simd_float4 x) { +#if defined __SSE__ + simd_float4 r = simd_fast_rsqrt(x); + return r*(1.5 - 0.5*simd_bitselect(x, -INFINITY, r == INFINITY)*r*r); +#elif defined __ARM_NEON__ + simd_float4 r = simd_fast_rsqrt(x); + return r*vrsqrtsq_f32(x, r*r); +#else + return 1/__tg_sqrt(x); +#endif +} + +static inline SIMD_CFUNC simd_float8 simd_precise_rsqrt(simd_float8 x) { +#if defined __AVX__ + simd_float8 r = simd_fast_rsqrt(x); + return r*(1.5 - 0.5*simd_bitselect(x, -INFINITY, r == INFINITY)*r*r); +#else + return simd_make_float8(simd_precise_rsqrt(x.lo), simd_precise_rsqrt(x.hi)); +#endif +} + +static inline SIMD_CFUNC simd_float16 simd_precise_rsqrt(simd_float16 x) { +#if defined __AVX512F__ + simd_float16 r = simd_fast_rsqrt(x); + return r*(1.5 - 0.5*simd_bitselect(x, -INFINITY, r == INFINITY)*r*r); +#else + return simd_make_float16(simd_precise_rsqrt(x.lo), simd_precise_rsqrt(x.hi)); +#endif +} + +static inline SIMD_CFUNC double simd_precise_rsqrt(double x) { + return 1/sqrt(x); +} + +static inline SIMD_CFUNC simd_double2 simd_precise_rsqrt(simd_double2 x) { + return 1/__tg_sqrt(x); +} + +static inline SIMD_CFUNC simd_double3 simd_precise_rsqrt(simd_double3 x) { + return 1/__tg_sqrt(x); +} + +static inline SIMD_CFUNC simd_double4 simd_precise_rsqrt(simd_double4 x) { + return 1/__tg_sqrt(x); +} + +static inline SIMD_CFUNC simd_double8 simd_precise_rsqrt(simd_double8 x) { + return 1/__tg_sqrt(x); +} + +static inline SIMD_CFUNC float simd_fract(float x) { + return fmin(x - floor(x), 0x1.fffffep-1f); +} + +static inline SIMD_CFUNC simd_float2 simd_fract(simd_float2 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffep-1f); +} + +static inline SIMD_CFUNC simd_float3 simd_fract(simd_float3 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffep-1f); +} + +static inline SIMD_CFUNC simd_float4 simd_fract(simd_float4 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffep-1f); +} + +static inline SIMD_CFUNC simd_float8 simd_fract(simd_float8 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffep-1f); +} + +static inline SIMD_CFUNC simd_float16 simd_fract(simd_float16 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffep-1f); +} + +static inline SIMD_CFUNC double simd_fract(double x) { + return fmin(x - floor(x), 0x1.fffffffffffffp-1); +} + +static inline SIMD_CFUNC simd_double2 simd_fract(simd_double2 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffffffffffp-1); +} + +static inline SIMD_CFUNC simd_double3 simd_fract(simd_double3 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffffffffffp-1); +} + +static inline SIMD_CFUNC simd_double4 simd_fract(simd_double4 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffffffffffp-1); +} + +static inline SIMD_CFUNC simd_double8 simd_fract(simd_double8 x) { + return __tg_fmin(x - __tg_floor(x), 0x1.fffffffffffffp-1); +} + +static inline SIMD_CFUNC float simd_step(float edge, float x) { + return !(x < edge); +} + +static inline SIMD_CFUNC simd_float2 simd_step(simd_float2 edge, simd_float2 x) { + return simd_bitselect((simd_float2)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_float3 simd_step(simd_float3 edge, simd_float3 x) { + return simd_bitselect((simd_float3)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_float4 simd_step(simd_float4 edge, simd_float4 x) { + return simd_bitselect((simd_float4)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_float8 simd_step(simd_float8 edge, simd_float8 x) { + return simd_bitselect((simd_float8)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_float16 simd_step(simd_float16 edge, simd_float16 x) { + return simd_bitselect((simd_float16)1, 0, x < edge); +} + +static inline SIMD_CFUNC double simd_step(double edge, double x) { + return !(x < edge); +} + +static inline SIMD_CFUNC simd_double2 simd_step(simd_double2 edge, simd_double2 x) { + return simd_bitselect((simd_double2)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_double3 simd_step(simd_double3 edge, simd_double3 x) { + return simd_bitselect((simd_double3)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_double4 simd_step(simd_double4 edge, simd_double4 x) { + return simd_bitselect((simd_double4)1, 0, x < edge); +} + +static inline SIMD_CFUNC simd_double8 simd_step(simd_double8 edge, simd_double8 x) { + return simd_bitselect((simd_double8)1, 0, x < edge); +} + +static inline SIMD_CFUNC float simd_smoothstep(float edge0, float edge1, float x) { + float t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_float2 simd_smoothstep(simd_float2 edge0, simd_float2 edge1, simd_float2 x) { + simd_float2 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_float3 simd_smoothstep(simd_float3 edge0, simd_float3 edge1, simd_float3 x) { + simd_float3 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_float4 simd_smoothstep(simd_float4 edge0, simd_float4 edge1, simd_float4 x) { + simd_float4 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_float8 simd_smoothstep(simd_float8 edge0, simd_float8 edge1, simd_float8 x) { + simd_float8 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_float16 simd_smoothstep(simd_float16 edge0, simd_float16 edge1, simd_float16 x) { + simd_float16 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC double simd_smoothstep(double edge0, double edge1, double x) { + double t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_double2 simd_smoothstep(simd_double2 edge0, simd_double2 edge1, simd_double2 x) { + simd_double2 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_double3 simd_smoothstep(simd_double3 edge0, simd_double3 edge1, simd_double3 x) { + simd_double3 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_double4 simd_smoothstep(simd_double4 edge0, simd_double4 edge1, simd_double4 x) { + simd_double4 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC simd_double8 simd_smoothstep(simd_double8 edge0, simd_double8 edge1, simd_double8 x) { + simd_double8 t = simd_clamp((x - edge0)/(edge1 - edge0), 0, 1); + return t*t*(3 - 2*t); +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char32 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC char simd_reduce_add(simd_char64 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar32 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_add(simd_uchar64 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC short simd_reduce_add(simd_short2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC short simd_reduce_add(simd_short3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC short simd_reduce_add(simd_short4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC short simd_reduce_add(simd_short8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC short simd_reduce_add(simd_short16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC short simd_reduce_add(simd_short32 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_add(simd_ushort32 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC int simd_reduce_add(simd_int2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC int simd_reduce_add(simd_int3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC int simd_reduce_add(simd_int4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC int simd_reduce_add(simd_int8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC int simd_reduce_add(simd_int16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_add(simd_uint16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC float simd_reduce_add(simd_float2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC float simd_reduce_add(simd_float3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC float simd_reduce_add(simd_float4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC float simd_reduce_add(simd_float8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC float simd_reduce_add(simd_float16 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_add(simd_long8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_add(simd_ulong8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC double simd_reduce_add(simd_double2 x) { + return x.x + x.y; +} + +static inline SIMD_CFUNC double simd_reduce_add(simd_double3 x) { + return x.x + x.y + x.z; +} + +static inline SIMD_CFUNC double simd_reduce_add(simd_double4 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC double simd_reduce_add(simd_double8 x) { + return simd_reduce_add(x.lo + x.hi); +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char3 x) { + char t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char32 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_min(simd_char64 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar3 x) { + unsigned char t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar32 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_min(simd_uchar64 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_min(simd_short2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC short simd_reduce_min(simd_short3 x) { + short t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC short simd_reduce_min(simd_short4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_min(simd_short8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_min(simd_short16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_min(simd_short32 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort3 x) { + unsigned short t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_min(simd_ushort32 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC int simd_reduce_min(simd_int2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC int simd_reduce_min(simd_int3 x) { + int t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC int simd_reduce_min(simd_int4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC int simd_reduce_min(simd_int8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC int simd_reduce_min(simd_int16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint3 x) { + unsigned int t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_min(simd_uint16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC float simd_reduce_min(simd_float2 x) { + return fmin(x.x, x.y); +} + +static inline SIMD_CFUNC float simd_reduce_min(simd_float3 x) { + return fmin(fmin(x.x, x.z), x.y); +} + +static inline SIMD_CFUNC float simd_reduce_min(simd_float4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC float simd_reduce_min(simd_float8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC float simd_reduce_min(simd_float16 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long3 x) { + simd_long1 t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_min(simd_long8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong2 x) { + return x.y < x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong3 x) { + simd_ulong1 t = x.z < x.x ? x.z : x.x; + return x.y < t ? x.y : t; +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_min(simd_ulong8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC double simd_reduce_min(simd_double2 x) { + return fmin(x.x, x.y); +} + +static inline SIMD_CFUNC double simd_reduce_min(simd_double3 x) { + return fmin(fmin(x.x, x.z), x.y); +} + +static inline SIMD_CFUNC double simd_reduce_min(simd_double4 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC double simd_reduce_min(simd_double8 x) { + return simd_reduce_min(simd_min(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char3 x) { + char t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char32 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC char simd_reduce_max(simd_char64 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar3 x) { + unsigned char t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar32 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned char simd_reduce_max(simd_uchar64 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_max(simd_short2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC short simd_reduce_max(simd_short3 x) { + short t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC short simd_reduce_max(simd_short4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_max(simd_short8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_max(simd_short16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC short simd_reduce_max(simd_short32 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort3 x) { + unsigned short t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned short simd_reduce_max(simd_ushort32 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC int simd_reduce_max(simd_int2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC int simd_reduce_max(simd_int3 x) { + int t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC int simd_reduce_max(simd_int4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC int simd_reduce_max(simd_int8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC int simd_reduce_max(simd_int16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint3 x) { + unsigned int t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC unsigned int simd_reduce_max(simd_uint16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC float simd_reduce_max(simd_float2 x) { + return fmax(x.x, x.y); +} + +static inline SIMD_CFUNC float simd_reduce_max(simd_float3 x) { + return fmax(fmax(x.x, x.z), x.y); +} + +static inline SIMD_CFUNC float simd_reduce_max(simd_float4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC float simd_reduce_max(simd_float8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC float simd_reduce_max(simd_float16 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long3 x) { + simd_long1 t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_long1 simd_reduce_max(simd_long8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong2 x) { + return x.y > x.x ? x.y : x.x; +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong3 x) { + simd_ulong1 t = x.z > x.x ? x.z : x.x; + return x.y > t ? x.y : t; +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC simd_ulong1 simd_reduce_max(simd_ulong8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC double simd_reduce_max(simd_double2 x) { + return fmax(x.x, x.y); +} + +static inline SIMD_CFUNC double simd_reduce_max(simd_double3 x) { + return fmax(fmax(x.x, x.z), x.y); +} + +static inline SIMD_CFUNC double simd_reduce_max(simd_double4 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +static inline SIMD_CFUNC double simd_reduce_max(simd_double8 x) { + return simd_reduce_max(simd_max(x.lo, x.hi)); +} + +#ifdef __cplusplus +} +#endif +#endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* SIMD_COMMON_HEADER */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/conversion.h b/lib/libc/include/any-macos.11-any/simd/conversion.h new file mode 100644 index 0000000000..6379afde05 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/conversion.h @@ -0,0 +1,1966 @@ +/* Copyright (c) 2014-2017 Apple, Inc. All rights reserved. + * + * The interfaces declared in this header provide conversions between vector + * types. The following functions are available: + * + * simd_char(x) simd_uchar(x) + * simd_short(x) simd_ushort(x) + * simd_int(x) simd_uint(x) + * simd_long(x) simd_ulong(x) + * simd_float(x) + * simd_double(x) + * + * Each of these functions converts x to a vector whose elements have the + * type named by the function, with the same number of elements as x. Unlike + * a vector cast, these functions convert the elements to the new element + * type. These conversions behave exactly as C scalar conversions, except + * that conversions from integer vector types to signed integer vector types + * are guaranteed to wrap modulo 2^N (where N is the number of bits in an + * element of the result type). + * + * For integer vector types, saturating conversions are also available: + * + * simd_char_sat(x) simd_uchar_sat(x) + * simd_short_sat(x) simd_ushort_sat(x) + * simd_int_sat(x) simd_uint_sat(x) + * simd_long_sat(x) simd_ulong_sat(x) + * + * These conversions clamp x to the representable range of the result type + * before converting. + * + * Unlike most vector operations in , there are no abbreviated C++ + * names for these functions in the simd:: namespace. + */ + +#ifndef __SIMD_CONVERSION_HEADER__ +#define __SIMD_CONVERSION_HEADER__ + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static simd_char2 SIMD_CFUNC simd_char(simd_char2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_char3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_char4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_char8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_char16 __x); +static simd_char32 SIMD_CFUNC simd_char(simd_char32 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_uchar2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_uchar3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_uchar4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_uchar8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_uchar16 __x); +static simd_char32 SIMD_CFUNC simd_char(simd_uchar32 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_short2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_short3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_short4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_short8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_short16 __x); +static simd_char32 SIMD_CFUNC simd_char(simd_short32 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_ushort2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_ushort3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_ushort4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_ushort8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_ushort16 __x); +static simd_char32 SIMD_CFUNC simd_char(simd_ushort32 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_int2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_int3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_int4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_int8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_int16 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_uint2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_uint3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_uint4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_uint8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_uint16 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_float2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_float3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_float4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_float8 __x); +static simd_char16 SIMD_CFUNC simd_char(simd_float16 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_long2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_long3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_long4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_long8 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_ulong2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_ulong3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_ulong4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_ulong8 __x); +static simd_char2 SIMD_CFUNC simd_char(simd_double2 __x); +static simd_char3 SIMD_CFUNC simd_char(simd_double3 __x); +static simd_char4 SIMD_CFUNC simd_char(simd_double4 __x); +static simd_char8 SIMD_CFUNC simd_char(simd_double8 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_char2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_char3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_char4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_char8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_char16 __x); +static simd_char32 SIMD_CFUNC simd_char_sat(simd_char32 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_short2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_short3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_short4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_short8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_short16 __x); +static simd_char32 SIMD_CFUNC simd_char_sat(simd_short32 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_int2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_int3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_int4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_int8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_int16 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_float2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_float3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_float4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_float8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_float16 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_long2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_long3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_long4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_long8 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_double2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_double3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_double4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_double8 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_uchar2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_uchar3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_uchar4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_uchar8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_uchar16 __x); +static simd_char32 SIMD_CFUNC simd_char_sat(simd_uchar32 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_ushort2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_ushort3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_ushort4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_ushort8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_ushort16 __x); +static simd_char32 SIMD_CFUNC simd_char_sat(simd_ushort32 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_uint2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_uint3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_uint4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_uint8 __x); +static simd_char16 SIMD_CFUNC simd_char_sat(simd_uint16 __x); +static simd_char2 SIMD_CFUNC simd_char_sat(simd_ulong2 __x); +static simd_char3 SIMD_CFUNC simd_char_sat(simd_ulong3 __x); +static simd_char4 SIMD_CFUNC simd_char_sat(simd_ulong4 __x); +static simd_char8 SIMD_CFUNC simd_char_sat(simd_ulong8 __x); +#define vector_char simd_char +#define vector_char_sat simd_char_sat + +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_char2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_char3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_char4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_char8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_char16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_char32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_uchar2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_uchar3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_uchar4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_uchar8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_uchar16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_uchar32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_short2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_short3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_short4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_short8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_short16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_short32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_ushort2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_ushort3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_ushort4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_ushort8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_ushort16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_ushort32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_int2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_int3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_int4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_int8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_int16 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_uint2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_uint3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_uint4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_uint8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_uint16 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_float2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_float3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_float4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_float8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_float16 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_long2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_long3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_long4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_long8 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_ulong2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_ulong3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_ulong4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_ulong8 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_double2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_double3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_double4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_double8 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_char2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_char3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_char4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_char8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_char16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_char32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_short2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_short3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_short4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_short8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_short16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_short32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_int2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_int3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_int4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_int8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_int16 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_float2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_float3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_float4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_float8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_float16 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_long2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_long3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_long4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_long8 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_double2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_double3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_double4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_double8 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_uchar2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_uchar3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_uchar4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_uchar8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_uchar16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_uchar32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_ushort2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_ushort3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_ushort4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_ushort8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_ushort16 __x); +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_ushort32 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_uint2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_uint3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_uint4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_uint8 __x); +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_uint16 __x); +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_ulong2 __x); +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_ulong3 __x); +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_ulong4 __x); +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_ulong8 __x); +#define vector_uchar simd_uchar +#define vector_uchar_sat simd_uchar_sat + +static simd_short2 SIMD_CFUNC simd_short(simd_char2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_char3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_char4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_char8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_char16 __x); +static simd_short32 SIMD_CFUNC simd_short(simd_char32 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_uchar2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_uchar3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_uchar4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_uchar8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_uchar16 __x); +static simd_short32 SIMD_CFUNC simd_short(simd_uchar32 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_short2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_short3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_short4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_short8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_short16 __x); +static simd_short32 SIMD_CFUNC simd_short(simd_short32 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_ushort2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_ushort3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_ushort4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_ushort8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_ushort16 __x); +static simd_short32 SIMD_CFUNC simd_short(simd_ushort32 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_int2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_int3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_int4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_int8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_int16 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_uint2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_uint3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_uint4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_uint8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_uint16 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_float2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_float3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_float4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_float8 __x); +static simd_short16 SIMD_CFUNC simd_short(simd_float16 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_long2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_long3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_long4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_long8 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_ulong2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_ulong3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_ulong4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_ulong8 __x); +static simd_short2 SIMD_CFUNC simd_short(simd_double2 __x); +static simd_short3 SIMD_CFUNC simd_short(simd_double3 __x); +static simd_short4 SIMD_CFUNC simd_short(simd_double4 __x); +static simd_short8 SIMD_CFUNC simd_short(simd_double8 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_char2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_char3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_char4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_char8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_char16 __x); +static simd_short32 SIMD_CFUNC simd_short_sat(simd_char32 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_short2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_short3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_short4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_short8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_short16 __x); +static simd_short32 SIMD_CFUNC simd_short_sat(simd_short32 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_int2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_int3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_int4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_int8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_int16 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_float2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_float3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_float4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_float8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_float16 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_long2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_long3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_long4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_long8 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_double2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_double3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_double4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_double8 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_uchar2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_uchar3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_uchar4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_uchar8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_uchar16 __x); +static simd_short32 SIMD_CFUNC simd_short_sat(simd_uchar32 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_ushort2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_ushort3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_ushort4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_ushort8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_ushort16 __x); +static simd_short32 SIMD_CFUNC simd_short_sat(simd_ushort32 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_uint2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_uint3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_uint4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_uint8 __x); +static simd_short16 SIMD_CFUNC simd_short_sat(simd_uint16 __x); +static simd_short2 SIMD_CFUNC simd_short_sat(simd_ulong2 __x); +static simd_short3 SIMD_CFUNC simd_short_sat(simd_ulong3 __x); +static simd_short4 SIMD_CFUNC simd_short_sat(simd_ulong4 __x); +static simd_short8 SIMD_CFUNC simd_short_sat(simd_ulong8 __x); +#define vector_short simd_short +#define vector_short_sat simd_short_sat + +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_char2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_char3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_char4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_char8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_char16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_char32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_uchar2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_uchar3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_uchar4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_uchar8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_uchar16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_uchar32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_short2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_short3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_short4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_short8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_short16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_short32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_ushort2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_ushort3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_ushort4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_ushort8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_ushort16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_ushort32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_int2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_int3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_int4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_int8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_int16 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_uint2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_uint3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_uint4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_uint8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_uint16 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_float2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_float3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_float4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_float8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_float16 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_long2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_long3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_long4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_long8 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_ulong2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_ulong3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_ulong4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_ulong8 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_double2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_double3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_double4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_double8 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_char2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_char3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_char4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_char8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_char16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_char32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_short2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_short3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_short4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_short8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_short16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_short32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_int2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_int3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_int4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_int8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_int16 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_float2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_float3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_float4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_float8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_float16 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_long2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_long3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_long4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_long8 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_double2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_double3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_double4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_double8 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_uchar2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_uchar3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_uchar4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_uchar8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_uchar16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_uchar32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_ushort2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_ushort3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_ushort4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_ushort8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_ushort16 __x); +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_ushort32 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_uint2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_uint3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_uint4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_uint8 __x); +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_uint16 __x); +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_ulong2 __x); +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_ulong3 __x); +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_ulong4 __x); +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_ulong8 __x); +#define vector_ushort simd_ushort +#define vector_ushort_sat simd_ushort_sat + +static simd_int2 SIMD_CFUNC simd_int(simd_char2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_char3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_char4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_char8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_char16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_uchar2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_uchar3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_uchar4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_uchar8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_uchar16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_short2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_short3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_short4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_short8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_short16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_ushort2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_ushort3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_ushort4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_ushort8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_ushort16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_int2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_int3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_int4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_int8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_int16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_uint2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_uint3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_uint4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_uint8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_uint16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_float2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_float3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_float4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_float8 __x); +static simd_int16 SIMD_CFUNC simd_int(simd_float16 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_long2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_long3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_long4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_long8 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_ulong2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_ulong3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_ulong4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_ulong8 __x); +static simd_int2 SIMD_CFUNC simd_int(simd_double2 __x); +static simd_int3 SIMD_CFUNC simd_int(simd_double3 __x); +static simd_int4 SIMD_CFUNC simd_int(simd_double4 __x); +static simd_int8 SIMD_CFUNC simd_int(simd_double8 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_char2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_char3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_char4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_char8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_char16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_short2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_short3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_short4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_short8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_short16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_int2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_int3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_int4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_int8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_int16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_float2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_float3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_float4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_float8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_float16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_long2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_long3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_long4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_long8 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_double2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_double3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_double4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_double8 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_uchar2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_uchar3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_uchar4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_uchar8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_uchar16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_ushort2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_ushort3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_ushort4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_ushort8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_ushort16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_uint2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_uint3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_uint4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_uint8 __x); +static simd_int16 SIMD_CFUNC simd_int_sat(simd_uint16 __x); +static simd_int2 SIMD_CFUNC simd_int_sat(simd_ulong2 __x); +static simd_int3 SIMD_CFUNC simd_int_sat(simd_ulong3 __x); +static simd_int4 SIMD_CFUNC simd_int_sat(simd_ulong4 __x); +static simd_int8 SIMD_CFUNC simd_int_sat(simd_ulong8 __x); +static simd_int2 SIMD_CFUNC simd_int_rte(simd_float2 __x); +static simd_int3 SIMD_CFUNC simd_int_rte(simd_float3 __x); +static simd_int4 SIMD_CFUNC simd_int_rte(simd_float4 __x); +static simd_int8 SIMD_CFUNC simd_int_rte(simd_float8 __x); +static simd_int16 SIMD_CFUNC simd_int_rte(simd_float16 __x); +#define vector_int simd_int +#define vector_int_sat simd_int_sat + +static simd_uint2 SIMD_CFUNC simd_uint(simd_char2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_char3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_char4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_char8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_char16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_uchar2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_uchar3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_uchar4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_uchar8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_uchar16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_short2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_short3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_short4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_short8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_short16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_ushort2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_ushort3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_ushort4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_ushort8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_ushort16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_int2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_int3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_int4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_int8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_int16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_uint2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_uint3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_uint4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_uint8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_uint16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_float2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_float3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_float4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_float8 __x); +static simd_uint16 SIMD_CFUNC simd_uint(simd_float16 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_long2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_long3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_long4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_long8 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_ulong2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_ulong3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_ulong4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_ulong8 __x); +static simd_uint2 SIMD_CFUNC simd_uint(simd_double2 __x); +static simd_uint3 SIMD_CFUNC simd_uint(simd_double3 __x); +static simd_uint4 SIMD_CFUNC simd_uint(simd_double4 __x); +static simd_uint8 SIMD_CFUNC simd_uint(simd_double8 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_char2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_char3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_char4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_char8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_char16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_short2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_short3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_short4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_short8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_short16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_int2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_int3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_int4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_int8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_int16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_float2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_float3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_float4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_float8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_float16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_long2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_long3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_long4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_long8 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_double2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_double3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_double4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_double8 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_uchar2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_uchar3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_uchar4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_uchar8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_uchar16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_ushort2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_ushort3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_ushort4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_ushort8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_ushort16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_uint2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_uint3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_uint4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_uint8 __x); +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_uint16 __x); +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_ulong2 __x); +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_ulong3 __x); +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_ulong4 __x); +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_ulong8 __x); +#define vector_uint simd_uint +#define vector_uint_sat simd_uint_sat + +static simd_float2 SIMD_CFUNC simd_float(simd_char2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_char3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_char4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_char8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_char16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_uchar2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_uchar3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_uchar4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_uchar8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_uchar16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_short2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_short3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_short4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_short8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_short16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_ushort2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_ushort3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_ushort4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_ushort8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_ushort16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_int2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_int3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_int4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_int8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_int16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_uint2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_uint3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_uint4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_uint8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_uint16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_float2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_float3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_float4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_float8 __x); +static simd_float16 SIMD_CFUNC simd_float(simd_float16 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_long2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_long3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_long4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_long8 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_ulong2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_ulong3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_ulong4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_ulong8 __x); +static simd_float2 SIMD_CFUNC simd_float(simd_double2 __x); +static simd_float3 SIMD_CFUNC simd_float(simd_double3 __x); +static simd_float4 SIMD_CFUNC simd_float(simd_double4 __x); +static simd_float8 SIMD_CFUNC simd_float(simd_double8 __x); +#define vector_float simd_float + +static simd_long2 SIMD_CFUNC simd_long(simd_char2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_char3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_char4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_char8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_uchar2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_uchar3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_uchar4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_uchar8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_short2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_short3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_short4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_short8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_ushort2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_ushort3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_ushort4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_ushort8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_int2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_int3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_int4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_int8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_uint2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_uint3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_uint4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_uint8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_float2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_float3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_float4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_float8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_long2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_long3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_long4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_long8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_ulong2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_ulong3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_ulong4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_ulong8 __x); +static simd_long2 SIMD_CFUNC simd_long(simd_double2 __x); +static simd_long3 SIMD_CFUNC simd_long(simd_double3 __x); +static simd_long4 SIMD_CFUNC simd_long(simd_double4 __x); +static simd_long8 SIMD_CFUNC simd_long(simd_double8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_char2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_char3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_char4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_char8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_short2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_short3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_short4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_short8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_int2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_int3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_int4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_int8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_float2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_float3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_float4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_float8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_long2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_long3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_long4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_long8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_double2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_double3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_double4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_double8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_uchar2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_uchar3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_uchar4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_uchar8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_ushort2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_ushort3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_ushort4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_ushort8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_uint2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_uint3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_uint4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_uint8 __x); +static simd_long2 SIMD_CFUNC simd_long_sat(simd_ulong2 __x); +static simd_long3 SIMD_CFUNC simd_long_sat(simd_ulong3 __x); +static simd_long4 SIMD_CFUNC simd_long_sat(simd_ulong4 __x); +static simd_long8 SIMD_CFUNC simd_long_sat(simd_ulong8 __x); +static simd_long2 SIMD_CFUNC simd_long_rte(simd_double2 __x); +static simd_long3 SIMD_CFUNC simd_long_rte(simd_double3 __x); +static simd_long4 SIMD_CFUNC simd_long_rte(simd_double4 __x); +static simd_long8 SIMD_CFUNC simd_long_rte(simd_double8 __x); +#define vector_long simd_long +#define vector_long_sat simd_long_sat + +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_char2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_char3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_char4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_char8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_uchar2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_uchar3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_uchar4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_uchar8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_short2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_short3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_short4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_short8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_ushort2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_ushort3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_ushort4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_ushort8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_int2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_int3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_int4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_int8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_uint2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_uint3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_uint4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_uint8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_float2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_float3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_float4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_float8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_long2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_long3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_long4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_long8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_ulong2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_ulong3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_ulong4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_ulong8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_double2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_double3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_double4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_double8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_char2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_char3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_char4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_char8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_short2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_short3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_short4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_short8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_int2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_int3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_int4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_int8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_float2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_float3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_float4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_float8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_long2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_long3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_long4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_long8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_double2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_double3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_double4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_double8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_uchar2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_uchar3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_uchar4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_uchar8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_ushort2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_ushort3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_ushort4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_ushort8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_uint2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_uint3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_uint4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_uint8 __x); +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_ulong2 __x); +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_ulong3 __x); +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_ulong4 __x); +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_ulong8 __x); +#define vector_ulong simd_ulong +#define vector_ulong_sat simd_ulong_sat + +static simd_double2 SIMD_CFUNC simd_double(simd_char2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_char3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_char4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_char8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_uchar2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_uchar3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_uchar4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_uchar8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_short2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_short3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_short4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_short8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_ushort2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_ushort3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_ushort4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_ushort8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_int2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_int3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_int4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_int8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_uint2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_uint3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_uint4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_uint8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_float2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_float3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_float4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_float8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_long2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_long3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_long4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_long8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_ulong2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_ulong3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_ulong4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_ulong8 __x); +static simd_double2 SIMD_CFUNC simd_double(simd_double2 __x); +static simd_double3 SIMD_CFUNC simd_double(simd_double3 __x); +static simd_double4 SIMD_CFUNC simd_double(simd_double4 __x); +static simd_double8 SIMD_CFUNC simd_double(simd_double8 __x); +#define vector_double simd_double + +static simd_char2 SIMD_CFUNC vector2(char __x, char __y) { return ( simd_char2){__x, __y}; } +static simd_uchar2 SIMD_CFUNC vector2(unsigned char __x, unsigned char __y) { return ( simd_uchar2){__x, __y}; } +static simd_short2 SIMD_CFUNC vector2(short __x, short __y) { return ( simd_short2){__x, __y}; } +static simd_ushort2 SIMD_CFUNC vector2(unsigned short __x, unsigned short __y) { return (simd_ushort2){__x, __y}; } +static simd_int2 SIMD_CFUNC vector2(int __x, int __y) { return ( simd_int2){__x, __y}; } +static simd_uint2 SIMD_CFUNC vector2(unsigned int __x, unsigned int __y) { return ( simd_uint2){__x, __y}; } +static simd_float2 SIMD_CFUNC vector2(float __x, float __y) { return ( simd_float2){__x, __y}; } +static simd_long2 SIMD_CFUNC vector2(simd_long1 __x, simd_long1 __y) { return ( simd_long2){__x, __y}; } +static simd_ulong2 SIMD_CFUNC vector2(simd_ulong1 __x, simd_ulong1 __y) { return ( simd_ulong2){__x, __y}; } +static simd_double2 SIMD_CFUNC vector2(double __x, double __y) { return (simd_double2){__x, __y}; } + +static simd_char3 SIMD_CFUNC vector3(char __x, char __y, char __z) { return ( simd_char3){__x, __y, __z}; } +static simd_uchar3 SIMD_CFUNC vector3(unsigned char __x, unsigned char __y, unsigned char __z) { return ( simd_uchar3){__x, __y, __z}; } +static simd_short3 SIMD_CFUNC vector3(short __x, short __y, short __z) { return ( simd_short3){__x, __y, __z}; } +static simd_ushort3 SIMD_CFUNC vector3(unsigned short __x, unsigned short __y, unsigned short __z) { return (simd_ushort3){__x, __y, __z}; } +static simd_int3 SIMD_CFUNC vector3(int __x, int __y, int __z) { return ( simd_int3){__x, __y, __z}; } +static simd_uint3 SIMD_CFUNC vector3(unsigned int __x, unsigned int __y, unsigned int __z) { return ( simd_uint3){__x, __y, __z}; } +static simd_float3 SIMD_CFUNC vector3(float __x, float __y, float __z) { return ( simd_float3){__x, __y, __z}; } +static simd_long3 SIMD_CFUNC vector3(simd_long1 __x, simd_long1 __y, simd_long1 __z) { return ( simd_long3){__x, __y, __z}; } +static simd_ulong3 SIMD_CFUNC vector3(simd_ulong1 __x, simd_ulong1 __y, simd_ulong1 __z) { return ( simd_ulong3){__x, __y, __z}; } +static simd_double3 SIMD_CFUNC vector3(double __x, double __y, double __z) { return (simd_double3){__x, __y, __z}; } + +static simd_char3 SIMD_CFUNC vector3(simd_char2 __xy, char __z) { simd_char3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_uchar3 SIMD_CFUNC vector3(simd_uchar2 __xy, unsigned char __z) { simd_uchar3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_short3 SIMD_CFUNC vector3(simd_short2 __xy, short __z) { simd_short3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_ushort3 SIMD_CFUNC vector3(simd_ushort2 __xy, unsigned short __z) { simd_ushort3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_int3 SIMD_CFUNC vector3(simd_int2 __xy, int __z) { simd_int3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_uint3 SIMD_CFUNC vector3(simd_uint2 __xy, unsigned int __z) { simd_uint3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_float3 SIMD_CFUNC vector3(simd_float2 __xy, float __z) { simd_float3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_long3 SIMD_CFUNC vector3(simd_long2 __xy, simd_long1 __z) { simd_long3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_ulong3 SIMD_CFUNC vector3(simd_ulong2 __xy, simd_ulong1 __z) { simd_ulong3 __r; __r.xy = __xy; __r.z = __z; return __r; } +static simd_double3 SIMD_CFUNC vector3(simd_double2 __xy, double __z) { simd_double3 __r; __r.xy = __xy; __r.z = __z; return __r; } + +static simd_char4 SIMD_CFUNC vector4(char __x, char __y, char __z, char __w) { return ( simd_char4){__x, __y, __z, __w}; } +static simd_uchar4 SIMD_CFUNC vector4(unsigned char __x, unsigned char __y, unsigned char __z, unsigned char __w) { return ( simd_uchar4){__x, __y, __z, __w}; } +static simd_short4 SIMD_CFUNC vector4(short __x, short __y, short __z, short __w) { return ( simd_short4){__x, __y, __z, __w}; } +static simd_ushort4 SIMD_CFUNC vector4(unsigned short __x, unsigned short __y, unsigned short __z, unsigned short __w) { return (simd_ushort4){__x, __y, __z, __w}; } +static simd_int4 SIMD_CFUNC vector4(int __x, int __y, int __z, int __w) { return ( simd_int4){__x, __y, __z, __w}; } +static simd_uint4 SIMD_CFUNC vector4(unsigned int __x, unsigned int __y, unsigned int __z, unsigned int __w) { return ( simd_uint4){__x, __y, __z, __w}; } +static simd_float4 SIMD_CFUNC vector4(float __x, float __y, float __z, float __w) { return ( simd_float4){__x, __y, __z, __w}; } +static simd_long4 SIMD_CFUNC vector4(simd_long1 __x, simd_long1 __y, simd_long1 __z, simd_long1 __w) { return ( simd_long4){__x, __y, __z, __w}; } +static simd_ulong4 SIMD_CFUNC vector4(simd_ulong1 __x, simd_ulong1 __y, simd_ulong1 __z, simd_ulong1 __w) { return ( simd_ulong4){__x, __y, __z, __w}; } +static simd_double4 SIMD_CFUNC vector4(double __x, double __y, double __z, double __w) { return (simd_double4){__x, __y, __z, __w}; } + +static simd_char4 SIMD_CFUNC vector4(simd_char2 __xy, simd_char2 __zw) { simd_char4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_uchar4 SIMD_CFUNC vector4(simd_uchar2 __xy, simd_uchar2 __zw) { simd_uchar4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_short4 SIMD_CFUNC vector4(simd_short2 __xy, simd_short2 __zw) { simd_short4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_ushort4 SIMD_CFUNC vector4(simd_ushort2 __xy, simd_ushort2 __zw) { simd_ushort4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_int4 SIMD_CFUNC vector4(simd_int2 __xy, simd_int2 __zw) { simd_int4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_uint4 SIMD_CFUNC vector4(simd_uint2 __xy, simd_uint2 __zw) { simd_uint4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_float4 SIMD_CFUNC vector4(simd_float2 __xy, simd_float2 __zw) { simd_float4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_long4 SIMD_CFUNC vector4(simd_long2 __xy, simd_long2 __zw) { simd_long4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_ulong4 SIMD_CFUNC vector4(simd_ulong2 __xy, simd_ulong2 __zw) { simd_ulong4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } +static simd_double4 SIMD_CFUNC vector4(simd_double2 __xy, simd_double2 __zw) { simd_double4 __r; __r.xy = __xy; __r.zw = __zw; return __r; } + +static simd_char4 SIMD_CFUNC vector4(simd_char3 __xyz, char __w) { simd_char4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_uchar4 SIMD_CFUNC vector4(simd_uchar3 __xyz, unsigned char __w) { simd_uchar4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_short4 SIMD_CFUNC vector4(simd_short3 __xyz, short __w) { simd_short4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_ushort4 SIMD_CFUNC vector4(simd_ushort3 __xyz, unsigned short __w) { simd_ushort4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_int4 SIMD_CFUNC vector4(simd_int3 __xyz, int __w) { simd_int4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_uint4 SIMD_CFUNC vector4(simd_uint3 __xyz, unsigned int __w) { simd_uint4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_float4 SIMD_CFUNC vector4(simd_float3 __xyz, float __w) { simd_float4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_long4 SIMD_CFUNC vector4(simd_long3 __xyz, simd_long1 __w) { simd_long4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_ulong4 SIMD_CFUNC vector4(simd_ulong3 __xyz, simd_ulong1 __w) { simd_ulong4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } +static simd_double4 SIMD_CFUNC vector4(simd_double3 __xyz, double __w) { simd_double4 __r; __r.xyz = __xyz; __r.w = __w; return __r; } + +static simd_char8 SIMD_CFUNC vector8(simd_char4 __lo, simd_char4 __hi) { simd_char8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_uchar8 SIMD_CFUNC vector8(simd_uchar4 __lo, simd_uchar4 __hi) { simd_uchar8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_short8 SIMD_CFUNC vector8(simd_short4 __lo, simd_short4 __hi) { simd_short8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_ushort8 SIMD_CFUNC vector8(simd_ushort4 __lo, simd_ushort4 __hi) { simd_ushort8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_int8 SIMD_CFUNC vector8(simd_int4 __lo, simd_int4 __hi) { simd_int8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_uint8 SIMD_CFUNC vector8(simd_uint4 __lo, simd_uint4 __hi) { simd_uint8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_float8 SIMD_CFUNC vector8(simd_float4 __lo, simd_float4 __hi) { simd_float8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_long8 SIMD_CFUNC vector8(simd_long4 __lo, simd_long4 __hi) { simd_long8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_ulong8 SIMD_CFUNC vector8(simd_ulong4 __lo, simd_ulong4 __hi) { simd_ulong8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_double8 SIMD_CFUNC vector8(simd_double4 __lo, simd_double4 __hi) { simd_double8 __r; __r.lo = __lo; __r.hi = __hi; return __r; } + +static simd_char16 SIMD_CFUNC vector16(simd_char8 __lo, simd_char8 __hi) { simd_char16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_uchar16 SIMD_CFUNC vector16(simd_uchar8 __lo, simd_uchar8 __hi) { simd_uchar16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_short16 SIMD_CFUNC vector16(simd_short8 __lo, simd_short8 __hi) { simd_short16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_ushort16 SIMD_CFUNC vector16(simd_ushort8 __lo, simd_ushort8 __hi) { simd_ushort16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_int16 SIMD_CFUNC vector16(simd_int8 __lo, simd_int8 __hi) { simd_int16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_uint16 SIMD_CFUNC vector16(simd_uint8 __lo, simd_uint8 __hi) { simd_uint16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_float16 SIMD_CFUNC vector16(simd_float8 __lo, simd_float8 __hi) { simd_float16 __r; __r.lo = __lo; __r.hi = __hi; return __r; } + +static simd_char32 SIMD_CFUNC vector32(simd_char16 __lo, simd_char16 __hi) { simd_char32 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_uchar32 SIMD_CFUNC vector32(simd_uchar16 __lo, simd_uchar16 __hi) { simd_uchar32 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_short32 SIMD_CFUNC vector32(simd_short16 __lo, simd_short16 __hi) { simd_short32 __r; __r.lo = __lo; __r.hi = __hi; return __r; } +static simd_ushort32 SIMD_CFUNC vector32(simd_ushort16 __lo, simd_ushort16 __hi) { simd_ushort32 __r; __r.lo = __lo; __r.hi = __hi; return __r; } + +#pragma mark - Implementation + +static simd_char2 SIMD_CFUNC simd_char(simd_char2 __x) { return __x; } +static simd_char3 SIMD_CFUNC simd_char(simd_char3 __x) { return __x; } +static simd_char4 SIMD_CFUNC simd_char(simd_char4 __x) { return __x; } +static simd_char8 SIMD_CFUNC simd_char(simd_char8 __x) { return __x; } +static simd_char16 SIMD_CFUNC simd_char(simd_char16 __x) { return __x; } +static simd_char32 SIMD_CFUNC simd_char(simd_char32 __x) { return __x; } +static simd_char2 SIMD_CFUNC simd_char(simd_uchar2 __x) { return (simd_char2)__x; } +static simd_char3 SIMD_CFUNC simd_char(simd_uchar3 __x) { return (simd_char3)__x; } +static simd_char4 SIMD_CFUNC simd_char(simd_uchar4 __x) { return (simd_char4)__x; } +static simd_char8 SIMD_CFUNC simd_char(simd_uchar8 __x) { return (simd_char8)__x; } +static simd_char16 SIMD_CFUNC simd_char(simd_uchar16 __x) { return (simd_char16)__x; } +static simd_char32 SIMD_CFUNC simd_char(simd_uchar32 __x) { return (simd_char32)__x; } +static simd_char2 SIMD_CFUNC simd_char(simd_short2 __x) { return __builtin_convertvector(__x & 0xff, simd_char2); } +static simd_char3 SIMD_CFUNC simd_char(simd_short3 __x) { return __builtin_convertvector(__x & 0xff, simd_char3); } +static simd_char4 SIMD_CFUNC simd_char(simd_short4 __x) { return __builtin_convertvector(__x & 0xff, simd_char4); } +static simd_char8 SIMD_CFUNC simd_char(simd_short8 __x) { return __builtin_convertvector(__x & 0xff, simd_char8); } +static simd_char16 SIMD_CFUNC simd_char(simd_short16 __x) { return __builtin_convertvector(__x & 0xff, simd_char16); } +static simd_char32 SIMD_CFUNC simd_char(simd_short32 __x) { return __builtin_convertvector(__x & 0xff, simd_char32); } +static simd_char2 SIMD_CFUNC simd_char(simd_ushort2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_ushort3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_ushort4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_ushort8 __x) { return simd_char(simd_short(__x)); } +static simd_char16 SIMD_CFUNC simd_char(simd_ushort16 __x) { return simd_char(simd_short(__x)); } +static simd_char32 SIMD_CFUNC simd_char(simd_ushort32 __x) { return simd_char(simd_short(__x)); } +static simd_char2 SIMD_CFUNC simd_char(simd_int2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_int3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_int4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_int8 __x) { return simd_char(simd_short(__x)); } +static simd_char16 SIMD_CFUNC simd_char(simd_int16 __x) { return simd_char(simd_short(__x)); } +static simd_char2 SIMD_CFUNC simd_char(simd_uint2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_uint3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_uint4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_uint8 __x) { return simd_char(simd_short(__x)); } +static simd_char16 SIMD_CFUNC simd_char(simd_uint16 __x) { return simd_char(simd_short(__x)); } +static simd_char2 SIMD_CFUNC simd_char(simd_float2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_float3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_float4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_float8 __x) { return simd_char(simd_short(__x)); } +static simd_char16 SIMD_CFUNC simd_char(simd_float16 __x) { return simd_char(simd_short(__x)); } +static simd_char2 SIMD_CFUNC simd_char(simd_long2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_long3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_long4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_long8 __x) { return simd_char(simd_short(__x)); } +static simd_char2 SIMD_CFUNC simd_char(simd_ulong2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_ulong3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_ulong4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_ulong8 __x) { return simd_char(simd_short(__x)); } +static simd_char2 SIMD_CFUNC simd_char(simd_double2 __x) { return simd_char(simd_short(__x)); } +static simd_char3 SIMD_CFUNC simd_char(simd_double3 __x) { return simd_char(simd_short(__x)); } +static simd_char4 SIMD_CFUNC simd_char(simd_double4 __x) { return simd_char(simd_short(__x)); } +static simd_char8 SIMD_CFUNC simd_char(simd_double8 __x) { return simd_char(simd_short(__x)); } + +static simd_char2 SIMD_CFUNC simd_char_sat(simd_char2 __x) { return __x; } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_char3 __x) { return __x; } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_char4 __x) { return __x; } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_char8 __x) { return __x; } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_char16 __x) { return __x; } +static simd_char32 SIMD_CFUNC simd_char_sat(simd_char32 __x) { return __x; } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_short2 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_short3 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_short4 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_short8 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_short16 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char32 SIMD_CFUNC simd_char_sat(simd_short32 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_int2 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_int3 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_int4 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_int8 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_int16 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_float2 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_float3 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_float4 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_float8 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_float16 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_long2 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_long3 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_long4 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_long8 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_double2 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_double3 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_double4 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_double8 __x) { return simd_char(simd_clamp(__x,-0x80,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_uchar2 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_uchar3 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_uchar4 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_uchar8 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_uchar16 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char32 SIMD_CFUNC simd_char_sat(simd_uchar32 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_ushort2 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_ushort3 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_ushort4 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_ushort8 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_ushort16 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char32 SIMD_CFUNC simd_char_sat(simd_ushort32 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_uint2 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_uint3 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_uint4 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_uint8 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char16 SIMD_CFUNC simd_char_sat(simd_uint16 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char2 SIMD_CFUNC simd_char_sat(simd_ulong2 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char3 SIMD_CFUNC simd_char_sat(simd_ulong3 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char4 SIMD_CFUNC simd_char_sat(simd_ulong4 __x) { return simd_char(simd_min(__x,0x7f)); } +static simd_char8 SIMD_CFUNC simd_char_sat(simd_ulong8 __x) { return simd_char(simd_min(__x,0x7f)); } + + +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_char2 __x) { return (simd_uchar2)__x; } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_char3 __x) { return (simd_uchar3)__x; } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_char4 __x) { return (simd_uchar4)__x; } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_char8 __x) { return (simd_uchar8)__x; } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_char16 __x) { return (simd_uchar16)__x; } +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_char32 __x) { return (simd_uchar32)__x; } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_uchar2 __x) { return __x; } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_uchar3 __x) { return __x; } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_uchar4 __x) { return __x; } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_uchar8 __x) { return __x; } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_uchar16 __x) { return __x; } +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_uchar32 __x) { return __x; } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_short2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_short3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_short4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_short8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_short16 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_short32 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_ushort2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_ushort3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_ushort4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_ushort8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_ushort16 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar32 SIMD_CFUNC simd_uchar(simd_ushort32 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_int2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_int3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_int4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_int8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_int16 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_uint2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_uint3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_uint4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_uint8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_uint16 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_float2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_float3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_float4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_float8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar16 SIMD_CFUNC simd_uchar(simd_float16 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_long2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_long3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_long4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_long8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_ulong2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_ulong3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_ulong4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_ulong8 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar(simd_double2 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar(simd_double3 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar(simd_double4 __x) { return simd_uchar(simd_char(__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar(simd_double8 __x) { return simd_uchar(simd_char(__x)); } + +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_char2 __x) { return simd_uchar(simd_max(0,__x)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_char3 __x) { return simd_uchar(simd_max(0,__x)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_char4 __x) { return simd_uchar(simd_max(0,__x)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_char8 __x) { return simd_uchar(simd_max(0,__x)); } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_char16 __x) { return simd_uchar(simd_max(0,__x)); } +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_char32 __x) { return simd_uchar(simd_max(0,__x)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_short2 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_short3 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_short4 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_short8 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_short16 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_short32 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_int2 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_int3 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_int4 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_int8 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_int16 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_float2 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_float3 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_float4 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_float8 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_float16 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_long2 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_long3 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_long4 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_long8 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_double2 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_double3 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_double4 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_double8 __x) { return simd_uchar(simd_clamp(__x,0,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_uchar2 __x) { return __x; } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_uchar3 __x) { return __x; } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_uchar4 __x) { return __x; } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_uchar8 __x) { return __x; } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_uchar16 __x) { return __x; } +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_uchar32 __x) { return __x; } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_ushort2 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_ushort3 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_ushort4 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_ushort8 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_ushort16 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar32 SIMD_CFUNC simd_uchar_sat(simd_ushort32 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_uint2 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_uint3 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_uint4 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_uint8 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar16 SIMD_CFUNC simd_uchar_sat(simd_uint16 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar2 SIMD_CFUNC simd_uchar_sat(simd_ulong2 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar3 SIMD_CFUNC simd_uchar_sat(simd_ulong3 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar4 SIMD_CFUNC simd_uchar_sat(simd_ulong4 __x) { return simd_uchar(simd_min(__x,0xff)); } +static simd_uchar8 SIMD_CFUNC simd_uchar_sat(simd_ulong8 __x) { return simd_uchar(simd_min(__x,0xff)); } + + +static simd_short2 SIMD_CFUNC simd_short(simd_char2 __x) { return __builtin_convertvector(__x, simd_short2); } +static simd_short3 SIMD_CFUNC simd_short(simd_char3 __x) { return __builtin_convertvector(__x, simd_short3); } +static simd_short4 SIMD_CFUNC simd_short(simd_char4 __x) { return __builtin_convertvector(__x, simd_short4); } +static simd_short8 SIMD_CFUNC simd_short(simd_char8 __x) { return __builtin_convertvector(__x, simd_short8); } +static simd_short16 SIMD_CFUNC simd_short(simd_char16 __x) { return __builtin_convertvector(__x, simd_short16); } +static simd_short32 SIMD_CFUNC simd_short(simd_char32 __x) { return __builtin_convertvector(__x, simd_short32); } +static simd_short2 SIMD_CFUNC simd_short(simd_uchar2 __x) { return __builtin_convertvector(__x, simd_short2); } +static simd_short3 SIMD_CFUNC simd_short(simd_uchar3 __x) { return __builtin_convertvector(__x, simd_short3); } +static simd_short4 SIMD_CFUNC simd_short(simd_uchar4 __x) { return __builtin_convertvector(__x, simd_short4); } +static simd_short8 SIMD_CFUNC simd_short(simd_uchar8 __x) { return __builtin_convertvector(__x, simd_short8); } +static simd_short16 SIMD_CFUNC simd_short(simd_uchar16 __x) { return __builtin_convertvector(__x, simd_short16); } +static simd_short32 SIMD_CFUNC simd_short(simd_uchar32 __x) { return __builtin_convertvector(__x, simd_short32); } +static simd_short2 SIMD_CFUNC simd_short(simd_short2 __x) { return __x; } +static simd_short3 SIMD_CFUNC simd_short(simd_short3 __x) { return __x; } +static simd_short4 SIMD_CFUNC simd_short(simd_short4 __x) { return __x; } +static simd_short8 SIMD_CFUNC simd_short(simd_short8 __x) { return __x; } +static simd_short16 SIMD_CFUNC simd_short(simd_short16 __x) { return __x; } +static simd_short32 SIMD_CFUNC simd_short(simd_short32 __x) { return __x; } +static simd_short2 SIMD_CFUNC simd_short(simd_ushort2 __x) { return (simd_short2)__x; } +static simd_short3 SIMD_CFUNC simd_short(simd_ushort3 __x) { return (simd_short3)__x; } +static simd_short4 SIMD_CFUNC simd_short(simd_ushort4 __x) { return (simd_short4)__x; } +static simd_short8 SIMD_CFUNC simd_short(simd_ushort8 __x) { return (simd_short8)__x; } +static simd_short16 SIMD_CFUNC simd_short(simd_ushort16 __x) { return (simd_short16)__x; } +static simd_short32 SIMD_CFUNC simd_short(simd_ushort32 __x) { return (simd_short32)__x; } +static simd_short2 SIMD_CFUNC simd_short(simd_int2 __x) { return __builtin_convertvector(__x & 0xffff, simd_short2); } +static simd_short3 SIMD_CFUNC simd_short(simd_int3 __x) { return __builtin_convertvector(__x & 0xffff, simd_short3); } +static simd_short4 SIMD_CFUNC simd_short(simd_int4 __x) { return __builtin_convertvector(__x & 0xffff, simd_short4); } +static simd_short8 SIMD_CFUNC simd_short(simd_int8 __x) { return __builtin_convertvector(__x & 0xffff, simd_short8); } +static simd_short16 SIMD_CFUNC simd_short(simd_int16 __x) { return __builtin_convertvector(__x & 0xffff, simd_short16); } +static simd_short2 SIMD_CFUNC simd_short(simd_uint2 __x) { return simd_short(simd_int(__x)); } +static simd_short3 SIMD_CFUNC simd_short(simd_uint3 __x) { return simd_short(simd_int(__x)); } +static simd_short4 SIMD_CFUNC simd_short(simd_uint4 __x) { return simd_short(simd_int(__x)); } +static simd_short8 SIMD_CFUNC simd_short(simd_uint8 __x) { return simd_short(simd_int(__x)); } +static simd_short16 SIMD_CFUNC simd_short(simd_uint16 __x) { return simd_short(simd_int(__x)); } +static simd_short2 SIMD_CFUNC simd_short(simd_float2 __x) { return simd_short(simd_int(__x)); } +static simd_short3 SIMD_CFUNC simd_short(simd_float3 __x) { return simd_short(simd_int(__x)); } +static simd_short4 SIMD_CFUNC simd_short(simd_float4 __x) { return simd_short(simd_int(__x)); } +static simd_short8 SIMD_CFUNC simd_short(simd_float8 __x) { return simd_short(simd_int(__x)); } +static simd_short16 SIMD_CFUNC simd_short(simd_float16 __x) { return simd_short(simd_int(__x)); } +static simd_short2 SIMD_CFUNC simd_short(simd_long2 __x) { return simd_short(simd_int(__x)); } +static simd_short3 SIMD_CFUNC simd_short(simd_long3 __x) { return simd_short(simd_int(__x)); } +static simd_short4 SIMD_CFUNC simd_short(simd_long4 __x) { return simd_short(simd_int(__x)); } +static simd_short8 SIMD_CFUNC simd_short(simd_long8 __x) { return simd_short(simd_int(__x)); } +static simd_short2 SIMD_CFUNC simd_short(simd_ulong2 __x) { return simd_short(simd_int(__x)); } +static simd_short3 SIMD_CFUNC simd_short(simd_ulong3 __x) { return simd_short(simd_int(__x)); } +static simd_short4 SIMD_CFUNC simd_short(simd_ulong4 __x) { return simd_short(simd_int(__x)); } +static simd_short8 SIMD_CFUNC simd_short(simd_ulong8 __x) { return simd_short(simd_int(__x)); } +static simd_short2 SIMD_CFUNC simd_short(simd_double2 __x) { return simd_short(simd_int(__x)); } +static simd_short3 SIMD_CFUNC simd_short(simd_double3 __x) { return simd_short(simd_int(__x)); } +static simd_short4 SIMD_CFUNC simd_short(simd_double4 __x) { return simd_short(simd_int(__x)); } +static simd_short8 SIMD_CFUNC simd_short(simd_double8 __x) { return simd_short(simd_int(__x)); } + +static simd_short2 SIMD_CFUNC simd_short_sat(simd_char2 __x) { return simd_short(__x); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_char3 __x) { return simd_short(__x); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_char4 __x) { return simd_short(__x); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_char8 __x) { return simd_short(__x); } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_char16 __x) { return simd_short(__x); } +static simd_short32 SIMD_CFUNC simd_short_sat(simd_char32 __x) { return simd_short(__x); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_short2 __x) { return __x; } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_short3 __x) { return __x; } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_short4 __x) { return __x; } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_short8 __x) { return __x; } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_short16 __x) { return __x; } +static simd_short32 SIMD_CFUNC simd_short_sat(simd_short32 __x) { return __x; } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_int2 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_int3 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_int4 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_int8 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_int16 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_float2 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_float3 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_float4 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_float8 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_float16 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_long2 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_long3 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_long4 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_long8 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_double2 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_double3 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_double4 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_double8 __x) { return simd_short(simd_clamp(__x,-0x8000,0x7fff)); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_uchar2 __x) { return simd_short(__x); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_uchar3 __x) { return simd_short(__x); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_uchar4 __x) { return simd_short(__x); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_uchar8 __x) { return simd_short(__x); } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_uchar16 __x) { return simd_short(__x); } +static simd_short32 SIMD_CFUNC simd_short_sat(simd_uchar32 __x) { return simd_short(__x); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_ushort2 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_ushort3 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_ushort4 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_ushort8 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_ushort16 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short32 SIMD_CFUNC simd_short_sat(simd_ushort32 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_uint2 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_uint3 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_uint4 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_uint8 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short16 SIMD_CFUNC simd_short_sat(simd_uint16 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short2 SIMD_CFUNC simd_short_sat(simd_ulong2 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short3 SIMD_CFUNC simd_short_sat(simd_ulong3 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short4 SIMD_CFUNC simd_short_sat(simd_ulong4 __x) { return simd_short(simd_min(__x,0x7fff)); } +static simd_short8 SIMD_CFUNC simd_short_sat(simd_ulong8 __x) { return simd_short(simd_min(__x,0x7fff)); } + + +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_char2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_char3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_char4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_char8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_char16 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_char32 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_uchar2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_uchar3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_uchar4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_uchar8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_uchar16 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_uchar32 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_short2 __x) { return (simd_ushort2)__x; } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_short3 __x) { return (simd_ushort3)__x; } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_short4 __x) { return (simd_ushort4)__x; } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_short8 __x) { return (simd_ushort8)__x; } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_short16 __x) { return (simd_ushort16)__x; } +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_short32 __x) { return (simd_ushort32)__x; } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_ushort2 __x) { return __x; } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_ushort3 __x) { return __x; } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_ushort4 __x) { return __x; } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_ushort8 __x) { return __x; } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_ushort16 __x) { return __x; } +static simd_ushort32 SIMD_CFUNC simd_ushort(simd_ushort32 __x) { return __x; } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_int2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_int3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_int4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_int8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_int16 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_uint2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_uint3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_uint4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_uint8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_uint16 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_float2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_float3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_float4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_float8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort16 SIMD_CFUNC simd_ushort(simd_float16 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_long2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_long3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_long4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_long8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_ulong2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_ulong3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_ulong4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_ulong8 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort2 SIMD_CFUNC simd_ushort(simd_double2 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort3 SIMD_CFUNC simd_ushort(simd_double3 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort4 SIMD_CFUNC simd_ushort(simd_double4 __x) { return simd_ushort(simd_short(__x)); } +static simd_ushort8 SIMD_CFUNC simd_ushort(simd_double8 __x) { return simd_ushort(simd_short(__x)); } + +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_char2 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_char3 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_char4 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_char8 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_char16 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_char32 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_short2 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_short3 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_short4 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_short8 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_short16 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_short32 __x) { return simd_ushort(simd_max(__x, 0)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_int2 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_int3 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_int4 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_int8 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_int16 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_float2 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_float3 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_float4 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_float8 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_float16 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_long2 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_long3 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_long4 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_long8 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_double2 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_double3 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_double4 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_double8 __x) { return simd_ushort(simd_clamp(__x, 0, 0xffff)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_uchar2 __x) { return simd_ushort(__x); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_uchar3 __x) { return simd_ushort(__x); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_uchar4 __x) { return simd_ushort(__x); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_uchar8 __x) { return simd_ushort(__x); } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_uchar16 __x) { return simd_ushort(__x); } +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_uchar32 __x) { return simd_ushort(__x); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_ushort2 __x) { return __x; } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_ushort3 __x) { return __x; } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_ushort4 __x) { return __x; } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_ushort8 __x) { return __x; } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_ushort16 __x) { return __x; } +static simd_ushort32 SIMD_CFUNC simd_ushort_sat(simd_ushort32 __x) { return __x; } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_uint2 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_uint3 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_uint4 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_uint8 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort16 SIMD_CFUNC simd_ushort_sat(simd_uint16 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort2 SIMD_CFUNC simd_ushort_sat(simd_ulong2 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort3 SIMD_CFUNC simd_ushort_sat(simd_ulong3 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort4 SIMD_CFUNC simd_ushort_sat(simd_ulong4 __x) { return simd_ushort(simd_min(__x, 0xffff)); } +static simd_ushort8 SIMD_CFUNC simd_ushort_sat(simd_ulong8 __x) { return simd_ushort(simd_min(__x, 0xffff)); } + + +static simd_int2 SIMD_CFUNC simd_int(simd_char2 __x) { return __builtin_convertvector(__x, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_char3 __x) { return __builtin_convertvector(__x, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_char4 __x) { return __builtin_convertvector(__x, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_char8 __x) { return __builtin_convertvector(__x, simd_int8); } +static simd_int16 SIMD_CFUNC simd_int(simd_char16 __x) { return __builtin_convertvector(__x, simd_int16); } +static simd_int2 SIMD_CFUNC simd_int(simd_uchar2 __x) { return __builtin_convertvector(__x, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_uchar3 __x) { return __builtin_convertvector(__x, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_uchar4 __x) { return __builtin_convertvector(__x, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_uchar8 __x) { return __builtin_convertvector(__x, simd_int8); } +static simd_int16 SIMD_CFUNC simd_int(simd_uchar16 __x) { return __builtin_convertvector(__x, simd_int16); } +static simd_int2 SIMD_CFUNC simd_int(simd_short2 __x) { return __builtin_convertvector(__x, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_short3 __x) { return __builtin_convertvector(__x, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_short4 __x) { return __builtin_convertvector(__x, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_short8 __x) { return __builtin_convertvector(__x, simd_int8); } +static simd_int16 SIMD_CFUNC simd_int(simd_short16 __x) { return __builtin_convertvector(__x, simd_int16); } +static simd_int2 SIMD_CFUNC simd_int(simd_ushort2 __x) { return __builtin_convertvector(__x, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_ushort3 __x) { return __builtin_convertvector(__x, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_ushort4 __x) { return __builtin_convertvector(__x, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_ushort8 __x) { return __builtin_convertvector(__x, simd_int8); } +static simd_int16 SIMD_CFUNC simd_int(simd_ushort16 __x) { return __builtin_convertvector(__x, simd_int16); } +static simd_int2 SIMD_CFUNC simd_int(simd_int2 __x) { return __x; } +static simd_int3 SIMD_CFUNC simd_int(simd_int3 __x) { return __x; } +static simd_int4 SIMD_CFUNC simd_int(simd_int4 __x) { return __x; } +static simd_int8 SIMD_CFUNC simd_int(simd_int8 __x) { return __x; } +static simd_int16 SIMD_CFUNC simd_int(simd_int16 __x) { return __x; } +static simd_int2 SIMD_CFUNC simd_int(simd_uint2 __x) { return (simd_int2)__x; } +static simd_int3 SIMD_CFUNC simd_int(simd_uint3 __x) { return (simd_int3)__x; } +static simd_int4 SIMD_CFUNC simd_int(simd_uint4 __x) { return (simd_int4)__x; } +static simd_int8 SIMD_CFUNC simd_int(simd_uint8 __x) { return (simd_int8)__x; } +static simd_int16 SIMD_CFUNC simd_int(simd_uint16 __x) { return (simd_int16)__x; } +static simd_int2 SIMD_CFUNC simd_int(simd_float2 __x) { return __builtin_convertvector(__x, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_float3 __x) { return __builtin_convertvector(__x, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_float4 __x) { return __builtin_convertvector(__x, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_float8 __x) { return __builtin_convertvector(__x, simd_int8); } +static simd_int16 SIMD_CFUNC simd_int(simd_float16 __x) { return __builtin_convertvector(__x, simd_int16); } +static simd_int2 SIMD_CFUNC simd_int(simd_long2 __x) { return __builtin_convertvector(__x & 0xffffffff, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_long3 __x) { return __builtin_convertvector(__x & 0xffffffff, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_long4 __x) { return __builtin_convertvector(__x & 0xffffffff, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_long8 __x) { return __builtin_convertvector(__x & 0xffffffff, simd_int8); } +static simd_int2 SIMD_CFUNC simd_int(simd_ulong2 __x) { return simd_int(simd_long(__x)); } +static simd_int3 SIMD_CFUNC simd_int(simd_ulong3 __x) { return simd_int(simd_long(__x)); } +static simd_int4 SIMD_CFUNC simd_int(simd_ulong4 __x) { return simd_int(simd_long(__x)); } +static simd_int8 SIMD_CFUNC simd_int(simd_ulong8 __x) { return simd_int(simd_long(__x)); } +static simd_int2 SIMD_CFUNC simd_int(simd_double2 __x) { return __builtin_convertvector(__x, simd_int2); } +static simd_int3 SIMD_CFUNC simd_int(simd_double3 __x) { return __builtin_convertvector(__x, simd_int3); } +static simd_int4 SIMD_CFUNC simd_int(simd_double4 __x) { return __builtin_convertvector(__x, simd_int4); } +static simd_int8 SIMD_CFUNC simd_int(simd_double8 __x) { return __builtin_convertvector(__x, simd_int8); } + +static simd_int2 SIMD_CFUNC simd_int_sat(simd_char2 __x) { return simd_int(__x); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_char3 __x) { return simd_int(__x); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_char4 __x) { return simd_int(__x); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_char8 __x) { return simd_int(__x); } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_char16 __x) { return simd_int(__x); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_short2 __x) { return simd_int(__x); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_short3 __x) { return simd_int(__x); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_short4 __x) { return simd_int(__x); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_short8 __x) { return simd_int(__x); } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_short16 __x) { return simd_int(__x); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_int2 __x) { return __x; } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_int3 __x) { return __x; } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_int4 __x) { return __x; } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_int8 __x) { return __x; } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_int16 __x) { return __x; } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_float2 __x) { return simd_bitselect(simd_int(simd_max(__x,-0x1.0p31f)), 0x7fffffff, __x >= 0x1.0p31f); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_float3 __x) { return simd_bitselect(simd_int(simd_max(__x,-0x1.0p31f)), 0x7fffffff, __x >= 0x1.0p31f); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_float4 __x) { return simd_bitselect(simd_int(simd_max(__x,-0x1.0p31f)), 0x7fffffff, __x >= 0x1.0p31f); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_float8 __x) { return simd_bitselect(simd_int(simd_max(__x,-0x1.0p31f)), 0x7fffffff, __x >= 0x1.0p31f); } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_float16 __x) { return simd_bitselect(simd_int(simd_max(__x,-0x1.0p31f)), 0x7fffffff, __x >= 0x1.0p31f); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_long2 __x) { return simd_int(simd_clamp(__x,-0x80000000LL,0x7fffffffLL)); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_long3 __x) { return simd_int(simd_clamp(__x,-0x80000000LL,0x7fffffffLL)); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_long4 __x) { return simd_int(simd_clamp(__x,-0x80000000LL,0x7fffffffLL)); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_long8 __x) { return simd_int(simd_clamp(__x,-0x80000000LL,0x7fffffffLL)); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_double2 __x) { return simd_int(simd_clamp(__x,-0x1.0p31,0x1.fffffffcp30)); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_double3 __x) { return simd_int(simd_clamp(__x,-0x1.0p31,0x1.fffffffcp30)); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_double4 __x) { return simd_int(simd_clamp(__x,-0x1.0p31,0x1.fffffffcp30)); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_double8 __x) { return simd_int(simd_clamp(__x,-0x1.0p31,0x1.fffffffcp30)); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_uchar2 __x) { return simd_int(__x); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_uchar3 __x) { return simd_int(__x); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_uchar4 __x) { return simd_int(__x); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_uchar8 __x) { return simd_int(__x); } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_uchar16 __x) { return simd_int(__x); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_ushort2 __x) { return simd_int(__x); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_ushort3 __x) { return simd_int(__x); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_ushort4 __x) { return simd_int(__x); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_ushort8 __x) { return simd_int(__x); } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_ushort16 __x) { return simd_int(__x); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_uint2 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_uint3 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_uint4 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_uint8 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int16 SIMD_CFUNC simd_int_sat(simd_uint16 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int2 SIMD_CFUNC simd_int_sat(simd_ulong2 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int3 SIMD_CFUNC simd_int_sat(simd_ulong3 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int4 SIMD_CFUNC simd_int_sat(simd_ulong4 __x) { return simd_int(simd_min(__x,0x7fffffff)); } +static simd_int8 SIMD_CFUNC simd_int_sat(simd_ulong8 __x) { return simd_int(simd_min(__x,0x7fffffff)); } + +static simd_int2 SIMD_CFUNC simd_int_rte(simd_float2 __x) { +#if defined __arm64__ + return vcvtn_s32_f32(__x); +#else + return simd_make_int2(simd_int_rte(simd_make_float4_undef(__x))); +#endif +} + +static simd_int3 SIMD_CFUNC simd_int_rte(simd_float3 __x) { + return simd_make_int3(simd_int_rte(simd_make_float4_undef(__x))); +} + +static simd_int4 SIMD_CFUNC simd_int_rte(simd_float4 __x) { +#if defined __SSE2__ + return _mm_cvtps_epi32(__x); +#elif defined __arm64__ + return vcvtnq_s32_f32(__x); +#else + simd_float4 magic = __tg_copysign(0x1.0p23, __x); + simd_int4 x_is_small = __tg_fabs(__x) < 0x1.0p23; + return __builtin_convertvector(simd_bitselect(__x, (__x + magic) - magic, x_is_small & 0x7fffffff), simd_int4); +#endif +} + +static simd_int8 SIMD_CFUNC simd_int_rte(simd_float8 __x) { +#if defined __AVX__ + return _mm256_cvtps_epi32(__x); +#else + return simd_make_int8(simd_int_rte(__x.lo), simd_int_rte(__x.hi)); +#endif +} + +static simd_int16 SIMD_CFUNC simd_int_rte(simd_float16 __x) { +#if defined __AVX512F__ + return _mm512_cvt_roundps_epi32(__x, _MM_FROUND_RINT); +#else + return simd_make_int16(simd_int_rte(__x.lo), simd_int_rte(__x.hi)); +#endif +} + +static simd_uint2 SIMD_CFUNC simd_uint(simd_char2 __x) { return simd_uint(simd_int(__x)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_char3 __x) { return simd_uint(simd_int(__x)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_char4 __x) { return simd_uint(simd_int(__x)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_char8 __x) { return simd_uint(simd_int(__x)); } +static simd_uint16 SIMD_CFUNC simd_uint(simd_char16 __x) { return simd_uint(simd_int(__x)); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_uchar2 __x) { return simd_uint(simd_int(__x)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_uchar3 __x) { return simd_uint(simd_int(__x)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_uchar4 __x) { return simd_uint(simd_int(__x)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_uchar8 __x) { return simd_uint(simd_int(__x)); } +static simd_uint16 SIMD_CFUNC simd_uint(simd_uchar16 __x) { return simd_uint(simd_int(__x)); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_short2 __x) { return simd_uint(simd_int(__x)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_short3 __x) { return simd_uint(simd_int(__x)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_short4 __x) { return simd_uint(simd_int(__x)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_short8 __x) { return simd_uint(simd_int(__x)); } +static simd_uint16 SIMD_CFUNC simd_uint(simd_short16 __x) { return simd_uint(simd_int(__x)); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_ushort2 __x) { return simd_uint(simd_int(__x)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_ushort3 __x) { return simd_uint(simd_int(__x)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_ushort4 __x) { return simd_uint(simd_int(__x)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_ushort8 __x) { return simd_uint(simd_int(__x)); } +static simd_uint16 SIMD_CFUNC simd_uint(simd_ushort16 __x) { return simd_uint(simd_int(__x)); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_int2 __x) { return (simd_uint2)__x; } +static simd_uint3 SIMD_CFUNC simd_uint(simd_int3 __x) { return (simd_uint3)__x; } +static simd_uint4 SIMD_CFUNC simd_uint(simd_int4 __x) { return (simd_uint4)__x; } +static simd_uint8 SIMD_CFUNC simd_uint(simd_int8 __x) { return (simd_uint8)__x; } +static simd_uint16 SIMD_CFUNC simd_uint(simd_int16 __x) { return (simd_uint16)__x; } +static simd_uint2 SIMD_CFUNC simd_uint(simd_uint2 __x) { return __x; } +static simd_uint3 SIMD_CFUNC simd_uint(simd_uint3 __x) { return __x; } +static simd_uint4 SIMD_CFUNC simd_uint(simd_uint4 __x) { return __x; } +static simd_uint8 SIMD_CFUNC simd_uint(simd_uint8 __x) { return __x; } +static simd_uint16 SIMD_CFUNC simd_uint(simd_uint16 __x) { return __x; } +static simd_uint2 SIMD_CFUNC simd_uint(simd_float2 __x) { simd_int2 __big = __x > 0x1.0p31f; return simd_uint(simd_int(__x - simd_bitselect((simd_float2)0,0x1.0p31f,__big))) + simd_bitselect((simd_uint2)0,0x80000000,__big); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_float3 __x) { simd_int3 __big = __x > 0x1.0p31f; return simd_uint(simd_int(__x - simd_bitselect((simd_float3)0,0x1.0p31f,__big))) + simd_bitselect((simd_uint3)0,0x80000000,__big); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_float4 __x) { simd_int4 __big = __x > 0x1.0p31f; return simd_uint(simd_int(__x - simd_bitselect((simd_float4)0,0x1.0p31f,__big))) + simd_bitselect((simd_uint4)0,0x80000000,__big); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_float8 __x) { simd_int8 __big = __x > 0x1.0p31f; return simd_uint(simd_int(__x - simd_bitselect((simd_float8)0,0x1.0p31f,__big))) + simd_bitselect((simd_uint8)0,0x80000000,__big); } +static simd_uint16 SIMD_CFUNC simd_uint(simd_float16 __x) { simd_int16 __big = __x > 0x1.0p31f; return simd_uint(simd_int(__x - simd_bitselect((simd_float16)0,0x1.0p31f,__big))) + simd_bitselect((simd_uint16)0,0x80000000,__big); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_long2 __x) { return simd_uint(simd_int(__x)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_long3 __x) { return simd_uint(simd_int(__x)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_long4 __x) { return simd_uint(simd_int(__x)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_long8 __x) { return simd_uint(simd_int(__x)); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_ulong2 __x) { return simd_uint(simd_int(__x)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_ulong3 __x) { return simd_uint(simd_int(__x)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_ulong4 __x) { return simd_uint(simd_int(__x)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_ulong8 __x) { return simd_uint(simd_int(__x)); } +static simd_uint2 SIMD_CFUNC simd_uint(simd_double2 __x) { simd_long2 __big = __x > 0x1.fffffffcp30; return simd_uint(simd_int(__x - simd_bitselect((simd_double2)0,0x1.0p31,__big))) + simd_bitselect((simd_uint2)0,0x80000000,simd_int(__big)); } +static simd_uint3 SIMD_CFUNC simd_uint(simd_double3 __x) { simd_long3 __big = __x > 0x1.fffffffcp30; return simd_uint(simd_int(__x - simd_bitselect((simd_double3)0,0x1.0p31,__big))) + simd_bitselect((simd_uint3)0,0x80000000,simd_int(__big)); } +static simd_uint4 SIMD_CFUNC simd_uint(simd_double4 __x) { simd_long4 __big = __x > 0x1.fffffffcp30; return simd_uint(simd_int(__x - simd_bitselect((simd_double4)0,0x1.0p31,__big))) + simd_bitselect((simd_uint4)0,0x80000000,simd_int(__big)); } +static simd_uint8 SIMD_CFUNC simd_uint(simd_double8 __x) { simd_long8 __big = __x > 0x1.fffffffcp30; return simd_uint(simd_int(__x - simd_bitselect((simd_double8)0,0x1.0p31,__big))) + simd_bitselect((simd_uint8)0,0x80000000,simd_int(__big)); } + +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_char2 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_char3 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_char4 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_char8 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_char16 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_short2 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_short3 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_short4 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_short8 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_short16 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_int2 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_int3 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_int4 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_int8 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_int16 __x) { return simd_uint(simd_max(__x,0)); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_float2 __x) { return simd_bitselect(simd_uint(simd_max(__x,0)), 0xffffffff, __x >= 0x1.0p32f); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_float3 __x) { return simd_bitselect(simd_uint(simd_max(__x,0)), 0xffffffff, __x >= 0x1.0p32f); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_float4 __x) { return simd_bitselect(simd_uint(simd_max(__x,0)), 0xffffffff, __x >= 0x1.0p32f); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_float8 __x) { return simd_bitselect(simd_uint(simd_max(__x,0)), 0xffffffff, __x >= 0x1.0p32f); } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_float16 __x) { return simd_bitselect(simd_uint(simd_max(__x,0)), 0xffffffff, __x >= 0x1.0p32f); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_long2 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_long3 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_long4 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_long8 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_double2 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_double3 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_double4 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_double8 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_uchar2 __x) { return simd_uint(__x); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_uchar3 __x) { return simd_uint(__x); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_uchar4 __x) { return simd_uint(__x); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_uchar8 __x) { return simd_uint(__x); } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_uchar16 __x) { return simd_uint(__x); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_ushort2 __x) { return simd_uint(__x); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_ushort3 __x) { return simd_uint(__x); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_ushort4 __x) { return simd_uint(__x); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_ushort8 __x) { return simd_uint(__x); } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_ushort16 __x) { return simd_uint(__x); } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_uint2 __x) { return __x; } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_uint3 __x) { return __x; } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_uint4 __x) { return __x; } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_uint8 __x) { return __x; } +static simd_uint16 SIMD_CFUNC simd_uint_sat(simd_uint16 __x) { return __x; } +static simd_uint2 SIMD_CFUNC simd_uint_sat(simd_ulong2 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint3 SIMD_CFUNC simd_uint_sat(simd_ulong3 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint4 SIMD_CFUNC simd_uint_sat(simd_ulong4 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } +static simd_uint8 SIMD_CFUNC simd_uint_sat(simd_ulong8 __x) { return simd_uint(simd_clamp(__x,0,0xffffffff)); } + + +static simd_float2 SIMD_CFUNC simd_float(simd_char2 __x) { return (simd_float2)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float3 SIMD_CFUNC simd_float(simd_char3 __x) { return (simd_float3)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float4 SIMD_CFUNC simd_float(simd_char4 __x) { return (simd_float4)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float8 SIMD_CFUNC simd_float(simd_char8 __x) { return (simd_float8)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float16 SIMD_CFUNC simd_float(simd_char16 __x) { return (simd_float16)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float2 SIMD_CFUNC simd_float(simd_uchar2 __x) { return (simd_float2)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float3 SIMD_CFUNC simd_float(simd_uchar3 __x) { return (simd_float3)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float4 SIMD_CFUNC simd_float(simd_uchar4 __x) { return (simd_float4)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float8 SIMD_CFUNC simd_float(simd_uchar8 __x) { return (simd_float8)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float16 SIMD_CFUNC simd_float(simd_uchar16 __x) { return (simd_float16)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float2 SIMD_CFUNC simd_float(simd_short2 __x) { return (simd_float2)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float3 SIMD_CFUNC simd_float(simd_short3 __x) { return (simd_float3)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float4 SIMD_CFUNC simd_float(simd_short4 __x) { return (simd_float4)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float8 SIMD_CFUNC simd_float(simd_short8 __x) { return (simd_float8)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float16 SIMD_CFUNC simd_float(simd_short16 __x) { return (simd_float16)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float2 SIMD_CFUNC simd_float(simd_ushort2 __x) { return (simd_float2)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float3 SIMD_CFUNC simd_float(simd_ushort3 __x) { return (simd_float3)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float4 SIMD_CFUNC simd_float(simd_ushort4 __x) { return (simd_float4)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float8 SIMD_CFUNC simd_float(simd_ushort8 __x) { return (simd_float8)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float16 SIMD_CFUNC simd_float(simd_ushort16 __x) { return (simd_float16)(simd_int(__x) + 0x4b400000) - 0x1.8p23f; } +static simd_float2 SIMD_CFUNC simd_float(simd_int2 __x) { return __builtin_convertvector(__x,simd_float2); } +static simd_float3 SIMD_CFUNC simd_float(simd_int3 __x) { return __builtin_convertvector(__x,simd_float3); } +static simd_float4 SIMD_CFUNC simd_float(simd_int4 __x) { return __builtin_convertvector(__x,simd_float4); } +static simd_float8 SIMD_CFUNC simd_float(simd_int8 __x) { return __builtin_convertvector(__x,simd_float8); } +static simd_float16 SIMD_CFUNC simd_float(simd_int16 __x) { return __builtin_convertvector(__x,simd_float16); } +static simd_float2 SIMD_CFUNC simd_float(simd_uint2 __x) { return __builtin_convertvector(__x,simd_float2); } +static simd_float3 SIMD_CFUNC simd_float(simd_uint3 __x) { return __builtin_convertvector(__x,simd_float3); } +static simd_float4 SIMD_CFUNC simd_float(simd_uint4 __x) { return __builtin_convertvector(__x,simd_float4); } +static simd_float8 SIMD_CFUNC simd_float(simd_uint8 __x) { return __builtin_convertvector(__x,simd_float8); } +static simd_float16 SIMD_CFUNC simd_float(simd_uint16 __x) { return __builtin_convertvector(__x,simd_float16); } +static simd_float2 SIMD_CFUNC simd_float(simd_float2 __x) { return __x; } +static simd_float3 SIMD_CFUNC simd_float(simd_float3 __x) { return __x; } +static simd_float4 SIMD_CFUNC simd_float(simd_float4 __x) { return __x; } +static simd_float8 SIMD_CFUNC simd_float(simd_float8 __x) { return __x; } +static simd_float16 SIMD_CFUNC simd_float(simd_float16 __x) { return __x; } +static simd_float2 SIMD_CFUNC simd_float(simd_long2 __x) { return __builtin_convertvector(__x,simd_float2); } +static simd_float3 SIMD_CFUNC simd_float(simd_long3 __x) { return __builtin_convertvector(__x,simd_float3); } +static simd_float4 SIMD_CFUNC simd_float(simd_long4 __x) { return __builtin_convertvector(__x,simd_float4); } +static simd_float8 SIMD_CFUNC simd_float(simd_long8 __x) { return __builtin_convertvector(__x,simd_float8); } +static simd_float2 SIMD_CFUNC simd_float(simd_ulong2 __x) { return __builtin_convertvector(__x,simd_float2); } +static simd_float3 SIMD_CFUNC simd_float(simd_ulong3 __x) { return __builtin_convertvector(__x,simd_float3); } +static simd_float4 SIMD_CFUNC simd_float(simd_ulong4 __x) { return __builtin_convertvector(__x,simd_float4); } +static simd_float8 SIMD_CFUNC simd_float(simd_ulong8 __x) { return __builtin_convertvector(__x,simd_float8); } +static simd_float2 SIMD_CFUNC simd_float(simd_double2 __x) { return __builtin_convertvector(__x,simd_float2); } +static simd_float3 SIMD_CFUNC simd_float(simd_double3 __x) { return __builtin_convertvector(__x,simd_float3); } +static simd_float4 SIMD_CFUNC simd_float(simd_double4 __x) { return __builtin_convertvector(__x,simd_float4); } +static simd_float8 SIMD_CFUNC simd_float(simd_double8 __x) { return __builtin_convertvector(__x,simd_float8); } + + +static simd_long2 SIMD_CFUNC simd_long(simd_char2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_char3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_char4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_char8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_uchar2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_uchar3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_uchar4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_uchar8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_short2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_short3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_short4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_short8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_ushort2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_ushort3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_ushort4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_ushort8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_int2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_int3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_int4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_int8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_uint2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_uint3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_uint4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_uint8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_float2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_float3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_float4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_float8 __x) { return __builtin_convertvector(__x,simd_long8); } +static simd_long2 SIMD_CFUNC simd_long(simd_long2 __x) { return __x; } +static simd_long3 SIMD_CFUNC simd_long(simd_long3 __x) { return __x; } +static simd_long4 SIMD_CFUNC simd_long(simd_long4 __x) { return __x; } +static simd_long8 SIMD_CFUNC simd_long(simd_long8 __x) { return __x; } +static simd_long2 SIMD_CFUNC simd_long(simd_ulong2 __x) { return (simd_long2)__x; } +static simd_long3 SIMD_CFUNC simd_long(simd_ulong3 __x) { return (simd_long3)__x; } +static simd_long4 SIMD_CFUNC simd_long(simd_ulong4 __x) { return (simd_long4)__x; } +static simd_long8 SIMD_CFUNC simd_long(simd_ulong8 __x) { return (simd_long8)__x; } +static simd_long2 SIMD_CFUNC simd_long(simd_double2 __x) { return __builtin_convertvector(__x,simd_long2); } +static simd_long3 SIMD_CFUNC simd_long(simd_double3 __x) { return __builtin_convertvector(__x,simd_long3); } +static simd_long4 SIMD_CFUNC simd_long(simd_double4 __x) { return __builtin_convertvector(__x,simd_long4); } +static simd_long8 SIMD_CFUNC simd_long(simd_double8 __x) { return __builtin_convertvector(__x,simd_long8); } + +static simd_long2 SIMD_CFUNC simd_long_sat(simd_char2 __x) { return simd_long(__x); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_char3 __x) { return simd_long(__x); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_char4 __x) { return simd_long(__x); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_char8 __x) { return simd_long(__x); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_short2 __x) { return simd_long(__x); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_short3 __x) { return simd_long(__x); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_short4 __x) { return simd_long(__x); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_short8 __x) { return simd_long(__x); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_int2 __x) { return simd_long(__x); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_int3 __x) { return simd_long(__x); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_int4 __x) { return simd_long(__x); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_int8 __x) { return simd_long(__x); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_float2 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63f)), 0x7fffffffffffffff, simd_long(__x >= 0x1.0p63f)); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_float3 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63f)), 0x7fffffffffffffff, simd_long(__x >= 0x1.0p63f)); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_float4 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63f)), 0x7fffffffffffffff, simd_long(__x >= 0x1.0p63f)); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_float8 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63f)), 0x7fffffffffffffff, simd_long(__x >= 0x1.0p63f)); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_long2 __x) { return __x; } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_long3 __x) { return __x; } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_long4 __x) { return __x; } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_long8 __x) { return __x; } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_double2 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63)), 0x7fffffffffffffff, __x >= 0x1.0p63); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_double3 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63)), 0x7fffffffffffffff, __x >= 0x1.0p63); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_double4 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63)), 0x7fffffffffffffff, __x >= 0x1.0p63); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_double8 __x) { return simd_bitselect(simd_long(simd_max(__x,-0x1.0p63)), 0x7fffffffffffffff, __x >= 0x1.0p63); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_uchar2 __x) { return simd_long(__x); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_uchar3 __x) { return simd_long(__x); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_uchar4 __x) { return simd_long(__x); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_uchar8 __x) { return simd_long(__x); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_ushort2 __x) { return simd_long(__x); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_ushort3 __x) { return simd_long(__x); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_ushort4 __x) { return simd_long(__x); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_ushort8 __x) { return simd_long(__x); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_uint2 __x) { return simd_long(__x); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_uint3 __x) { return simd_long(__x); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_uint4 __x) { return simd_long(__x); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_uint8 __x) { return simd_long(__x); } +static simd_long2 SIMD_CFUNC simd_long_sat(simd_ulong2 __x) { return simd_long(simd_min(__x,0x7fffffffffffffff)); } +static simd_long3 SIMD_CFUNC simd_long_sat(simd_ulong3 __x) { return simd_long(simd_min(__x,0x7fffffffffffffff)); } +static simd_long4 SIMD_CFUNC simd_long_sat(simd_ulong4 __x) { return simd_long(simd_min(__x,0x7fffffffffffffff)); } +static simd_long8 SIMD_CFUNC simd_long_sat(simd_ulong8 __x) { return simd_long(simd_min(__x,0x7fffffffffffffff)); } + +static simd_long2 SIMD_CFUNC simd_long_rte(simd_double2 __x) { +#if defined __AVX512F__ + return _mm_cvtpd_epi64(__x); +#elif defined __arm64__ + return vcvtnq_s64_f64(__x); +#else + simd_double2 magic = __tg_copysign(0x1.0p52, __x); + simd_long2 x_is_small = __tg_fabs(__x) < 0x1.0p52; + return __builtin_convertvector(simd_bitselect(__x, (__x + magic) - magic, x_is_small & 0x7fffffffffffffff), simd_long2); +#endif +} + +static simd_long3 SIMD_CFUNC simd_long_rte(simd_double3 __x) { + return simd_make_long3(simd_long_rte(simd_make_double4_undef(__x))); +} + +static simd_long4 SIMD_CFUNC simd_long_rte(simd_double4 __x) { +#if defined __AVX512F__ + return _mm256_cvtpd_epi64(__x); +#else + return simd_make_long4(simd_long_rte(__x.lo), simd_long_rte(__x.hi)); +#endif +} + +static simd_long8 SIMD_CFUNC simd_long_rte(simd_double8 __x) { +#if defined __AVX512F__ + return _mm512_cvt_roundpd_epi64(__x, _MM_FROUND_RINT); +#else + return simd_make_long8(simd_long_rte(__x.lo), simd_long_rte(__x.hi)); +#endif +} + + +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_char2 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_char3 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_char4 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_char8 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_uchar2 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_uchar3 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_uchar4 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_uchar8 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_short2 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_short3 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_short4 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_short8 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_ushort2 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_ushort3 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_ushort4 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_ushort8 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_int2 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_int3 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_int4 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_int8 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_uint2 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_uint3 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_uint4 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_uint8 __x) { return simd_ulong(simd_long(__x)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_float2 __x) { simd_int2 __big = __x >= 0x1.0p63f; return simd_ulong(simd_long(__x - simd_bitselect((simd_float2)0,0x1.0p63f,__big))) + simd_bitselect((simd_ulong2)0,0x8000000000000000,simd_long(__big)); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_float3 __x) { simd_int3 __big = __x >= 0x1.0p63f; return simd_ulong(simd_long(__x - simd_bitselect((simd_float3)0,0x1.0p63f,__big))) + simd_bitselect((simd_ulong3)0,0x8000000000000000,simd_long(__big)); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_float4 __x) { simd_int4 __big = __x >= 0x1.0p63f; return simd_ulong(simd_long(__x - simd_bitselect((simd_float4)0,0x1.0p63f,__big))) + simd_bitselect((simd_ulong4)0,0x8000000000000000,simd_long(__big)); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_float8 __x) { simd_int8 __big = __x >= 0x1.0p63f; return simd_ulong(simd_long(__x - simd_bitselect((simd_float8)0,0x1.0p63f,__big))) + simd_bitselect((simd_ulong8)0,0x8000000000000000,simd_long(__big)); } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_long2 __x) { return (simd_ulong2)__x; } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_long3 __x) { return (simd_ulong3)__x; } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_long4 __x) { return (simd_ulong4)__x; } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_long8 __x) { return (simd_ulong8)__x; } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_ulong2 __x) { return __x; } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_ulong3 __x) { return __x; } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_ulong4 __x) { return __x; } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_ulong8 __x) { return __x; } +static simd_ulong2 SIMD_CFUNC simd_ulong(simd_double2 __x) { simd_long2 __big = __x >= 0x1.0p63; return simd_ulong(simd_long(__x - simd_bitselect((simd_double2)0,0x1.0p63,__big))) + simd_bitselect((simd_ulong2)0,0x8000000000000000,__big); } +static simd_ulong3 SIMD_CFUNC simd_ulong(simd_double3 __x) { simd_long3 __big = __x >= 0x1.0p63; return simd_ulong(simd_long(__x - simd_bitselect((simd_double3)0,0x1.0p63,__big))) + simd_bitselect((simd_ulong3)0,0x8000000000000000,__big); } +static simd_ulong4 SIMD_CFUNC simd_ulong(simd_double4 __x) { simd_long4 __big = __x >= 0x1.0p63; return simd_ulong(simd_long(__x - simd_bitselect((simd_double4)0,0x1.0p63,__big))) + simd_bitselect((simd_ulong4)0,0x8000000000000000,__big); } +static simd_ulong8 SIMD_CFUNC simd_ulong(simd_double8 __x) { simd_long8 __big = __x >= 0x1.0p63; return simd_ulong(simd_long(__x - simd_bitselect((simd_double8)0,0x1.0p63,__big))) + simd_bitselect((simd_ulong8)0,0x8000000000000000,__big); } + +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_char2 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_char3 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_char4 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_char8 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_short2 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_short3 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_short4 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_short8 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_int2 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_int3 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_int4 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_int8 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_float2 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.f)), 0xffffffffffffffff, simd_long(__x >= 0x1.0p64f)); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_float3 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.f)), 0xffffffffffffffff, simd_long(__x >= 0x1.0p64f)); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_float4 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.f)), 0xffffffffffffffff, simd_long(__x >= 0x1.0p64f)); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_float8 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.f)), 0xffffffffffffffff, simd_long(__x >= 0x1.0p64f)); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_long2 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_long3 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_long4 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_long8 __x) { return simd_ulong(simd_max(__x,0)); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_double2 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.0)), 0xffffffffffffffff, __x >= 0x1.0p64); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_double3 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.0)), 0xffffffffffffffff, __x >= 0x1.0p64); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_double4 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.0)), 0xffffffffffffffff, __x >= 0x1.0p64); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_double8 __x) { return simd_bitselect(simd_ulong(simd_max(__x,0.0)), 0xffffffffffffffff, __x >= 0x1.0p64); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_uchar2 __x) { return simd_ulong(__x); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_uchar3 __x) { return simd_ulong(__x); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_uchar4 __x) { return simd_ulong(__x); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_uchar8 __x) { return simd_ulong(__x); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_ushort2 __x) { return simd_ulong(__x); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_ushort3 __x) { return simd_ulong(__x); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_ushort4 __x) { return simd_ulong(__x); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_ushort8 __x) { return simd_ulong(__x); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_uint2 __x) { return simd_ulong(__x); } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_uint3 __x) { return simd_ulong(__x); } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_uint4 __x) { return simd_ulong(__x); } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_uint8 __x) { return simd_ulong(__x); } +static simd_ulong2 SIMD_CFUNC simd_ulong_sat(simd_ulong2 __x) { return __x; } +static simd_ulong3 SIMD_CFUNC simd_ulong_sat(simd_ulong3 __x) { return __x; } +static simd_ulong4 SIMD_CFUNC simd_ulong_sat(simd_ulong4 __x) { return __x; } +static simd_ulong8 SIMD_CFUNC simd_ulong_sat(simd_ulong8 __x) { return __x; } + + +static simd_double2 SIMD_CFUNC simd_double(simd_char2 __x) { return simd_double(simd_int(__x)); } +static simd_double3 SIMD_CFUNC simd_double(simd_char3 __x) { return simd_double(simd_int(__x)); } +static simd_double4 SIMD_CFUNC simd_double(simd_char4 __x) { return simd_double(simd_int(__x)); } +static simd_double8 SIMD_CFUNC simd_double(simd_char8 __x) { return simd_double(simd_int(__x)); } +static simd_double2 SIMD_CFUNC simd_double(simd_uchar2 __x) { return simd_double(simd_int(__x)); } +static simd_double3 SIMD_CFUNC simd_double(simd_uchar3 __x) { return simd_double(simd_int(__x)); } +static simd_double4 SIMD_CFUNC simd_double(simd_uchar4 __x) { return simd_double(simd_int(__x)); } +static simd_double8 SIMD_CFUNC simd_double(simd_uchar8 __x) { return simd_double(simd_int(__x)); } +static simd_double2 SIMD_CFUNC simd_double(simd_short2 __x) { return simd_double(simd_int(__x)); } +static simd_double3 SIMD_CFUNC simd_double(simd_short3 __x) { return simd_double(simd_int(__x)); } +static simd_double4 SIMD_CFUNC simd_double(simd_short4 __x) { return simd_double(simd_int(__x)); } +static simd_double8 SIMD_CFUNC simd_double(simd_short8 __x) { return simd_double(simd_int(__x)); } +static simd_double2 SIMD_CFUNC simd_double(simd_ushort2 __x) { return simd_double(simd_int(__x)); } +static simd_double3 SIMD_CFUNC simd_double(simd_ushort3 __x) { return simd_double(simd_int(__x)); } +static simd_double4 SIMD_CFUNC simd_double(simd_ushort4 __x) { return simd_double(simd_int(__x)); } +static simd_double8 SIMD_CFUNC simd_double(simd_ushort8 __x) { return simd_double(simd_int(__x)); } +static simd_double2 SIMD_CFUNC simd_double(simd_int2 __x) { return __builtin_convertvector(__x, simd_double2); } +static simd_double3 SIMD_CFUNC simd_double(simd_int3 __x) { return __builtin_convertvector(__x, simd_double3); } +static simd_double4 SIMD_CFUNC simd_double(simd_int4 __x) { return __builtin_convertvector(__x, simd_double4); } +static simd_double8 SIMD_CFUNC simd_double(simd_int8 __x) { return __builtin_convertvector(__x, simd_double8); } +static simd_double2 SIMD_CFUNC simd_double(simd_uint2 __x) { return __builtin_convertvector(__x, simd_double2); } +static simd_double3 SIMD_CFUNC simd_double(simd_uint3 __x) { return __builtin_convertvector(__x, simd_double3); } +static simd_double4 SIMD_CFUNC simd_double(simd_uint4 __x) { return __builtin_convertvector(__x, simd_double4); } +static simd_double8 SIMD_CFUNC simd_double(simd_uint8 __x) { return __builtin_convertvector(__x, simd_double8); } +static simd_double2 SIMD_CFUNC simd_double(simd_float2 __x) { return __builtin_convertvector(__x, simd_double2); } +static simd_double3 SIMD_CFUNC simd_double(simd_float3 __x) { return __builtin_convertvector(__x, simd_double3); } +static simd_double4 SIMD_CFUNC simd_double(simd_float4 __x) { return __builtin_convertvector(__x, simd_double4); } +static simd_double8 SIMD_CFUNC simd_double(simd_float8 __x) { return __builtin_convertvector(__x, simd_double8); } +static simd_double2 SIMD_CFUNC simd_double(simd_long2 __x) { return __builtin_convertvector(__x, simd_double2); } +static simd_double3 SIMD_CFUNC simd_double(simd_long3 __x) { return __builtin_convertvector(__x, simd_double3); } +static simd_double4 SIMD_CFUNC simd_double(simd_long4 __x) { return __builtin_convertvector(__x, simd_double4); } +static simd_double8 SIMD_CFUNC simd_double(simd_long8 __x) { return __builtin_convertvector(__x, simd_double8); } +static simd_double2 SIMD_CFUNC simd_double(simd_ulong2 __x) { return __builtin_convertvector(__x, simd_double2); } +static simd_double3 SIMD_CFUNC simd_double(simd_ulong3 __x) { return __builtin_convertvector(__x, simd_double3); } +static simd_double4 SIMD_CFUNC simd_double(simd_ulong4 __x) { return __builtin_convertvector(__x, simd_double4); } +static simd_double8 SIMD_CFUNC simd_double(simd_ulong8 __x) { return __builtin_convertvector(__x, simd_double8); } +static simd_double2 SIMD_CFUNC simd_double(simd_double2 __x) { return __builtin_convertvector(__x, simd_double2); } +static simd_double3 SIMD_CFUNC simd_double(simd_double3 __x) { return __builtin_convertvector(__x, simd_double3); } +static simd_double4 SIMD_CFUNC simd_double(simd_double4 __x) { return __builtin_convertvector(__x, simd_double4); } +static simd_double8 SIMD_CFUNC simd_double(simd_double8 __x) { return __builtin_convertvector(__x, simd_double8); } + + +#ifdef __cplusplus +} +#endif +#endif // SIMD_COMPILER_HAS_REQUIRED_FEATURES +#endif // __SIMD_CONVERSION_HEADER__ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/math.h b/lib/libc/include/any-macos.11-any/simd/math.h new file mode 100644 index 0000000000..4d5c654f69 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/math.h @@ -0,0 +1,5380 @@ +/*! @header + * The interfaces declared in this header provide elementwise math operations + * on vectors; each lane of the result vector depends only on the data in the + * corresponding lane of the argument(s) to the function. + * + * You should not use the C functions declared in this header directly (these + * are functions with names like `__tg_cos(x)`). These are merely + * implementation details of overloading; instead of calling + * `__tg_cos(x)`, call `cos(x)`. If you are writing C++, use `simd::cos(x)`. + * + * Note that while these vector functions are relatively recent additions, + * scalar fallback is provided for all of them, so they are available even + * when targeting older OS versions. + * + * The following functions are available: + * + * C name C++ name Notes + * ---------------------------------------------------------------------- + * acos(x) simd::acos(x) + * asin(x) simd::asin(x) + * atan(x) simd::atan(x) + * atan2(y,x) simd::atan2(y,x) The argument order matches the scalar + * atan2 function, which gives the angle + * of a line with slope y/x. + * cos(x) simd::cos(x) + * sin(x) simd::sin(x) + * tan(x) simd::tan(x) + * + * cospi(x) simd::cospi(x) Returns cos(pi*x), sin(pi*x), tan(pi*x) + * sinpi(x) simd::sinpi(x) more efficiently and accurately than + * tanpi(x) simd::tanpi(x) would otherwise be possible + * + * acosh(x) simd::acosh(x) + * asinh(x) simd::asinh(x) + * atanh(x) simd::atanh(x) + * + * cosh(x) simd::cosh(x) + * sinh(x) simd::sinh(x) + * tanh(x) simd::tanh(x) + * + * exp(x) simd::exp(x) + * exp2(x) simd::exp2(x) + * exp10(x) simd::exp10(x) More efficient that pow(10,x). + * expm1(x) simd::expm1(x) exp(x)-1, accurate even for tiny x. + * + * log(x) simd::log(x) + * log2(x) simd::log2(x) + * log10(x) simd::log10(x) + * log1p(x) simd::log1p(x) log(1+x), accurate even for tiny x. + * + * fabs(x) simd::fabs(x) + * cbrt(x) simd::cbrt(x) + * sqrt(x) simd::sqrt(x) + * pow(x,y) simd::pow(x,y) + * copysign(x,y) simd::copysign(x,y) + * hypot(x,y) simd::hypot(x,y) sqrt(x*x + y*y), computed without + * overflow.1 + * erf(x) simd::erf(x) + * erfc(x) simd::erfc(x) + * tgamma(x) simd::tgamma(x) + * + * fmod(x,y) simd::fmod(x,y) + * remainder(x,y) simd::remainder(x,y) + * + * ceil(x) simd::ceil(x) + * floor(x) simd::floor(x) + * rint(x) simd::rint(x) + * round(x) simd::round(x) + * trunc(x) simd::trunc(x) + * + * fdim(x,y) simd::fdim(x,y) + * fmax(x,y) simd::fmax(x,y) When one argument to fmin or fmax is + * fmin(x,y) simd::fmin(x,y) constant, use it as the *second* (y) + * argument to get better codegen on some + * architectures. E.g., write fmin(x,2) + * instead of fmin(2,x). + * fma(x,y,z) simd::fma(x,y,z) Fast on arm64 and when targeting AVX2 + * and later; may be quite expensive on + * older hardware. + * simd_muladd(x,y,z) simd::muladd(x,y,z) + * + * @copyright 2014-2017 Apple, Inc. All rights reserved. + * @unsorted */ + +#ifndef SIMD_MATH_HEADER +#define SIMD_MATH_HEADER + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_acos(simd_float2 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_acos(simd_float3 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_acos(simd_float4 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_acos(simd_float8 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_acos(simd_float16 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_acos(simd_double2 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_acos(simd_double3 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_acos(simd_double4 x); +/*! @abstract Do not call this function; instead use `acos` in C and + * Objective-C, and `simd::acos` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_acos(simd_double8 x); + +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_asin(simd_float2 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_asin(simd_float3 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_asin(simd_float4 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_asin(simd_float8 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_asin(simd_float16 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_asin(simd_double2 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_asin(simd_double3 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_asin(simd_double4 x); +/*! @abstract Do not call this function; instead use `asin` in C and + * Objective-C, and `simd::asin` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_asin(simd_double8 x); + +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_atan(simd_float2 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_atan(simd_float3 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_atan(simd_float4 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_atan(simd_float8 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_atan(simd_float16 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_atan(simd_double2 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_atan(simd_double3 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_atan(simd_double4 x); +/*! @abstract Do not call this function; instead use `atan` in C and + * Objective-C, and `simd::atan` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_atan(simd_double8 x); + +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_cos(simd_float2 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_cos(simd_float3 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_cos(simd_float4 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_cos(simd_float8 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_cos(simd_float16 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_cos(simd_double2 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_cos(simd_double3 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_cos(simd_double4 x); +/*! @abstract Do not call this function; instead use `cos` in C and + * Objective-C, and `simd::cos` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_cos(simd_double8 x); + +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_sin(simd_float2 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_sin(simd_float3 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_sin(simd_float4 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_sin(simd_float8 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_sin(simd_float16 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_sin(simd_double2 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_sin(simd_double3 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_sin(simd_double4 x); +/*! @abstract Do not call this function; instead use `sin` in C and + * Objective-C, and `simd::sin` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_sin(simd_double8 x); + +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_tan(simd_float2 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_tan(simd_float3 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_tan(simd_float4 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_tan(simd_float8 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_tan(simd_float16 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_tan(simd_double2 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_tan(simd_double3 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_tan(simd_double4 x); +/*! @abstract Do not call this function; instead use `tan` in C and + * Objective-C, and `simd::tan` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_tan(simd_double8 x); + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_cospi(simd_float2 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_cospi(simd_float3 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_cospi(simd_float4 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_cospi(simd_float8 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_cospi(simd_float16 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_cospi(simd_double2 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_cospi(simd_double3 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_cospi(simd_double4 x); +/*! @abstract Do not call this function; instead use `cospi` in C and + * Objective-C, and `simd::cospi` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_cospi(simd_double8 x); +#endif + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_sinpi(simd_float2 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_sinpi(simd_float3 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_sinpi(simd_float4 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_sinpi(simd_float8 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_sinpi(simd_float16 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_sinpi(simd_double2 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_sinpi(simd_double3 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_sinpi(simd_double4 x); +/*! @abstract Do not call this function; instead use `sinpi` in C and + * Objective-C, and `simd::sinpi` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_sinpi(simd_double8 x); +#endif + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_tanpi(simd_float2 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_tanpi(simd_float3 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_tanpi(simd_float4 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_tanpi(simd_float8 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_tanpi(simd_float16 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_tanpi(simd_double2 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_tanpi(simd_double3 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_tanpi(simd_double4 x); +/*! @abstract Do not call this function; instead use `tanpi` in C and + * Objective-C, and `simd::tanpi` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_tanpi(simd_double8 x); +#endif + +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_acosh(simd_float2 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_acosh(simd_float3 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_acosh(simd_float4 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_acosh(simd_float8 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_acosh(simd_float16 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_acosh(simd_double2 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_acosh(simd_double3 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_acosh(simd_double4 x); +/*! @abstract Do not call this function; instead use `acosh` in C and + * Objective-C, and `simd::acosh` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_acosh(simd_double8 x); + +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_asinh(simd_float2 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_asinh(simd_float3 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_asinh(simd_float4 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_asinh(simd_float8 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_asinh(simd_float16 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_asinh(simd_double2 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_asinh(simd_double3 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_asinh(simd_double4 x); +/*! @abstract Do not call this function; instead use `asinh` in C and + * Objective-C, and `simd::asinh` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_asinh(simd_double8 x); + +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_atanh(simd_float2 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_atanh(simd_float3 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_atanh(simd_float4 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_atanh(simd_float8 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_atanh(simd_float16 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_atanh(simd_double2 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_atanh(simd_double3 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_atanh(simd_double4 x); +/*! @abstract Do not call this function; instead use `atanh` in C and + * Objective-C, and `simd::atanh` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_atanh(simd_double8 x); + +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_cosh(simd_float2 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_cosh(simd_float3 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_cosh(simd_float4 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_cosh(simd_float8 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_cosh(simd_float16 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_cosh(simd_double2 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_cosh(simd_double3 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_cosh(simd_double4 x); +/*! @abstract Do not call this function; instead use `cosh` in C and + * Objective-C, and `simd::cosh` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_cosh(simd_double8 x); + +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_sinh(simd_float2 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_sinh(simd_float3 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_sinh(simd_float4 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_sinh(simd_float8 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_sinh(simd_float16 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_sinh(simd_double2 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_sinh(simd_double3 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_sinh(simd_double4 x); +/*! @abstract Do not call this function; instead use `sinh` in C and + * Objective-C, and `simd::sinh` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_sinh(simd_double8 x); + +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_tanh(simd_float2 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_tanh(simd_float3 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_tanh(simd_float4 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_tanh(simd_float8 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_tanh(simd_float16 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_tanh(simd_double2 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_tanh(simd_double3 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_tanh(simd_double4 x); +/*! @abstract Do not call this function; instead use `tanh` in C and + * Objective-C, and `simd::tanh` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_tanh(simd_double8 x); + +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_exp(simd_float2 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_exp(simd_float3 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_exp(simd_float4 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_exp(simd_float8 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_exp(simd_float16 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_exp(simd_double2 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_exp(simd_double3 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_exp(simd_double4 x); +/*! @abstract Do not call this function; instead use `exp` in C and + * Objective-C, and `simd::exp` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_exp(simd_double8 x); + +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_exp2(simd_float2 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_exp2(simd_float3 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_exp2(simd_float4 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_exp2(simd_float8 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_exp2(simd_float16 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_exp2(simd_double2 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_exp2(simd_double3 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_exp2(simd_double4 x); +/*! @abstract Do not call this function; instead use `exp2` in C and + * Objective-C, and `simd::exp2` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_exp2(simd_double8 x); + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_exp10(simd_float2 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_exp10(simd_float3 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_exp10(simd_float4 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_exp10(simd_float8 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_exp10(simd_float16 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_exp10(simd_double2 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_exp10(simd_double3 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_exp10(simd_double4 x); +/*! @abstract Do not call this function; instead use `exp10` in C and + * Objective-C, and `simd::exp10` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_exp10(simd_double8 x); +#endif + +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_expm1(simd_float2 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_expm1(simd_float3 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_expm1(simd_float4 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_expm1(simd_float8 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_expm1(simd_float16 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_expm1(simd_double2 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_expm1(simd_double3 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_expm1(simd_double4 x); +/*! @abstract Do not call this function; instead use `expm1` in C and + * Objective-C, and `simd::expm1` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_expm1(simd_double8 x); + +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_log(simd_float2 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_log(simd_float3 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_log(simd_float4 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_log(simd_float8 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_log(simd_float16 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_log(simd_double2 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_log(simd_double3 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_log(simd_double4 x); +/*! @abstract Do not call this function; instead use `log` in C and + * Objective-C, and `simd::log` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_log(simd_double8 x); + +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_log2(simd_float2 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_log2(simd_float3 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_log2(simd_float4 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_log2(simd_float8 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_log2(simd_float16 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_log2(simd_double2 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_log2(simd_double3 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_log2(simd_double4 x); +/*! @abstract Do not call this function; instead use `log2` in C and + * Objective-C, and `simd::log2` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_log2(simd_double8 x); + +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_log10(simd_float2 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_log10(simd_float3 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_log10(simd_float4 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_log10(simd_float8 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_log10(simd_float16 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_log10(simd_double2 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_log10(simd_double3 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_log10(simd_double4 x); +/*! @abstract Do not call this function; instead use `log10` in C and + * Objective-C, and `simd::log10` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_log10(simd_double8 x); + +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_log1p(simd_float2 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_log1p(simd_float3 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_log1p(simd_float4 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_log1p(simd_float8 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_log1p(simd_float16 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_log1p(simd_double2 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_log1p(simd_double3 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_log1p(simd_double4 x); +/*! @abstract Do not call this function; instead use `log1p` in C and + * Objective-C, and `simd::log1p` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_log1p(simd_double8 x); + +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_fabs(simd_float2 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_fabs(simd_float3 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_fabs(simd_float4 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_fabs(simd_float8 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_fabs(simd_float16 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_fabs(simd_double2 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_fabs(simd_double3 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_fabs(simd_double4 x); +/*! @abstract Do not call this function; instead use `fabs` in C and + * Objective-C, and `simd::fabs` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_fabs(simd_double8 x); + +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_cbrt(simd_float2 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_cbrt(simd_float3 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_cbrt(simd_float4 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_cbrt(simd_float8 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_cbrt(simd_float16 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_cbrt(simd_double2 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_cbrt(simd_double3 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_cbrt(simd_double4 x); +/*! @abstract Do not call this function; instead use `cbrt` in C and + * Objective-C, and `simd::cbrt` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_cbrt(simd_double8 x); + +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_sqrt(simd_float2 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_sqrt(simd_float3 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_sqrt(simd_float4 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_sqrt(simd_float8 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_sqrt(simd_float16 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_sqrt(simd_double2 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_sqrt(simd_double3 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_sqrt(simd_double4 x); +/*! @abstract Do not call this function; instead use `sqrt` in C and + * Objective-C, and `simd::sqrt` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_sqrt(simd_double8 x); + +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_erf(simd_float2 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_erf(simd_float3 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_erf(simd_float4 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_erf(simd_float8 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_erf(simd_float16 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_erf(simd_double2 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_erf(simd_double3 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_erf(simd_double4 x); +/*! @abstract Do not call this function; instead use `erf` in C and + * Objective-C, and `simd::erf` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_erf(simd_double8 x); + +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_erfc(simd_float2 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_erfc(simd_float3 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_erfc(simd_float4 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_erfc(simd_float8 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_erfc(simd_float16 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_erfc(simd_double2 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_erfc(simd_double3 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_erfc(simd_double4 x); +/*! @abstract Do not call this function; instead use `erfc` in C and + * Objective-C, and `simd::erfc` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_erfc(simd_double8 x); + +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_tgamma(simd_float2 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_tgamma(simd_float3 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_tgamma(simd_float4 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_tgamma(simd_float8 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_tgamma(simd_float16 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_tgamma(simd_double2 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_tgamma(simd_double3 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_tgamma(simd_double4 x); +/*! @abstract Do not call this function; instead use `tgamma` in C and + * Objective-C, and `simd::tgamma` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_tgamma(simd_double8 x); + +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_ceil(simd_float2 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_ceil(simd_float3 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_ceil(simd_float4 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_ceil(simd_float8 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_ceil(simd_float16 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_ceil(simd_double2 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_ceil(simd_double3 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_ceil(simd_double4 x); +/*! @abstract Do not call this function; instead use `ceil` in C and + * Objective-C, and `simd::ceil` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_ceil(simd_double8 x); + +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_floor(simd_float2 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_floor(simd_float3 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_floor(simd_float4 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_floor(simd_float8 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_floor(simd_float16 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_floor(simd_double2 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_floor(simd_double3 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_floor(simd_double4 x); +/*! @abstract Do not call this function; instead use `floor` in C and + * Objective-C, and `simd::floor` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_floor(simd_double8 x); + +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_rint(simd_float2 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_rint(simd_float3 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_rint(simd_float4 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_rint(simd_float8 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_rint(simd_float16 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_rint(simd_double2 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_rint(simd_double3 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_rint(simd_double4 x); +/*! @abstract Do not call this function; instead use `rint` in C and + * Objective-C, and `simd::rint` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_rint(simd_double8 x); + +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_round(simd_float2 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_round(simd_float3 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_round(simd_float4 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_round(simd_float8 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_round(simd_float16 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_round(simd_double2 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_round(simd_double3 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_round(simd_double4 x); +/*! @abstract Do not call this function; instead use `round` in C and + * Objective-C, and `simd::round` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_round(simd_double8 x); + +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_trunc(simd_float2 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_trunc(simd_float3 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_trunc(simd_float4 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_trunc(simd_float8 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_trunc(simd_float16 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_trunc(simd_double2 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_trunc(simd_double3 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_trunc(simd_double4 x); +/*! @abstract Do not call this function; instead use `trunc` in C and + * Objective-C, and `simd::trunc` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_trunc(simd_double8 x); + + +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_atan2(simd_float2 y, simd_float2 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_atan2(simd_float3 y, simd_float3 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_atan2(simd_float4 y, simd_float4 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_atan2(simd_float8 y, simd_float8 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_atan2(simd_float16 y, simd_float16 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_atan2(simd_double2 y, simd_double2 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_atan2(simd_double3 y, simd_double3 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_atan2(simd_double4 y, simd_double4 x); +/*! @abstract Do not call this function; instead use `atan2` in C and + * Objective-C, and `simd::atan2` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_atan2(simd_double8 y, simd_double8 x); + +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_hypot(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_hypot(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_hypot(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_hypot(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_hypot(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_hypot(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_hypot(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_hypot(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `hypot` in C and + * Objective-C, and `simd::hypot` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_hypot(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_pow(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_pow(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_pow(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_pow(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_pow(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_pow(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_pow(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_pow(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `pow` in C and + * Objective-C, and `simd::pow` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_pow(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_fmod(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_fmod(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_fmod(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_fmod(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_fmod(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_fmod(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_fmod(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_fmod(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `fmod` in C and + * Objective-C, and `simd::fmod` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_fmod(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_remainder(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_remainder(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_remainder(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_remainder(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_remainder(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_remainder(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_remainder(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_remainder(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `remainder` in C and + * Objective-C, and `simd::remainder` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_remainder(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_copysign(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_copysign(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_copysign(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_copysign(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_copysign(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_copysign(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_copysign(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_copysign(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `copysign` in C and + * Objective-C, and `simd::copysign` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_copysign(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_nextafter(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_nextafter(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_nextafter(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_nextafter(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_nextafter(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_nextafter(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_nextafter(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_nextafter(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `nextafter` in C and + * Objective-C, and `simd::nextafter` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_nextafter(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_fdim(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_fdim(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_fdim(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_fdim(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_fdim(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_fdim(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_fdim(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_fdim(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `fdim` in C and + * Objective-C, and `simd::fdim` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_fdim(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_fmax(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_fmax(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_fmax(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_fmax(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_fmax(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_fmax(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_fmax(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_fmax(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `fmax` in C and + * Objective-C, and `simd::fmax` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_fmax(simd_double8 x, simd_double8 y); + +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_fmin(simd_float2 x, simd_float2 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_fmin(simd_float3 x, simd_float3 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_fmin(simd_float4 x, simd_float4 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_fmin(simd_float8 x, simd_float8 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_fmin(simd_float16 x, simd_float16 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_fmin(simd_double2 x, simd_double2 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_fmin(simd_double3 x, simd_double3 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_fmin(simd_double4 x, simd_double4 y); +/*! @abstract Do not call this function; instead use `fmin` in C and + * Objective-C, and `simd::fmin` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_fmin(simd_double8 x, simd_double8 y); + + +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_float2 __tg_fma(simd_float2 x, simd_float2 y, simd_float2 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_float3 __tg_fma(simd_float3 x, simd_float3 y, simd_float3 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_float4 __tg_fma(simd_float4 x, simd_float4 y, simd_float4 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_float8 __tg_fma(simd_float8 x, simd_float8 y, simd_float8 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_float16 __tg_fma(simd_float16 x, simd_float16 y, simd_float16 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_double2 __tg_fma(simd_double2 x, simd_double2 y, simd_double2 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_double3 __tg_fma(simd_double3 x, simd_double3 y, simd_double3 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_double4 __tg_fma(simd_double4 x, simd_double4 y, simd_double4 z); +/*! @abstract Do not call this function; instead use `fma` in C and Objective-C, + * and `simd::fma` in C++. */ +static inline SIMD_CFUNC simd_double8 __tg_fma(simd_double8 x, simd_double8 y, simd_double8 z); + +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC float simd_muladd(float x, float y, float z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_float2 simd_muladd(simd_float2 x, simd_float2 y, simd_float2 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_float3 simd_muladd(simd_float3 x, simd_float3 y, simd_float3 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_float4 simd_muladd(simd_float4 x, simd_float4 y, simd_float4 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_float8 simd_muladd(simd_float8 x, simd_float8 y, simd_float8 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_float16 simd_muladd(simd_float16 x, simd_float16 y, simd_float16 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC double simd_muladd(double x, double y, double z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_double2 simd_muladd(simd_double2 x, simd_double2 y, simd_double2 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_double3 simd_muladd(simd_double3 x, simd_double3 y, simd_double3 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_double4 simd_muladd(simd_double4 x, simd_double4 y, simd_double4 z); +/*! @abstract Computes accum + x*y by the most efficient means available; + * either a fused multiply add or separate multiply and add instructions. */ +static inline SIMD_CFUNC simd_double8 simd_muladd(simd_double8 x, simd_double8 y, simd_double8 z); + +#ifdef __cplusplus +} /* extern "C" */ + +#include +/*! @abstract Do not call this function directly; use simd::acos instead. */ +static SIMD_CPPFUNC float __tg_acos(float x) { return ::acos(x); } +/*! @abstract Do not call this function directly; use simd::acos instead. */ +static SIMD_CPPFUNC double __tg_acos(double x) { return ::acos(x); } +/*! @abstract Do not call this function directly; use simd::asin instead. */ +static SIMD_CPPFUNC float __tg_asin(float x) { return ::asin(x); } +/*! @abstract Do not call this function directly; use simd::asin instead. */ +static SIMD_CPPFUNC double __tg_asin(double x) { return ::asin(x); } +/*! @abstract Do not call this function directly; use simd::atan instead. */ +static SIMD_CPPFUNC float __tg_atan(float x) { return ::atan(x); } +/*! @abstract Do not call this function directly; use simd::atan instead. */ +static SIMD_CPPFUNC double __tg_atan(double x) { return ::atan(x); } +/*! @abstract Do not call this function directly; use simd::cos instead. */ +static SIMD_CPPFUNC float __tg_cos(float x) { return ::cos(x); } +/*! @abstract Do not call this function directly; use simd::cos instead. */ +static SIMD_CPPFUNC double __tg_cos(double x) { return ::cos(x); } +/*! @abstract Do not call this function directly; use simd::sin instead. */ +static SIMD_CPPFUNC float __tg_sin(float x) { return ::sin(x); } +/*! @abstract Do not call this function directly; use simd::sin instead. */ +static SIMD_CPPFUNC double __tg_sin(double x) { return ::sin(x); } +/*! @abstract Do not call this function directly; use simd::tan instead. */ +static SIMD_CPPFUNC float __tg_tan(float x) { return ::tan(x); } +/*! @abstract Do not call this function directly; use simd::tan instead. */ +static SIMD_CPPFUNC double __tg_tan(double x) { return ::tan(x); } +/*! @abstract Do not call this function directly; use simd::cospi instead. */ +static SIMD_CPPFUNC float __tg_cospi(float x) { return ::__cospi(x); } +/*! @abstract Do not call this function directly; use simd::cospi instead. */ +static SIMD_CPPFUNC double __tg_cospi(double x) { return ::__cospi(x); } +/*! @abstract Do not call this function directly; use simd::sinpi instead. */ +static SIMD_CPPFUNC float __tg_sinpi(float x) { return ::__sinpi(x); } +/*! @abstract Do not call this function directly; use simd::sinpi instead. */ +static SIMD_CPPFUNC double __tg_sinpi(double x) { return ::__sinpi(x); } +/*! @abstract Do not call this function directly; use simd::tanpi instead. */ +static SIMD_CPPFUNC float __tg_tanpi(float x) { return ::__tanpi(x); } +/*! @abstract Do not call this function directly; use simd::tanpi instead. */ +static SIMD_CPPFUNC double __tg_tanpi(double x) { return ::__tanpi(x); } +/*! @abstract Do not call this function directly; use simd::acosh instead. */ +static SIMD_CPPFUNC float __tg_acosh(float x) { return ::acosh(x); } +/*! @abstract Do not call this function directly; use simd::acosh instead. */ +static SIMD_CPPFUNC double __tg_acosh(double x) { return ::acosh(x); } +/*! @abstract Do not call this function directly; use simd::asinh instead. */ +static SIMD_CPPFUNC float __tg_asinh(float x) { return ::asinh(x); } +/*! @abstract Do not call this function directly; use simd::asinh instead. */ +static SIMD_CPPFUNC double __tg_asinh(double x) { return ::asinh(x); } +/*! @abstract Do not call this function directly; use simd::atanh instead. */ +static SIMD_CPPFUNC float __tg_atanh(float x) { return ::atanh(x); } +/*! @abstract Do not call this function directly; use simd::atanh instead. */ +static SIMD_CPPFUNC double __tg_atanh(double x) { return ::atanh(x); } +/*! @abstract Do not call this function directly; use simd::cosh instead. */ +static SIMD_CPPFUNC float __tg_cosh(float x) { return ::cosh(x); } +/*! @abstract Do not call this function directly; use simd::cosh instead. */ +static SIMD_CPPFUNC double __tg_cosh(double x) { return ::cosh(x); } +/*! @abstract Do not call this function directly; use simd::sinh instead. */ +static SIMD_CPPFUNC float __tg_sinh(float x) { return ::sinh(x); } +/*! @abstract Do not call this function directly; use simd::sinh instead. */ +static SIMD_CPPFUNC double __tg_sinh(double x) { return ::sinh(x); } +/*! @abstract Do not call this function directly; use simd::tanh instead. */ +static SIMD_CPPFUNC float __tg_tanh(float x) { return ::tanh(x); } +/*! @abstract Do not call this function directly; use simd::tanh instead. */ +static SIMD_CPPFUNC double __tg_tanh(double x) { return ::tanh(x); } +/*! @abstract Do not call this function directly; use simd::exp instead. */ +static SIMD_CPPFUNC float __tg_exp(float x) { return ::exp(x); } +/*! @abstract Do not call this function directly; use simd::exp instead. */ +static SIMD_CPPFUNC double __tg_exp(double x) { return ::exp(x); } +/*! @abstract Do not call this function directly; use simd::exp2 instead. */ +static SIMD_CPPFUNC float __tg_exp2(float x) { return ::exp2(x); } +/*! @abstract Do not call this function directly; use simd::exp2 instead. */ +static SIMD_CPPFUNC double __tg_exp2(double x) { return ::exp2(x); } +/*! @abstract Do not call this function directly; use simd::exp10 instead. */ +static SIMD_CPPFUNC float __tg_exp10(float x) { return ::__exp10(x); } +/*! @abstract Do not call this function directly; use simd::exp10 instead. */ +static SIMD_CPPFUNC double __tg_exp10(double x) { return ::__exp10(x); } +/*! @abstract Do not call this function directly; use simd::expm1 instead. */ +static SIMD_CPPFUNC float __tg_expm1(float x) { return ::expm1(x); } +/*! @abstract Do not call this function directly; use simd::expm1 instead. */ +static SIMD_CPPFUNC double __tg_expm1(double x) { return ::expm1(x); } +/*! @abstract Do not call this function directly; use simd::log instead. */ +static SIMD_CPPFUNC float __tg_log(float x) { return ::log(x); } +/*! @abstract Do not call this function directly; use simd::log instead. */ +static SIMD_CPPFUNC double __tg_log(double x) { return ::log(x); } +/*! @abstract Do not call this function directly; use simd::log2 instead. */ +static SIMD_CPPFUNC float __tg_log2(float x) { return ::log2(x); } +/*! @abstract Do not call this function directly; use simd::log2 instead. */ +static SIMD_CPPFUNC double __tg_log2(double x) { return ::log2(x); } +/*! @abstract Do not call this function directly; use simd::log10 instead. */ +static SIMD_CPPFUNC float __tg_log10(float x) { return ::log10(x); } +/*! @abstract Do not call this function directly; use simd::log10 instead. */ +static SIMD_CPPFUNC double __tg_log10(double x) { return ::log10(x); } +/*! @abstract Do not call this function directly; use simd::log1p instead. */ +static SIMD_CPPFUNC float __tg_log1p(float x) { return ::log1p(x); } +/*! @abstract Do not call this function directly; use simd::log1p instead. */ +static SIMD_CPPFUNC double __tg_log1p(double x) { return ::log1p(x); } +/*! @abstract Do not call this function directly; use simd::fabs instead. */ +static SIMD_CPPFUNC float __tg_fabs(float x) { return ::fabs(x); } +/*! @abstract Do not call this function directly; use simd::fabs instead. */ +static SIMD_CPPFUNC double __tg_fabs(double x) { return ::fabs(x); } +/*! @abstract Do not call this function directly; use simd::cbrt instead. */ +static SIMD_CPPFUNC float __tg_cbrt(float x) { return ::cbrt(x); } +/*! @abstract Do not call this function directly; use simd::cbrt instead. */ +static SIMD_CPPFUNC double __tg_cbrt(double x) { return ::cbrt(x); } +/*! @abstract Do not call this function directly; use simd::sqrt instead. */ +static SIMD_CPPFUNC float __tg_sqrt(float x) { return ::sqrt(x); } +/*! @abstract Do not call this function directly; use simd::sqrt instead. */ +static SIMD_CPPFUNC double __tg_sqrt(double x) { return ::sqrt(x); } +/*! @abstract Do not call this function directly; use simd::erf instead. */ +static SIMD_CPPFUNC float __tg_erf(float x) { return ::erf(x); } +/*! @abstract Do not call this function directly; use simd::erf instead. */ +static SIMD_CPPFUNC double __tg_erf(double x) { return ::erf(x); } +/*! @abstract Do not call this function directly; use simd::erfc instead. */ +static SIMD_CPPFUNC float __tg_erfc(float x) { return ::erfc(x); } +/*! @abstract Do not call this function directly; use simd::erfc instead. */ +static SIMD_CPPFUNC double __tg_erfc(double x) { return ::erfc(x); } +/*! @abstract Do not call this function directly; use simd::tgamma instead. */ +static SIMD_CPPFUNC float __tg_tgamma(float x) { return ::tgamma(x); } +/*! @abstract Do not call this function directly; use simd::tgamma instead. */ +static SIMD_CPPFUNC double __tg_tgamma(double x) { return ::tgamma(x); } +/*! @abstract Do not call this function directly; use simd::ceil instead. */ +static SIMD_CPPFUNC float __tg_ceil(float x) { return ::ceil(x); } +/*! @abstract Do not call this function directly; use simd::ceil instead. */ +static SIMD_CPPFUNC double __tg_ceil(double x) { return ::ceil(x); } +/*! @abstract Do not call this function directly; use simd::floor instead. */ +static SIMD_CPPFUNC float __tg_floor(float x) { return ::floor(x); } +/*! @abstract Do not call this function directly; use simd::floor instead. */ +static SIMD_CPPFUNC double __tg_floor(double x) { return ::floor(x); } +/*! @abstract Do not call this function directly; use simd::rint instead. */ +static SIMD_CPPFUNC float __tg_rint(float x) { return ::rint(x); } +/*! @abstract Do not call this function directly; use simd::rint instead. */ +static SIMD_CPPFUNC double __tg_rint(double x) { return ::rint(x); } +/*! @abstract Do not call this function directly; use simd::round instead. */ +static SIMD_CPPFUNC float __tg_round(float x) { return ::round(x); } +/*! @abstract Do not call this function directly; use simd::round instead. */ +static SIMD_CPPFUNC double __tg_round(double x) { return ::round(x); } +/*! @abstract Do not call this function directly; use simd::trunc instead. */ +static SIMD_CPPFUNC float __tg_trunc(float x) { return ::trunc(x); } +/*! @abstract Do not call this function directly; use simd::trunc instead. */ +static SIMD_CPPFUNC double __tg_trunc(double x) { return ::trunc(x); } +/*! @abstract Do not call this function directly; use simd::atan2 instead. */ +static SIMD_CPPFUNC float __tg_atan2(float x, float y) { return ::atan2(x, y); } +/*! @abstract Do not call this function directly; use simd::atan2 instead. */ +static SIMD_CPPFUNC double __tg_atan2(double x, float y) { return ::atan2(x, y); } +/*! @abstract Do not call this function directly; use simd::hypot instead. */ +static SIMD_CPPFUNC float __tg_hypot(float x, float y) { return ::hypot(x, y); } +/*! @abstract Do not call this function directly; use simd::hypot instead. */ +static SIMD_CPPFUNC double __tg_hypot(double x, float y) { return ::hypot(x, y); } +/*! @abstract Do not call this function directly; use simd::pow instead. */ +static SIMD_CPPFUNC float __tg_pow(float x, float y) { return ::pow(x, y); } +/*! @abstract Do not call this function directly; use simd::pow instead. */ +static SIMD_CPPFUNC double __tg_pow(double x, float y) { return ::pow(x, y); } +/*! @abstract Do not call this function directly; use simd::fmod instead. */ +static SIMD_CPPFUNC float __tg_fmod(float x, float y) { return ::fmod(x, y); } +/*! @abstract Do not call this function directly; use simd::fmod instead. */ +static SIMD_CPPFUNC double __tg_fmod(double x, float y) { return ::fmod(x, y); } +/*! @abstract Do not call this function directly; use simd::remainder + * instead. */ +static SIMD_CPPFUNC float __tg_remainder(float x, float y) { return ::remainder(x, y); } +/*! @abstract Do not call this function directly; use simd::remainder + * instead. */ +static SIMD_CPPFUNC double __tg_remainder(double x, float y) { return ::remainder(x, y); } +/*! @abstract Do not call this function directly; use simd::copysign + * instead. */ +static SIMD_CPPFUNC float __tg_copysign(float x, float y) { return ::copysign(x, y); } +/*! @abstract Do not call this function directly; use simd::copysign + * instead. */ +static SIMD_CPPFUNC double __tg_copysign(double x, float y) { return ::copysign(x, y); } +/*! @abstract Do not call this function directly; use simd::nextafter + * instead. */ +static SIMD_CPPFUNC float __tg_nextafter(float x, float y) { return ::nextafter(x, y); } +/*! @abstract Do not call this function directly; use simd::nextafter + * instead. */ +static SIMD_CPPFUNC double __tg_nextafter(double x, float y) { return ::nextafter(x, y); } +/*! @abstract Do not call this function directly; use simd::fdim instead. */ +static SIMD_CPPFUNC float __tg_fdim(float x, float y) { return ::fdim(x, y); } +/*! @abstract Do not call this function directly; use simd::fdim instead. */ +static SIMD_CPPFUNC double __tg_fdim(double x, float y) { return ::fdim(x, y); } +/*! @abstract Do not call this function directly; use simd::fmax instead. */ +static SIMD_CPPFUNC float __tg_fmax(float x, float y) { return ::fmax(x, y); } +/*! @abstract Do not call this function directly; use simd::fmax instead. */ +static SIMD_CPPFUNC double __tg_fmax(double x, float y) { return ::fmax(x, y); } +/*! @abstract Do not call this function directly; use simd::fmin instead. */ +static SIMD_CPPFUNC float __tg_fmin(float x, float y) { return ::fmin(x, y); } +/*! @abstract Do not call this function directly; use simd::fmin instead. */ +static SIMD_CPPFUNC double __tg_fmin(double x, float y) { return ::fmin(x, y); } +/*! @abstract Do not call this function directly; use simd::fma instead. */ +static SIMD_CPPFUNC float __tg_fma(float x, float y, float z) { return ::fma(x, y, z); } +/*! @abstract Do not call this function directly; use simd::fma instead. */ +static SIMD_CPPFUNC double __tg_fma(double x, double y, double z) { return ::fma(x, y, z); } + +namespace simd { +/*! @abstract Generalizes the function acos to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN acos(fptypeN x) { return ::__tg_acos(x); } + +/*! @abstract Generalizes the function asin to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN asin(fptypeN x) { return ::__tg_asin(x); } + +/*! @abstract Generalizes the function atan to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN atan(fptypeN x) { return ::__tg_atan(x); } + +/*! @abstract Generalizes the function cos to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN cos(fptypeN x) { return ::__tg_cos(x); } + +/*! @abstract Generalizes the function sin to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN sin(fptypeN x) { return ::__tg_sin(x); } + +/*! @abstract Generalizes the function tan to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN tan(fptypeN x) { return ::__tg_tan(x); } + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Generalizes the function cospi to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN cospi(fptypeN x) { return ::__tg_cospi(x); } +#endif + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Generalizes the function sinpi to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN sinpi(fptypeN x) { return ::__tg_sinpi(x); } +#endif + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Generalizes the function tanpi to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN tanpi(fptypeN x) { return ::__tg_tanpi(x); } +#endif + +/*! @abstract Generalizes the function acosh to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN acosh(fptypeN x) { return ::__tg_acosh(x); } + +/*! @abstract Generalizes the function asinh to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN asinh(fptypeN x) { return ::__tg_asinh(x); } + +/*! @abstract Generalizes the function atanh to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN atanh(fptypeN x) { return ::__tg_atanh(x); } + +/*! @abstract Generalizes the function cosh to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN cosh(fptypeN x) { return ::__tg_cosh(x); } + +/*! @abstract Generalizes the function sinh to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN sinh(fptypeN x) { return ::__tg_sinh(x); } + +/*! @abstract Generalizes the function tanh to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN tanh(fptypeN x) { return ::__tg_tanh(x); } + +/*! @abstract Generalizes the function exp to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN exp(fptypeN x) { return ::__tg_exp(x); } + +/*! @abstract Generalizes the function exp2 to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN exp2(fptypeN x) { return ::__tg_exp2(x); } + +#if SIMD_LIBRARY_VERSION >= 1 +/*! @abstract Generalizes the function exp10 to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN exp10(fptypeN x) { return ::__tg_exp10(x); } +#endif + +/*! @abstract Generalizes the function expm1 to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN expm1(fptypeN x) { return ::__tg_expm1(x); } + +/*! @abstract Generalizes the function log to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN log(fptypeN x) { return ::__tg_log(x); } + +/*! @abstract Generalizes the function log2 to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN log2(fptypeN x) { return ::__tg_log2(x); } + +/*! @abstract Generalizes the function log10 to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN log10(fptypeN x) { return ::__tg_log10(x); } + +/*! @abstract Generalizes the function log1p to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN log1p(fptypeN x) { return ::__tg_log1p(x); } + +/*! @abstract Generalizes the function fabs to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN fabs(fptypeN x) { return ::__tg_fabs(x); } + +/*! @abstract Generalizes the function cbrt to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN cbrt(fptypeN x) { return ::__tg_cbrt(x); } + +/*! @abstract Generalizes the function sqrt to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN sqrt(fptypeN x) { return ::__tg_sqrt(x); } + +/*! @abstract Generalizes the function erf to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN erf(fptypeN x) { return ::__tg_erf(x); } + +/*! @abstract Generalizes the function erfc to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN erfc(fptypeN x) { return ::__tg_erfc(x); } + +/*! @abstract Generalizes the function tgamma to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN tgamma(fptypeN x) { return ::__tg_tgamma(x); } + +/*! @abstract Generalizes the function ceil to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN ceil(fptypeN x) { return ::__tg_ceil(x); } + +/*! @abstract Generalizes the function floor to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN floor(fptypeN x) { return ::__tg_floor(x); } + +/*! @abstract Generalizes the function rint to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN rint(fptypeN x) { return ::__tg_rint(x); } + +/*! @abstract Generalizes the function round to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN round(fptypeN x) { return ::__tg_round(x); } + +/*! @abstract Generalizes the function trunc to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN trunc(fptypeN x) { return ::__tg_trunc(x); } + +/*! @abstract Generalizes the function atan2 to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN atan2(fptypeN y, fptypeN x) { return ::__tg_atan2(y, x); } + +/*! @abstract Generalizes the function hypot to operate on vectors + * of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN hypot(fptypeN x, fptypeN y) { return ::__tg_hypot(x, y); } + +/*! @abstract Generalizes the function pow to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN pow(fptypeN x, fptypeN y) { return ::__tg_pow(x, y); } + +/*! @abstract Generalizes the function fmod to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN fmod(fptypeN x, fptypeN y) { return ::__tg_fmod(x, y); } + +/*! @abstract Generalizes the function remainder to operate on + * vectors of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN remainder(fptypeN x, fptypeN y) { return ::__tg_remainder(x, y); } + +/*! @abstract Generalizes the function copysign to operate on + * vectors of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN copysign(fptypeN x, fptypeN y) { return ::__tg_copysign(x, y); } + +/*! @abstract Generalizes the function nextafter to operate on + * vectors of floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN nextafter(fptypeN x, fptypeN y) { return ::__tg_nextafter(x, y); } + +/*! @abstract Generalizes the function fdim to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN fdim(fptypeN x, fptypeN y) { return ::__tg_fdim(x, y); } + +/*! @abstract Generalizes the function fmax to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN fmax(fptypeN x, fptypeN y) { return ::__tg_fmax(x, y); } + +/*! @abstract Generalizes the function fmin to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN fmin(fptypeN x, fptypeN y) { return ::__tg_fmin(x, y); } + +/*! @abstract Generalizes the function fma to operate on vectors of + * floats and doubles. */ + template + static SIMD_CPPFUNC fptypeN fma(fptypeN x, fptypeN y, fptypeN z) { return ::__tg_fma(x, y, z); } + +/*! @abstract Computes x*y + z by the most efficient means available; either + * a fused multiply add or separate multiply and add. */ + template + static SIMD_CPPFUNC fptypeN muladd(fptypeN x, fptypeN y, fptypeN z) { return ::simd_muladd(x, y, z); } +}; + +extern "C" { +#else +#include +/* C and Objective-C, we need some infrastructure to piggyback on tgmath.h */ +static SIMD_OVERLOAD simd_float2 __tg_promote(simd_float2); +static SIMD_OVERLOAD simd_float3 __tg_promote(simd_float3); +static SIMD_OVERLOAD simd_float4 __tg_promote(simd_float4); +static SIMD_OVERLOAD simd_float8 __tg_promote(simd_float8); +static SIMD_OVERLOAD simd_float16 __tg_promote(simd_float16); +static SIMD_OVERLOAD simd_double2 __tg_promote(simd_double2); +static SIMD_OVERLOAD simd_double3 __tg_promote(simd_double3); +static SIMD_OVERLOAD simd_double4 __tg_promote(simd_double4); +static SIMD_OVERLOAD simd_double8 __tg_promote(simd_double8); + +/* Apple extensions to , added in macOS 10.9 and iOS 7.0 */ +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9 || \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || \ + __DRIVERKIT_VERSION_MIN_REQUIRED >= __DRIVERKIT_19_0 +static inline SIMD_CFUNC float __tg_cospi(float x) { return __cospif(x); } +static inline SIMD_CFUNC double __tg_cospi(double x) { return __cospi(x); } +#undef cospi +/*! @abstract `cospi(x)` computes `cos(pi * x)` without intermediate rounding. + * + * @discussion Both faster and more accurate than multiplying by `pi` and then + * calling `cos`. Defined for `float` and `double` as well as vectors of + * floats and doubles as provided by ``. */ +#define cospi(__x) __tg_cospi(__tg_promote1((__x))(__x)) + +static inline SIMD_CFUNC float __tg_sinpi(float x) { return __sinpif(x); } +static inline SIMD_CFUNC double __tg_sinpi(double x) { return __sinpi(x); } +#undef sinpi +/*! @abstract `sinpi(x)` computes `sin(pi * x)` without intermediate rounding. + * + * @discussion Both faster and more accurate than multiplying by `pi` and then + * calling `sin`. Defined for `float` and `double` as well as vectors + * of floats and doubles as provided by ``. */ +#define sinpi(__x) __tg_sinpi(__tg_promote1((__x))(__x)) + +static inline SIMD_CFUNC float __tg_tanpi(float x) { return __tanpif(x); } +static inline SIMD_CFUNC double __tg_tanpi(double x) { return __tanpi(x); } +#undef tanpi +/*! @abstract `tanpi(x)` computes `tan(pi * x)` without intermediate rounding. + * + * @discussion Both faster and more accurate than multiplying by `pi` and then + * calling `tan`. Defined for `float` and `double` as well as vectors of + * floats and doubles as provided by ``. */ +#define tanpi(__x) __tg_tanpi(__tg_promote1((__x))(__x)) + +static inline SIMD_CFUNC float __tg_exp10(float x) { return __exp10f(x); } +static inline SIMD_CFUNC double __tg_exp10(double x) { return __exp10(x); } +#undef exp10 +/*! @abstract `exp10(x)` computes `10**x` more efficiently and accurately + * than `pow(10, x)`. + * + * @discussion Defined for `float` and `double` as well as vectors of floats + * and doubles as provided by ``. */ +#define exp10(__x) __tg_exp10(__tg_promote1((__x))(__x)) +#endif + + +#endif /* !__cplusplus */ + +#pragma mark - fabs implementation +static inline SIMD_CFUNC simd_float2 __tg_fabs(simd_float2 x) { return simd_bitselect(0.0, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float3 __tg_fabs(simd_float3 x) { return simd_bitselect(0.0, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float4 __tg_fabs(simd_float4 x) { return simd_bitselect(0.0, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float8 __tg_fabs(simd_float8 x) { return simd_bitselect(0.0, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float16 __tg_fabs(simd_float16 x) { return simd_bitselect(0.0, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_double2 __tg_fabs(simd_double2 x) { return simd_bitselect(0.0, x, 0x7fffffffffffffffL); } +static inline SIMD_CFUNC simd_double3 __tg_fabs(simd_double3 x) { return simd_bitselect(0.0, x, 0x7fffffffffffffffL); } +static inline SIMD_CFUNC simd_double4 __tg_fabs(simd_double4 x) { return simd_bitselect(0.0, x, 0x7fffffffffffffffL); } +static inline SIMD_CFUNC simd_double8 __tg_fabs(simd_double8 x) { return simd_bitselect(0.0, x, 0x7fffffffffffffffL); } + +#pragma mark - fmin, fmax implementation +static SIMD_CFUNC simd_float2 __tg_fmin(simd_float2 x, simd_float2 y) { +#if defined __SSE2__ + return simd_make_float2(__tg_fmin(simd_make_float4_undef(x), simd_make_float4_undef(y))); +#elif defined __arm64__ + return vminnm_f32(x, y); +#elif defined __arm__ && __FINITE_MATH_ONLY__ + return vmin_f32(x, y); +#else + return simd_bitselect(y, x, (x <= y) | (y != y)); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_fmin(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_fmin(simd_make_float4_undef(x), simd_make_float4_undef(y))); +} + +static SIMD_CFUNC simd_float4 __tg_fmin(simd_float4 x, simd_float4 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ && !__FINITE_MATH_ONLY__ + return _mm_range_ps(x, y, 4); +#elif defined __SSE2__ && __FINITE_MATH_ONLY__ + return _mm_min_ps(x, y); +#elif defined __SSE2__ + return simd_bitselect(_mm_min_ps(x, y), x, y != y); +#elif defined __arm64__ + return vminnmq_f32(x, y); +#elif defined __arm__ && __FINITE_MATH_ONLY__ + return vminq_f32(x, y); +#else + return simd_bitselect(y, x, (x <= y) | (y != y)); +#endif +} + +static SIMD_CFUNC simd_float8 __tg_fmin(simd_float8 x, simd_float8 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ && !__FINITE_MATH_ONLY__ + return _mm256_range_ps(x, y, 4); +#elif defined __AVX__ && __FINITE_MATH_ONLY__ + return _mm256_min_ps(x, y); +#elif defined __AVX__ + return simd_bitselect(_mm256_min_ps(x, y), x, y != y); +#else + return simd_make_float8(__tg_fmin(x.lo, y.lo), __tg_fmin(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_fmin(simd_float16 x, simd_float16 y) { +#if defined __x86_64__ && defined __AVX512DQ__ && !__FINITE_MATH_ONLY__ + return _mm512_range_ps(x, y, 4); +#elif defined __x86_64__ && defined __AVX512F__ && __FINITE_MATH_ONLY__ + return _mm512_min_ps(x, y); +#elif defined __x86_64__ && defined __AVX512F__ + return simd_bitselect(_mm512_min_ps(x, y), x, y != y); +#else + return simd_make_float16(__tg_fmin(x.lo, y.lo), __tg_fmin(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_double2 __tg_fmin(simd_double2 x, simd_double2 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ + return _mm_range_pd(x, y, 4); +#elif defined __SSE2__ && __FINITE_MATH_ONLY__ + return _mm_min_pd(x, y); +#elif defined __SSE2__ + return simd_bitselect(_mm_min_pd(x, y), x, y != y); +#elif defined __arm64__ + return vminnmq_f64(x, y); +#else + return simd_bitselect(y, x, (x <= y) | (y != y)); +#endif +} + +static SIMD_CFUNC simd_double3 __tg_fmin(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_fmin(simd_make_double4_undef(x), simd_make_double4_undef(y))); +} + +static SIMD_CFUNC simd_double4 __tg_fmin(simd_double4 x, simd_double4 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ + return _mm256_range_pd(x, y, 4); +#elif defined __AVX__ && __FINITE_MATH_ONLY__ + return _mm256_min_pd(x, y); +#elif defined __AVX__ + return simd_bitselect(_mm256_min_pd(x, y), x, y != y); +#else + return simd_make_double4(__tg_fmin(x.lo, y.lo), __tg_fmin(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_fmin(simd_double8 x, simd_double8 y) { +#if defined __x86_64__ && defined __AVX512DQ__ + return _mm512_range_pd(x, y, 4); +#elif defined __x86_64__ && defined __AVX512F__ && __FINITE_MATH_ONLY__ + return _mm512_min_pd(x, y); +#elif defined __x86_64__ && defined __AVX512F__ + return simd_bitselect(_mm512_min_pd(x, y), x, y != y); +#else + return simd_make_double8(__tg_fmin(x.lo, y.lo), __tg_fmin(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_float2 __tg_fmax(simd_float2 x, simd_float2 y) { +#if defined __SSE2__ + return simd_make_float2(__tg_fmax(simd_make_float4_undef(x), simd_make_float4_undef(y))); +#elif defined __arm64__ + return vmaxnm_f32(x, y); +#elif defined __arm__ && __FINITE_MATH_ONLY__ + return vmax_f32(x, y); +#else + return simd_bitselect(y, x, (x >= y) | (y != y)); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_fmax(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_fmax(simd_make_float4_undef(x), simd_make_float4_undef(y))); +} + +static SIMD_CFUNC simd_float4 __tg_fmax(simd_float4 x, simd_float4 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ && !__FINITE_MATH_ONLY__ + return _mm_range_ps(x, y, 5); +#elif defined __SSE2__ && __FINITE_MATH_ONLY__ + return _mm_max_ps(x, y); +#elif defined __SSE2__ + return simd_bitselect(_mm_max_ps(x, y), x, y != y); +#elif defined __arm64__ + return vmaxnmq_f32(x, y); +#elif defined __arm__ && __FINITE_MATH_ONLY__ + return vmaxq_f32(x, y); +#else + return simd_bitselect(y, x, (x >= y) | (y != y)); +#endif +} + +static SIMD_CFUNC simd_float8 __tg_fmax(simd_float8 x, simd_float8 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ && !__FINITE_MATH_ONLY__ + return _mm256_range_ps(x, y, 5); +#elif defined __AVX__ && __FINITE_MATH_ONLY__ + return _mm256_max_ps(x, y); +#elif defined __AVX__ + return simd_bitselect(_mm256_max_ps(x, y), x, y != y); +#else + return simd_make_float8(__tg_fmax(x.lo, y.lo), __tg_fmax(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_fmax(simd_float16 x, simd_float16 y) { +#if defined __x86_64__ && defined __AVX512DQ__ && !__FINITE_MATH_ONLY__ + return _mm512_range_ps(x, y, 5); +#elif defined __x86_64__ && defined __AVX512F__ && __FINITE_MATH_ONLY__ + return _mm512_max_ps(x, y); +#elif defined __x86_64__ && defined __AVX512F__ + return simd_bitselect(_mm512_max_ps(x, y), x, y != y); +#else + return simd_make_float16(__tg_fmax(x.lo, y.lo), __tg_fmax(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_double2 __tg_fmax(simd_double2 x, simd_double2 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ + return _mm_range_pd(x, y, 5); +#elif defined __SSE2__ && __FINITE_MATH_ONLY__ + return _mm_max_pd(x, y); +#elif defined __SSE2__ + return simd_bitselect(_mm_max_pd(x, y), x, y != y); +#elif defined __arm64__ + return vmaxnmq_f64(x, y); +#else + return simd_bitselect(y, x, (x >= y) | (y != y)); +#endif +} + +static SIMD_CFUNC simd_double3 __tg_fmax(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_fmax(simd_make_double4_undef(x), simd_make_double4_undef(y))); +} + +static SIMD_CFUNC simd_double4 __tg_fmax(simd_double4 x, simd_double4 y) { +#if defined __AVX512DQ__ && defined __AVX512VL__ + return _mm256_range_pd(x, y, 5); +#elif defined __AVX__ && __FINITE_MATH_ONLY__ + return _mm256_max_pd(x, y); +#elif defined __AVX__ + return simd_bitselect(_mm256_max_pd(x, y), x, y != y); +#else + return simd_make_double4(__tg_fmax(x.lo, y.lo), __tg_fmax(x.hi, y.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_fmax(simd_double8 x, simd_double8 y) { +#if defined __x86_64__ && defined __AVX512DQ__ + return _mm512_range_pd(x, y, 5); +#elif defined __x86_64__ && defined __AVX512F__ && __FINITE_MATH_ONLY__ + return _mm512_max_pd(x, y); +#elif defined __x86_64__ && defined __AVX512F__ + return simd_bitselect(_mm512_max_pd(x, y), x, y != y); +#else + return simd_make_double8(__tg_fmax(x.lo, y.lo), __tg_fmax(x.hi, y.hi)); +#endif +} + +#pragma mark - copysign implementation +static inline SIMD_CFUNC simd_float2 __tg_copysign(simd_float2 x, simd_float2 y) { return simd_bitselect(y, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float3 __tg_copysign(simd_float3 x, simd_float3 y) { return simd_bitselect(y, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float4 __tg_copysign(simd_float4 x, simd_float4 y) { return simd_bitselect(y, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float8 __tg_copysign(simd_float8 x, simd_float8 y) { return simd_bitselect(y, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_float16 __tg_copysign(simd_float16 x, simd_float16 y) { return simd_bitselect(y, x, 0x7fffffff); } +static inline SIMD_CFUNC simd_double2 __tg_copysign(simd_double2 x, simd_double2 y) { return simd_bitselect(y, x, 0x7fffffffffffffffL); } +static inline SIMD_CFUNC simd_double3 __tg_copysign(simd_double3 x, simd_double3 y) { return simd_bitselect(y, x, 0x7fffffffffffffffL); } +static inline SIMD_CFUNC simd_double4 __tg_copysign(simd_double4 x, simd_double4 y) { return simd_bitselect(y, x, 0x7fffffffffffffffL); } +static inline SIMD_CFUNC simd_double8 __tg_copysign(simd_double8 x, simd_double8 y) { return simd_bitselect(y, x, 0x7fffffffffffffffL); } + +#pragma mark - sqrt implementation +static SIMD_CFUNC simd_float2 __tg_sqrt(simd_float2 x) { +#if defined __SSE2__ + return simd_make_float2(__tg_sqrt(simd_make_float4_undef(x))); +#elif defined __arm64__ + return vsqrt_f32(x); +#else + return simd_make_float2(sqrt(x.x), sqrt(x.y)); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_sqrt(simd_float3 x) { + return simd_make_float3(__tg_sqrt(simd_make_float4_undef(x))); +} + +static SIMD_CFUNC simd_float4 __tg_sqrt(simd_float4 x) { +#if defined __SSE2__ + return _mm_sqrt_ps(x); +#elif defined __arm64__ + return vsqrtq_f32(x); +#else + return simd_make_float4(__tg_sqrt(x.lo), __tg_sqrt(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float8 __tg_sqrt(simd_float8 x) { +#if defined __AVX__ + return _mm256_sqrt_ps(x); +#else + return simd_make_float8(__tg_sqrt(x.lo), __tg_sqrt(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_sqrt(simd_float16 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_sqrt_ps(x); +#else + return simd_make_float16(__tg_sqrt(x.lo), __tg_sqrt(x.hi)); +#endif +} + +static SIMD_CFUNC simd_double2 __tg_sqrt(simd_double2 x) { +#if defined __SSE2__ + return _mm_sqrt_pd(x); +#elif defined __arm64__ + return vsqrtq_f64(x); +#else + return simd_make_double2(sqrt(x.x), sqrt(x.y)); +#endif +} + +static SIMD_CFUNC simd_double3 __tg_sqrt(simd_double3 x) { + return simd_make_double3(__tg_sqrt(simd_make_double4_undef(x))); +} + +static SIMD_CFUNC simd_double4 __tg_sqrt(simd_double4 x) { +#if defined __AVX__ + return _mm256_sqrt_pd(x); +#else + return simd_make_double4(__tg_sqrt(x.lo), __tg_sqrt(x.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_sqrt(simd_double8 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_sqrt_pd(x); +#else + return simd_make_double8(__tg_sqrt(x.lo), __tg_sqrt(x.hi)); +#endif +} + +#pragma mark - ceil, floor, rint, trunc implementation +static SIMD_CFUNC simd_float2 __tg_ceil(simd_float2 x) { +#if defined __arm64__ + return vrndp_f32(x); +#else + return simd_make_float2(__tg_ceil(simd_make_float4_undef(x))); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_ceil(simd_float3 x) { + return simd_make_float3(__tg_ceil(simd_make_float4_undef(x))); +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_ceil_f4(simd_float4 x); +#endif + +static SIMD_CFUNC simd_float4 __tg_ceil(simd_float4 x) { +#if defined __SSE4_1__ + return _mm_round_ps(x, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +#elif defined __arm64__ + return vrndpq_f32(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_ceil_f4(x); +#else + simd_float4 truncated = __tg_trunc(x); + simd_float4 adjust = simd_bitselect((simd_float4)0, 1, truncated < x); + return __tg_copysign(truncated + adjust, x); +#endif +} + +static SIMD_CFUNC simd_float8 __tg_ceil(simd_float8 x) { +#if defined __AVX__ + return _mm256_round_ps(x, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_float8(__tg_ceil(x.lo), __tg_ceil(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_ceil(simd_float16 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_ps(x, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_float16(__tg_ceil(x.lo), __tg_ceil(x.hi)); +#endif +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_ceil_d2(simd_double2 x); +#endif + +static SIMD_CFUNC simd_double2 __tg_ceil(simd_double2 x) { +#if defined __SSE4_1__ + return _mm_round_pd(x, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +#elif defined __arm64__ + return vrndpq_f64(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_ceil_d2(x); +#else + simd_double2 truncated = __tg_trunc(x); + simd_double2 adjust = simd_bitselect((simd_double2)0, 1, truncated < x); + return __tg_copysign(truncated + adjust, x); +#endif +} + +static SIMD_CFUNC simd_double3 __tg_ceil(simd_double3 x) { + return simd_make_double3(__tg_ceil(simd_make_double4_undef(x))); +} + +static SIMD_CFUNC simd_double4 __tg_ceil(simd_double4 x) { +#if defined __AVX__ + return _mm256_round_pd(x, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_double4(__tg_ceil(x.lo), __tg_ceil(x.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_ceil(simd_double8 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_pd(x, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_double8(__tg_ceil(x.lo), __tg_ceil(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float2 __tg_floor(simd_float2 x) { +#if defined __arm64__ + return vrndm_f32(x); +#else + return simd_make_float2(__tg_floor(simd_make_float4_undef(x))); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_floor(simd_float3 x) { + return simd_make_float3(__tg_floor(simd_make_float4_undef(x))); +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_floor_f4(simd_float4 x); +#endif + +static SIMD_CFUNC simd_float4 __tg_floor(simd_float4 x) { +#if defined __SSE4_1__ + return _mm_round_ps(x, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#elif defined __arm64__ + return vrndmq_f32(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_floor_f4(x); +#else + simd_float4 truncated = __tg_trunc(x); + simd_float4 adjust = simd_bitselect((simd_float4)0, 1, truncated > x); + return truncated - adjust; +#endif +} + +static SIMD_CFUNC simd_float8 __tg_floor(simd_float8 x) { +#if defined __AVX__ + return _mm256_round_ps(x, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_float8(__tg_floor(x.lo), __tg_floor(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_floor(simd_float16 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_ps(x, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_float16(__tg_floor(x.lo), __tg_floor(x.hi)); +#endif +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_floor_d2(simd_double2 x); +#endif + +static SIMD_CFUNC simd_double2 __tg_floor(simd_double2 x) { +#if defined __SSE4_1__ + return _mm_round_pd(x, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#elif defined __arm64__ + return vrndmq_f64(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_floor_d2(x); +#else + simd_double2 truncated = __tg_trunc(x); + simd_double2 adjust = simd_bitselect((simd_double2)0, 1, truncated > x); + return truncated - adjust; +#endif +} + +static SIMD_CFUNC simd_double3 __tg_floor(simd_double3 x) { + return simd_make_double3(__tg_floor(simd_make_double4_undef(x))); +} + +static SIMD_CFUNC simd_double4 __tg_floor(simd_double4 x) { +#if defined __AVX__ + return _mm256_round_pd(x, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_double4(__tg_floor(x.lo), __tg_floor(x.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_floor(simd_double8 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_pd(x, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#else + return simd_make_double8(__tg_floor(x.lo), __tg_floor(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float2 __tg_rint(simd_float2 x) { +#if defined __arm64__ + return vrndx_f32(x); +#else + return simd_make_float2(__tg_rint(simd_make_float4_undef(x))); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_rint(simd_float3 x) { + return simd_make_float3(__tg_rint(simd_make_float4_undef(x))); +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_rint_f4(simd_float4 x); +#endif + +static SIMD_CFUNC simd_float4 __tg_rint(simd_float4 x) { +#if defined __SSE4_1__ + return _mm_round_ps(x, _MM_FROUND_RINT); +#elif defined __arm64__ + return vrndxq_f32(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_rint_f4(x); +#else + simd_float4 magic = __tg_copysign(0x1.0p23, x); + simd_int4 x_is_small = __tg_fabs(x) < 0x1.0p23; + return simd_bitselect(x, (x + magic) - magic, x_is_small & 0x7fffffff); +#endif +} + +static SIMD_CFUNC simd_float8 __tg_rint(simd_float8 x) { +#if defined __AVX__ + return _mm256_round_ps(x, _MM_FROUND_RINT); +#else + return simd_make_float8(__tg_rint(x.lo), __tg_rint(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_rint(simd_float16 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_ps(x, _MM_FROUND_RINT); +#else + return simd_make_float16(__tg_rint(x.lo), __tg_rint(x.hi)); +#endif +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_rint_d2(simd_double2 x); +#endif + +static SIMD_CFUNC simd_double2 __tg_rint(simd_double2 x) { +#if defined __SSE4_1__ + return _mm_round_pd(x, _MM_FROUND_RINT); +#elif defined __arm64__ + return vrndxq_f64(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_rint_d2(x); +#else + simd_double2 magic = __tg_copysign(0x1.0p52, x); + simd_long2 x_is_small = __tg_fabs(x) < 0x1.0p52; + return simd_bitselect(x, (x + magic) - magic, x_is_small & 0x7fffffffffffffff); +#endif +} + +static SIMD_CFUNC simd_double3 __tg_rint(simd_double3 x) { + return simd_make_double3(__tg_rint(simd_make_double4_undef(x))); +} + +static SIMD_CFUNC simd_double4 __tg_rint(simd_double4 x) { +#if defined __AVX__ + return _mm256_round_pd(x, _MM_FROUND_RINT); +#else + return simd_make_double4(__tg_rint(x.lo), __tg_rint(x.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_rint(simd_double8 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_pd(x, _MM_FROUND_RINT); +#else + return simd_make_double8(__tg_rint(x.lo), __tg_rint(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float2 __tg_trunc(simd_float2 x) { +#if defined __arm64__ + return vrnd_f32(x); +#else + return simd_make_float2(__tg_trunc(simd_make_float4_undef(x))); +#endif +} + +static SIMD_CFUNC simd_float3 __tg_trunc(simd_float3 x) { + return simd_make_float3(__tg_trunc(simd_make_float4_undef(x))); +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_trunc_f4(simd_float4 x); +#endif + +static SIMD_CFUNC simd_float4 __tg_trunc(simd_float4 x) { +#if defined __SSE4_1__ + return _mm_round_ps(x, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC); +#elif defined __arm64__ + return vrndq_f32(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_trunc_f4(x); +#else + simd_float4 binade = simd_bitselect(0, x, 0x7f800000); + simd_int4 mask = (simd_int4)__tg_fmin(-2*binade + 1, -0); + simd_float4 result = simd_bitselect(0, x, mask); + return simd_bitselect(x, result, binade < 0x1.0p23); +#endif +} + +static SIMD_CFUNC simd_float8 __tg_trunc(simd_float8 x) { +#if defined __AVX__ + return _mm256_round_ps(x, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC); +#else + return simd_make_float8(__tg_trunc(x.lo), __tg_trunc(x.hi)); +#endif +} + +static SIMD_CFUNC simd_float16 __tg_trunc(simd_float16 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_ps(x, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC); +#else + return simd_make_float16(__tg_trunc(x.lo), __tg_trunc(x.hi)); +#endif +} + +#if defined __arm__ && SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_trunc_d2(simd_double2 x); +#endif + +static SIMD_CFUNC simd_double2 __tg_trunc(simd_double2 x) { +#if defined __SSE4_1__ + return _mm_round_pd(x, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC); +#elif defined __arm64__ + return vrndq_f64(x); +#elif defined __arm__ && SIMD_LIBRARY_VERSION >= 3 + return _simd_trunc_d2(x); +#else + simd_double2 binade = simd_bitselect(0, x, 0x7ff0000000000000); + simd_long2 mask = (simd_long2)__tg_fmin(-2*binade + 1, -0); + simd_double2 result = simd_bitselect(0, x, mask); + return simd_bitselect(x, result, binade < 0x1.0p52); +#endif +} + +static SIMD_CFUNC simd_double3 __tg_trunc(simd_double3 x) { + return simd_make_double3(__tg_trunc(simd_make_double4_undef(x))); +} + +static SIMD_CFUNC simd_double4 __tg_trunc(simd_double4 x) { +#if defined __AVX__ + return _mm256_round_pd(x, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC); +#else + return simd_make_double4(__tg_trunc(x.lo), __tg_trunc(x.hi)); +#endif +} + +static SIMD_CFUNC simd_double8 __tg_trunc(simd_double8 x) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_roundscale_pd(x, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC); +#else + return simd_make_double8(__tg_trunc(x.lo), __tg_trunc(x.hi)); +#endif +} + +#pragma mark - sine, cosine implementation +static inline SIMD_CFUNC simd_float2 __tg_sin(simd_float2 x) { + return simd_make_float2(__tg_sin(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_sin(simd_float3 x) { + return simd_make_float3(__tg_sin(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_sin_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_sin(simd_float4 x) { + return _simd_sin_f4(x); +} +#elif SIMD_LIBRARY_VERSION == 1 +extern simd_float4 __sin_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_sin(simd_float4 x) { + return __sin_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_sin(simd_float4 x) { + return simd_make_float4(sin(x.x), sin(x.y), sin(x.z), sin(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_sin_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_sin(simd_float8 x) { + return _simd_sin_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_sin(simd_float8 x) { + return simd_make_float8(__tg_sin(x.lo), __tg_sin(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_sin_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_sin(simd_float16 x) { + return _simd_sin_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_sin(simd_float16 x) { + return simd_make_float16(__tg_sin(x.lo), __tg_sin(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_sin_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_sin(simd_double2 x) { + return _simd_sin_d2(x); +} +#elif SIMD_LIBRARY_VERSION == 1 +extern simd_double2 __sin_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_sin(simd_double2 x) { + return __sin_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_sin(simd_double2 x) { + return simd_make_double2(sin(x.x), sin(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_sin(simd_double3 x) { + return simd_make_double3(__tg_sin(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_sin_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_sin(simd_double4 x) { + return _simd_sin_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_sin(simd_double4 x) { + return simd_make_double4(__tg_sin(x.lo), __tg_sin(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_sin_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_sin(simd_double8 x) { + return _simd_sin_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_sin(simd_double8 x) { + return simd_make_double8(__tg_sin(x.lo), __tg_sin(x.hi)); +} +#endif + +static inline SIMD_CFUNC simd_float2 __tg_cos(simd_float2 x) { + return simd_make_float2(__tg_cos(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_cos(simd_float3 x) { + return simd_make_float3(__tg_cos(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_cos_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_cos(simd_float4 x) { + return _simd_cos_f4(x); +} +#elif SIMD_LIBRARY_VERSION == 1 +extern simd_float4 __cos_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_cos(simd_float4 x) { + return __cos_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_cos(simd_float4 x) { + return simd_make_float4(cos(x.x), cos(x.y), cos(x.z), cos(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_cos_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_cos(simd_float8 x) { + return _simd_cos_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_cos(simd_float8 x) { + return simd_make_float8(__tg_cos(x.lo), __tg_cos(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_cos_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_cos(simd_float16 x) { + return _simd_cos_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_cos(simd_float16 x) { + return simd_make_float16(__tg_cos(x.lo), __tg_cos(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_cos_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_cos(simd_double2 x) { + return _simd_cos_d2(x); +} +#elif SIMD_LIBRARY_VERSION == 1 +extern simd_double2 __cos_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_cos(simd_double2 x) { + return __cos_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_cos(simd_double2 x) { + return simd_make_double2(cos(x.x), cos(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_cos(simd_double3 x) { + return simd_make_double3(__tg_cos(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_cos_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_cos(simd_double4 x) { + return _simd_cos_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_cos(simd_double4 x) { + return simd_make_double4(__tg_cos(x.lo), __tg_cos(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_cos_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_cos(simd_double8 x) { + return _simd_cos_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_cos(simd_double8 x) { + return simd_make_double8(__tg_cos(x.lo), __tg_cos(x.hi)); +} +#endif + + +#pragma mark - acos implementation +static inline SIMD_CFUNC simd_float2 __tg_acos(simd_float2 x) { + return simd_make_float2(__tg_acos(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_acos(simd_float3 x) { + return simd_make_float3(__tg_acos(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_acos_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_acos(simd_float4 x) { + return _simd_acos_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_acos(simd_float4 x) { + return simd_make_float4(acos(x.x), acos(x.y), acos(x.z), acos(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_acos_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_acos(simd_float8 x) { + return _simd_acos_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_acos(simd_float8 x) { + return simd_make_float8(__tg_acos(x.lo), __tg_acos(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_acos_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_acos(simd_float16 x) { + return _simd_acos_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_acos(simd_float16 x) { + return simd_make_float16(__tg_acos(x.lo), __tg_acos(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_acos_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_acos(simd_double2 x) { + return _simd_acos_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_acos(simd_double2 x) { + return simd_make_double2(acos(x.x), acos(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_acos(simd_double3 x) { + return simd_make_double3(__tg_acos(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_acos_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_acos(simd_double4 x) { + return _simd_acos_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_acos(simd_double4 x) { + return simd_make_double4(__tg_acos(x.lo), __tg_acos(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_acos_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_acos(simd_double8 x) { + return _simd_acos_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_acos(simd_double8 x) { + return simd_make_double8(__tg_acos(x.lo), __tg_acos(x.hi)); +} +#endif + +#pragma mark - asin implementation +static inline SIMD_CFUNC simd_float2 __tg_asin(simd_float2 x) { + return simd_make_float2(__tg_asin(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_asin(simd_float3 x) { + return simd_make_float3(__tg_asin(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_asin_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_asin(simd_float4 x) { + return _simd_asin_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_asin(simd_float4 x) { + return simd_make_float4(asin(x.x), asin(x.y), asin(x.z), asin(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_asin_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_asin(simd_float8 x) { + return _simd_asin_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_asin(simd_float8 x) { + return simd_make_float8(__tg_asin(x.lo), __tg_asin(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_asin_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_asin(simd_float16 x) { + return _simd_asin_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_asin(simd_float16 x) { + return simd_make_float16(__tg_asin(x.lo), __tg_asin(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_asin_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_asin(simd_double2 x) { + return _simd_asin_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_asin(simd_double2 x) { + return simd_make_double2(asin(x.x), asin(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_asin(simd_double3 x) { + return simd_make_double3(__tg_asin(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_asin_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_asin(simd_double4 x) { + return _simd_asin_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_asin(simd_double4 x) { + return simd_make_double4(__tg_asin(x.lo), __tg_asin(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_asin_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_asin(simd_double8 x) { + return _simd_asin_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_asin(simd_double8 x) { + return simd_make_double8(__tg_asin(x.lo), __tg_asin(x.hi)); +} +#endif + +#pragma mark - atan implementation +static inline SIMD_CFUNC simd_float2 __tg_atan(simd_float2 x) { + return simd_make_float2(__tg_atan(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_atan(simd_float3 x) { + return simd_make_float3(__tg_atan(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_atan_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_atan(simd_float4 x) { + return _simd_atan_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_atan(simd_float4 x) { + return simd_make_float4(atan(x.x), atan(x.y), atan(x.z), atan(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_atan_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_atan(simd_float8 x) { + return _simd_atan_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_atan(simd_float8 x) { + return simd_make_float8(__tg_atan(x.lo), __tg_atan(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_atan_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_atan(simd_float16 x) { + return _simd_atan_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_atan(simd_float16 x) { + return simd_make_float16(__tg_atan(x.lo), __tg_atan(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_atan_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_atan(simd_double2 x) { + return _simd_atan_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_atan(simd_double2 x) { + return simd_make_double2(atan(x.x), atan(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_atan(simd_double3 x) { + return simd_make_double3(__tg_atan(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_atan_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_atan(simd_double4 x) { + return _simd_atan_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_atan(simd_double4 x) { + return simd_make_double4(__tg_atan(x.lo), __tg_atan(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_atan_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_atan(simd_double8 x) { + return _simd_atan_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_atan(simd_double8 x) { + return simd_make_double8(__tg_atan(x.lo), __tg_atan(x.hi)); +} +#endif + +#pragma mark - tan implementation +static inline SIMD_CFUNC simd_float2 __tg_tan(simd_float2 x) { + return simd_make_float2(__tg_tan(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_tan(simd_float3 x) { + return simd_make_float3(__tg_tan(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_tan_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_tan(simd_float4 x) { + return _simd_tan_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_tan(simd_float4 x) { + return simd_make_float4(tan(x.x), tan(x.y), tan(x.z), tan(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_tan_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_tan(simd_float8 x) { + return _simd_tan_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_tan(simd_float8 x) { + return simd_make_float8(__tg_tan(x.lo), __tg_tan(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_tan_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_tan(simd_float16 x) { + return _simd_tan_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_tan(simd_float16 x) { + return simd_make_float16(__tg_tan(x.lo), __tg_tan(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_tan_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_tan(simd_double2 x) { + return _simd_tan_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_tan(simd_double2 x) { + return simd_make_double2(tan(x.x), tan(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_tan(simd_double3 x) { + return simd_make_double3(__tg_tan(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_tan_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_tan(simd_double4 x) { + return _simd_tan_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_tan(simd_double4 x) { + return simd_make_double4(__tg_tan(x.lo), __tg_tan(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_tan_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_tan(simd_double8 x) { + return _simd_tan_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_tan(simd_double8 x) { + return simd_make_double8(__tg_tan(x.lo), __tg_tan(x.hi)); +} +#endif + +#pragma mark - cospi implementation +#if SIMD_LIBRARY_VERSION >= 1 +static inline SIMD_CFUNC simd_float2 __tg_cospi(simd_float2 x) { + return simd_make_float2(__tg_cospi(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_cospi(simd_float3 x) { + return simd_make_float3(__tg_cospi(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_cospi_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_cospi(simd_float4 x) { + return _simd_cospi_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_cospi(simd_float4 x) { + return simd_make_float4(__cospi(x.x), __cospi(x.y), __cospi(x.z), __cospi(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_cospi_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_cospi(simd_float8 x) { + return _simd_cospi_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_cospi(simd_float8 x) { + return simd_make_float8(__tg_cospi(x.lo), __tg_cospi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_cospi_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_cospi(simd_float16 x) { + return _simd_cospi_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_cospi(simd_float16 x) { + return simd_make_float16(__tg_cospi(x.lo), __tg_cospi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_cospi_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_cospi(simd_double2 x) { + return _simd_cospi_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_cospi(simd_double2 x) { + return simd_make_double2(__cospi(x.x), __cospi(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_cospi(simd_double3 x) { + return simd_make_double3(__tg_cospi(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_cospi_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_cospi(simd_double4 x) { + return _simd_cospi_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_cospi(simd_double4 x) { + return simd_make_double4(__tg_cospi(x.lo), __tg_cospi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_cospi_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_cospi(simd_double8 x) { + return _simd_cospi_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_cospi(simd_double8 x) { + return simd_make_double8(__tg_cospi(x.lo), __tg_cospi(x.hi)); +} +#endif + +#endif /* SIMD_LIBRARY_VERSION */ +#pragma mark - sinpi implementation +#if SIMD_LIBRARY_VERSION >= 1 +static inline SIMD_CFUNC simd_float2 __tg_sinpi(simd_float2 x) { + return simd_make_float2(__tg_sinpi(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_sinpi(simd_float3 x) { + return simd_make_float3(__tg_sinpi(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_sinpi_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_sinpi(simd_float4 x) { + return _simd_sinpi_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_sinpi(simd_float4 x) { + return simd_make_float4(__sinpi(x.x), __sinpi(x.y), __sinpi(x.z), __sinpi(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_sinpi_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_sinpi(simd_float8 x) { + return _simd_sinpi_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_sinpi(simd_float8 x) { + return simd_make_float8(__tg_sinpi(x.lo), __tg_sinpi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_sinpi_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_sinpi(simd_float16 x) { + return _simd_sinpi_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_sinpi(simd_float16 x) { + return simd_make_float16(__tg_sinpi(x.lo), __tg_sinpi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_sinpi_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_sinpi(simd_double2 x) { + return _simd_sinpi_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_sinpi(simd_double2 x) { + return simd_make_double2(__sinpi(x.x), __sinpi(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_sinpi(simd_double3 x) { + return simd_make_double3(__tg_sinpi(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_sinpi_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_sinpi(simd_double4 x) { + return _simd_sinpi_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_sinpi(simd_double4 x) { + return simd_make_double4(__tg_sinpi(x.lo), __tg_sinpi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_sinpi_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_sinpi(simd_double8 x) { + return _simd_sinpi_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_sinpi(simd_double8 x) { + return simd_make_double8(__tg_sinpi(x.lo), __tg_sinpi(x.hi)); +} +#endif + +#endif /* SIMD_LIBRARY_VERSION */ +#pragma mark - tanpi implementation +#if SIMD_LIBRARY_VERSION >= 1 +static inline SIMD_CFUNC simd_float2 __tg_tanpi(simd_float2 x) { + return simd_make_float2(__tg_tanpi(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_tanpi(simd_float3 x) { + return simd_make_float3(__tg_tanpi(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_tanpi_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_tanpi(simd_float4 x) { + return _simd_tanpi_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_tanpi(simd_float4 x) { + return simd_make_float4(__tanpi(x.x), __tanpi(x.y), __tanpi(x.z), __tanpi(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_tanpi_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_tanpi(simd_float8 x) { + return _simd_tanpi_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_tanpi(simd_float8 x) { + return simd_make_float8(__tg_tanpi(x.lo), __tg_tanpi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_tanpi_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_tanpi(simd_float16 x) { + return _simd_tanpi_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_tanpi(simd_float16 x) { + return simd_make_float16(__tg_tanpi(x.lo), __tg_tanpi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_tanpi_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_tanpi(simd_double2 x) { + return _simd_tanpi_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_tanpi(simd_double2 x) { + return simd_make_double2(__tanpi(x.x), __tanpi(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_tanpi(simd_double3 x) { + return simd_make_double3(__tg_tanpi(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_tanpi_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_tanpi(simd_double4 x) { + return _simd_tanpi_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_tanpi(simd_double4 x) { + return simd_make_double4(__tg_tanpi(x.lo), __tg_tanpi(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_tanpi_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_tanpi(simd_double8 x) { + return _simd_tanpi_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_tanpi(simd_double8 x) { + return simd_make_double8(__tg_tanpi(x.lo), __tg_tanpi(x.hi)); +} +#endif + +#endif /* SIMD_LIBRARY_VERSION */ +#pragma mark - acosh implementation +static inline SIMD_CFUNC simd_float2 __tg_acosh(simd_float2 x) { + return simd_make_float2(__tg_acosh(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_acosh(simd_float3 x) { + return simd_make_float3(__tg_acosh(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_acosh_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_acosh(simd_float4 x) { + return _simd_acosh_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_acosh(simd_float4 x) { + return simd_make_float4(acosh(x.x), acosh(x.y), acosh(x.z), acosh(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_acosh_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_acosh(simd_float8 x) { + return _simd_acosh_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_acosh(simd_float8 x) { + return simd_make_float8(__tg_acosh(x.lo), __tg_acosh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_acosh_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_acosh(simd_float16 x) { + return _simd_acosh_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_acosh(simd_float16 x) { + return simd_make_float16(__tg_acosh(x.lo), __tg_acosh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_acosh_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_acosh(simd_double2 x) { + return _simd_acosh_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_acosh(simd_double2 x) { + return simd_make_double2(acosh(x.x), acosh(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_acosh(simd_double3 x) { + return simd_make_double3(__tg_acosh(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_acosh_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_acosh(simd_double4 x) { + return _simd_acosh_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_acosh(simd_double4 x) { + return simd_make_double4(__tg_acosh(x.lo), __tg_acosh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_acosh_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_acosh(simd_double8 x) { + return _simd_acosh_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_acosh(simd_double8 x) { + return simd_make_double8(__tg_acosh(x.lo), __tg_acosh(x.hi)); +} +#endif + +#pragma mark - asinh implementation +static inline SIMD_CFUNC simd_float2 __tg_asinh(simd_float2 x) { + return simd_make_float2(__tg_asinh(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_asinh(simd_float3 x) { + return simd_make_float3(__tg_asinh(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_asinh_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_asinh(simd_float4 x) { + return _simd_asinh_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_asinh(simd_float4 x) { + return simd_make_float4(asinh(x.x), asinh(x.y), asinh(x.z), asinh(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_asinh_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_asinh(simd_float8 x) { + return _simd_asinh_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_asinh(simd_float8 x) { + return simd_make_float8(__tg_asinh(x.lo), __tg_asinh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_asinh_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_asinh(simd_float16 x) { + return _simd_asinh_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_asinh(simd_float16 x) { + return simd_make_float16(__tg_asinh(x.lo), __tg_asinh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_asinh_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_asinh(simd_double2 x) { + return _simd_asinh_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_asinh(simd_double2 x) { + return simd_make_double2(asinh(x.x), asinh(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_asinh(simd_double3 x) { + return simd_make_double3(__tg_asinh(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_asinh_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_asinh(simd_double4 x) { + return _simd_asinh_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_asinh(simd_double4 x) { + return simd_make_double4(__tg_asinh(x.lo), __tg_asinh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_asinh_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_asinh(simd_double8 x) { + return _simd_asinh_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_asinh(simd_double8 x) { + return simd_make_double8(__tg_asinh(x.lo), __tg_asinh(x.hi)); +} +#endif + +#pragma mark - atanh implementation +static inline SIMD_CFUNC simd_float2 __tg_atanh(simd_float2 x) { + return simd_make_float2(__tg_atanh(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_atanh(simd_float3 x) { + return simd_make_float3(__tg_atanh(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_atanh_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_atanh(simd_float4 x) { + return _simd_atanh_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_atanh(simd_float4 x) { + return simd_make_float4(atanh(x.x), atanh(x.y), atanh(x.z), atanh(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_atanh_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_atanh(simd_float8 x) { + return _simd_atanh_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_atanh(simd_float8 x) { + return simd_make_float8(__tg_atanh(x.lo), __tg_atanh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_atanh_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_atanh(simd_float16 x) { + return _simd_atanh_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_atanh(simd_float16 x) { + return simd_make_float16(__tg_atanh(x.lo), __tg_atanh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_atanh_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_atanh(simd_double2 x) { + return _simd_atanh_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_atanh(simd_double2 x) { + return simd_make_double2(atanh(x.x), atanh(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_atanh(simd_double3 x) { + return simd_make_double3(__tg_atanh(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_atanh_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_atanh(simd_double4 x) { + return _simd_atanh_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_atanh(simd_double4 x) { + return simd_make_double4(__tg_atanh(x.lo), __tg_atanh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_atanh_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_atanh(simd_double8 x) { + return _simd_atanh_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_atanh(simd_double8 x) { + return simd_make_double8(__tg_atanh(x.lo), __tg_atanh(x.hi)); +} +#endif + +#pragma mark - cosh implementation +static inline SIMD_CFUNC simd_float2 __tg_cosh(simd_float2 x) { + return simd_make_float2(__tg_cosh(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_cosh(simd_float3 x) { + return simd_make_float3(__tg_cosh(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_cosh_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_cosh(simd_float4 x) { + return _simd_cosh_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_cosh(simd_float4 x) { + return simd_make_float4(cosh(x.x), cosh(x.y), cosh(x.z), cosh(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_cosh_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_cosh(simd_float8 x) { + return _simd_cosh_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_cosh(simd_float8 x) { + return simd_make_float8(__tg_cosh(x.lo), __tg_cosh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_cosh_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_cosh(simd_float16 x) { + return _simd_cosh_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_cosh(simd_float16 x) { + return simd_make_float16(__tg_cosh(x.lo), __tg_cosh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_cosh_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_cosh(simd_double2 x) { + return _simd_cosh_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_cosh(simd_double2 x) { + return simd_make_double2(cosh(x.x), cosh(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_cosh(simd_double3 x) { + return simd_make_double3(__tg_cosh(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_cosh_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_cosh(simd_double4 x) { + return _simd_cosh_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_cosh(simd_double4 x) { + return simd_make_double4(__tg_cosh(x.lo), __tg_cosh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_cosh_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_cosh(simd_double8 x) { + return _simd_cosh_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_cosh(simd_double8 x) { + return simd_make_double8(__tg_cosh(x.lo), __tg_cosh(x.hi)); +} +#endif + +#pragma mark - sinh implementation +static inline SIMD_CFUNC simd_float2 __tg_sinh(simd_float2 x) { + return simd_make_float2(__tg_sinh(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_sinh(simd_float3 x) { + return simd_make_float3(__tg_sinh(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_sinh_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_sinh(simd_float4 x) { + return _simd_sinh_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_sinh(simd_float4 x) { + return simd_make_float4(sinh(x.x), sinh(x.y), sinh(x.z), sinh(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_sinh_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_sinh(simd_float8 x) { + return _simd_sinh_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_sinh(simd_float8 x) { + return simd_make_float8(__tg_sinh(x.lo), __tg_sinh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_sinh_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_sinh(simd_float16 x) { + return _simd_sinh_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_sinh(simd_float16 x) { + return simd_make_float16(__tg_sinh(x.lo), __tg_sinh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_sinh_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_sinh(simd_double2 x) { + return _simd_sinh_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_sinh(simd_double2 x) { + return simd_make_double2(sinh(x.x), sinh(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_sinh(simd_double3 x) { + return simd_make_double3(__tg_sinh(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_sinh_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_sinh(simd_double4 x) { + return _simd_sinh_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_sinh(simd_double4 x) { + return simd_make_double4(__tg_sinh(x.lo), __tg_sinh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_sinh_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_sinh(simd_double8 x) { + return _simd_sinh_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_sinh(simd_double8 x) { + return simd_make_double8(__tg_sinh(x.lo), __tg_sinh(x.hi)); +} +#endif + +#pragma mark - tanh implementation +static inline SIMD_CFUNC simd_float2 __tg_tanh(simd_float2 x) { + return simd_make_float2(__tg_tanh(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_tanh(simd_float3 x) { + return simd_make_float3(__tg_tanh(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_tanh_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_tanh(simd_float4 x) { + return _simd_tanh_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_tanh(simd_float4 x) { + return simd_make_float4(tanh(x.x), tanh(x.y), tanh(x.z), tanh(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_tanh_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_tanh(simd_float8 x) { + return _simd_tanh_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_tanh(simd_float8 x) { + return simd_make_float8(__tg_tanh(x.lo), __tg_tanh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_tanh_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_tanh(simd_float16 x) { + return _simd_tanh_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_tanh(simd_float16 x) { + return simd_make_float16(__tg_tanh(x.lo), __tg_tanh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_tanh_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_tanh(simd_double2 x) { + return _simd_tanh_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_tanh(simd_double2 x) { + return simd_make_double2(tanh(x.x), tanh(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_tanh(simd_double3 x) { + return simd_make_double3(__tg_tanh(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_tanh_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_tanh(simd_double4 x) { + return _simd_tanh_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_tanh(simd_double4 x) { + return simd_make_double4(__tg_tanh(x.lo), __tg_tanh(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_tanh_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_tanh(simd_double8 x) { + return _simd_tanh_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_tanh(simd_double8 x) { + return simd_make_double8(__tg_tanh(x.lo), __tg_tanh(x.hi)); +} +#endif + +#pragma mark - exp implementation +static inline SIMD_CFUNC simd_float2 __tg_exp(simd_float2 x) { + return simd_make_float2(__tg_exp(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_exp(simd_float3 x) { + return simd_make_float3(__tg_exp(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_exp_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_exp(simd_float4 x) { + return _simd_exp_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_exp(simd_float4 x) { + return simd_make_float4(exp(x.x), exp(x.y), exp(x.z), exp(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_exp_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_exp(simd_float8 x) { + return _simd_exp_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_exp(simd_float8 x) { + return simd_make_float8(__tg_exp(x.lo), __tg_exp(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_exp_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_exp(simd_float16 x) { + return _simd_exp_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_exp(simd_float16 x) { + return simd_make_float16(__tg_exp(x.lo), __tg_exp(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_exp_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_exp(simd_double2 x) { + return _simd_exp_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_exp(simd_double2 x) { + return simd_make_double2(exp(x.x), exp(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_exp(simd_double3 x) { + return simd_make_double3(__tg_exp(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_exp_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_exp(simd_double4 x) { + return _simd_exp_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_exp(simd_double4 x) { + return simd_make_double4(__tg_exp(x.lo), __tg_exp(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_exp_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_exp(simd_double8 x) { + return _simd_exp_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_exp(simd_double8 x) { + return simd_make_double8(__tg_exp(x.lo), __tg_exp(x.hi)); +} +#endif + +#pragma mark - exp2 implementation +static inline SIMD_CFUNC simd_float2 __tg_exp2(simd_float2 x) { + return simd_make_float2(__tg_exp2(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_exp2(simd_float3 x) { + return simd_make_float3(__tg_exp2(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_exp2_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_exp2(simd_float4 x) { + return _simd_exp2_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_exp2(simd_float4 x) { + return simd_make_float4(exp2(x.x), exp2(x.y), exp2(x.z), exp2(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_exp2_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_exp2(simd_float8 x) { + return _simd_exp2_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_exp2(simd_float8 x) { + return simd_make_float8(__tg_exp2(x.lo), __tg_exp2(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_exp2_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_exp2(simd_float16 x) { + return _simd_exp2_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_exp2(simd_float16 x) { + return simd_make_float16(__tg_exp2(x.lo), __tg_exp2(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_exp2_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_exp2(simd_double2 x) { + return _simd_exp2_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_exp2(simd_double2 x) { + return simd_make_double2(exp2(x.x), exp2(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_exp2(simd_double3 x) { + return simd_make_double3(__tg_exp2(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_exp2_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_exp2(simd_double4 x) { + return _simd_exp2_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_exp2(simd_double4 x) { + return simd_make_double4(__tg_exp2(x.lo), __tg_exp2(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_exp2_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_exp2(simd_double8 x) { + return _simd_exp2_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_exp2(simd_double8 x) { + return simd_make_double8(__tg_exp2(x.lo), __tg_exp2(x.hi)); +} +#endif + +#pragma mark - exp10 implementation +#if SIMD_LIBRARY_VERSION >= 1 +static inline SIMD_CFUNC simd_float2 __tg_exp10(simd_float2 x) { + return simd_make_float2(__tg_exp10(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_exp10(simd_float3 x) { + return simd_make_float3(__tg_exp10(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_exp10_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_exp10(simd_float4 x) { + return _simd_exp10_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_exp10(simd_float4 x) { + return simd_make_float4(__exp10(x.x), __exp10(x.y), __exp10(x.z), __exp10(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_exp10_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_exp10(simd_float8 x) { + return _simd_exp10_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_exp10(simd_float8 x) { + return simd_make_float8(__tg_exp10(x.lo), __tg_exp10(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_exp10_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_exp10(simd_float16 x) { + return _simd_exp10_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_exp10(simd_float16 x) { + return simd_make_float16(__tg_exp10(x.lo), __tg_exp10(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_exp10_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_exp10(simd_double2 x) { + return _simd_exp10_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_exp10(simd_double2 x) { + return simd_make_double2(__exp10(x.x), __exp10(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_exp10(simd_double3 x) { + return simd_make_double3(__tg_exp10(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_exp10_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_exp10(simd_double4 x) { + return _simd_exp10_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_exp10(simd_double4 x) { + return simd_make_double4(__tg_exp10(x.lo), __tg_exp10(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_exp10_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_exp10(simd_double8 x) { + return _simd_exp10_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_exp10(simd_double8 x) { + return simd_make_double8(__tg_exp10(x.lo), __tg_exp10(x.hi)); +} +#endif + +#endif /* SIMD_LIBRARY_VERSION */ +#pragma mark - expm1 implementation +static inline SIMD_CFUNC simd_float2 __tg_expm1(simd_float2 x) { + return simd_make_float2(__tg_expm1(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_expm1(simd_float3 x) { + return simd_make_float3(__tg_expm1(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_expm1_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_expm1(simd_float4 x) { + return _simd_expm1_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_expm1(simd_float4 x) { + return simd_make_float4(expm1(x.x), expm1(x.y), expm1(x.z), expm1(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_expm1_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_expm1(simd_float8 x) { + return _simd_expm1_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_expm1(simd_float8 x) { + return simd_make_float8(__tg_expm1(x.lo), __tg_expm1(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_expm1_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_expm1(simd_float16 x) { + return _simd_expm1_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_expm1(simd_float16 x) { + return simd_make_float16(__tg_expm1(x.lo), __tg_expm1(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_expm1_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_expm1(simd_double2 x) { + return _simd_expm1_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_expm1(simd_double2 x) { + return simd_make_double2(expm1(x.x), expm1(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_expm1(simd_double3 x) { + return simd_make_double3(__tg_expm1(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_expm1_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_expm1(simd_double4 x) { + return _simd_expm1_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_expm1(simd_double4 x) { + return simd_make_double4(__tg_expm1(x.lo), __tg_expm1(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_expm1_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_expm1(simd_double8 x) { + return _simd_expm1_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_expm1(simd_double8 x) { + return simd_make_double8(__tg_expm1(x.lo), __tg_expm1(x.hi)); +} +#endif + +#pragma mark - log implementation +static inline SIMD_CFUNC simd_float2 __tg_log(simd_float2 x) { + return simd_make_float2(__tg_log(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_log(simd_float3 x) { + return simd_make_float3(__tg_log(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_log_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_log(simd_float4 x) { + return _simd_log_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_log(simd_float4 x) { + return simd_make_float4(log(x.x), log(x.y), log(x.z), log(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_log_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_log(simd_float8 x) { + return _simd_log_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_log(simd_float8 x) { + return simd_make_float8(__tg_log(x.lo), __tg_log(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_log_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_log(simd_float16 x) { + return _simd_log_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_log(simd_float16 x) { + return simd_make_float16(__tg_log(x.lo), __tg_log(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_log_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_log(simd_double2 x) { + return _simd_log_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_log(simd_double2 x) { + return simd_make_double2(log(x.x), log(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_log(simd_double3 x) { + return simd_make_double3(__tg_log(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_log_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_log(simd_double4 x) { + return _simd_log_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_log(simd_double4 x) { + return simd_make_double4(__tg_log(x.lo), __tg_log(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_log_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_log(simd_double8 x) { + return _simd_log_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_log(simd_double8 x) { + return simd_make_double8(__tg_log(x.lo), __tg_log(x.hi)); +} +#endif + +#pragma mark - log2 implementation +static inline SIMD_CFUNC simd_float2 __tg_log2(simd_float2 x) { + return simd_make_float2(__tg_log2(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_log2(simd_float3 x) { + return simd_make_float3(__tg_log2(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_log2_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_log2(simd_float4 x) { + return _simd_log2_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_log2(simd_float4 x) { + return simd_make_float4(log2(x.x), log2(x.y), log2(x.z), log2(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_log2_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_log2(simd_float8 x) { + return _simd_log2_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_log2(simd_float8 x) { + return simd_make_float8(__tg_log2(x.lo), __tg_log2(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_log2_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_log2(simd_float16 x) { + return _simd_log2_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_log2(simd_float16 x) { + return simd_make_float16(__tg_log2(x.lo), __tg_log2(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_log2_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_log2(simd_double2 x) { + return _simd_log2_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_log2(simd_double2 x) { + return simd_make_double2(log2(x.x), log2(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_log2(simd_double3 x) { + return simd_make_double3(__tg_log2(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_log2_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_log2(simd_double4 x) { + return _simd_log2_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_log2(simd_double4 x) { + return simd_make_double4(__tg_log2(x.lo), __tg_log2(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_log2_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_log2(simd_double8 x) { + return _simd_log2_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_log2(simd_double8 x) { + return simd_make_double8(__tg_log2(x.lo), __tg_log2(x.hi)); +} +#endif + +#pragma mark - log10 implementation +static inline SIMD_CFUNC simd_float2 __tg_log10(simd_float2 x) { + return simd_make_float2(__tg_log10(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_log10(simd_float3 x) { + return simd_make_float3(__tg_log10(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_log10_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_log10(simd_float4 x) { + return _simd_log10_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_log10(simd_float4 x) { + return simd_make_float4(log10(x.x), log10(x.y), log10(x.z), log10(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_log10_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_log10(simd_float8 x) { + return _simd_log10_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_log10(simd_float8 x) { + return simd_make_float8(__tg_log10(x.lo), __tg_log10(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_log10_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_log10(simd_float16 x) { + return _simd_log10_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_log10(simd_float16 x) { + return simd_make_float16(__tg_log10(x.lo), __tg_log10(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_log10_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_log10(simd_double2 x) { + return _simd_log10_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_log10(simd_double2 x) { + return simd_make_double2(log10(x.x), log10(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_log10(simd_double3 x) { + return simd_make_double3(__tg_log10(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_log10_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_log10(simd_double4 x) { + return _simd_log10_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_log10(simd_double4 x) { + return simd_make_double4(__tg_log10(x.lo), __tg_log10(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_log10_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_log10(simd_double8 x) { + return _simd_log10_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_log10(simd_double8 x) { + return simd_make_double8(__tg_log10(x.lo), __tg_log10(x.hi)); +} +#endif + +#pragma mark - log1p implementation +static inline SIMD_CFUNC simd_float2 __tg_log1p(simd_float2 x) { + return simd_make_float2(__tg_log1p(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_log1p(simd_float3 x) { + return simd_make_float3(__tg_log1p(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_log1p_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_log1p(simd_float4 x) { + return _simd_log1p_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_log1p(simd_float4 x) { + return simd_make_float4(log1p(x.x), log1p(x.y), log1p(x.z), log1p(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_log1p_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_log1p(simd_float8 x) { + return _simd_log1p_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_log1p(simd_float8 x) { + return simd_make_float8(__tg_log1p(x.lo), __tg_log1p(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_log1p_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_log1p(simd_float16 x) { + return _simd_log1p_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_log1p(simd_float16 x) { + return simd_make_float16(__tg_log1p(x.lo), __tg_log1p(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_log1p_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_log1p(simd_double2 x) { + return _simd_log1p_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_log1p(simd_double2 x) { + return simd_make_double2(log1p(x.x), log1p(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_log1p(simd_double3 x) { + return simd_make_double3(__tg_log1p(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_log1p_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_log1p(simd_double4 x) { + return _simd_log1p_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_log1p(simd_double4 x) { + return simd_make_double4(__tg_log1p(x.lo), __tg_log1p(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_log1p_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_log1p(simd_double8 x) { + return _simd_log1p_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_log1p(simd_double8 x) { + return simd_make_double8(__tg_log1p(x.lo), __tg_log1p(x.hi)); +} +#endif + +#pragma mark - cbrt implementation +static inline SIMD_CFUNC simd_float2 __tg_cbrt(simd_float2 x) { + return simd_make_float2(__tg_cbrt(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_cbrt(simd_float3 x) { + return simd_make_float3(__tg_cbrt(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_cbrt_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_cbrt(simd_float4 x) { + return _simd_cbrt_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_cbrt(simd_float4 x) { + return simd_make_float4(cbrt(x.x), cbrt(x.y), cbrt(x.z), cbrt(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_cbrt_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_cbrt(simd_float8 x) { + return _simd_cbrt_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_cbrt(simd_float8 x) { + return simd_make_float8(__tg_cbrt(x.lo), __tg_cbrt(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_cbrt_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_cbrt(simd_float16 x) { + return _simd_cbrt_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_cbrt(simd_float16 x) { + return simd_make_float16(__tg_cbrt(x.lo), __tg_cbrt(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_cbrt_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_cbrt(simd_double2 x) { + return _simd_cbrt_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_cbrt(simd_double2 x) { + return simd_make_double2(cbrt(x.x), cbrt(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_cbrt(simd_double3 x) { + return simd_make_double3(__tg_cbrt(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_cbrt_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_cbrt(simd_double4 x) { + return _simd_cbrt_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_cbrt(simd_double4 x) { + return simd_make_double4(__tg_cbrt(x.lo), __tg_cbrt(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_cbrt_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_cbrt(simd_double8 x) { + return _simd_cbrt_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_cbrt(simd_double8 x) { + return simd_make_double8(__tg_cbrt(x.lo), __tg_cbrt(x.hi)); +} +#endif + +#pragma mark - erf implementation +static inline SIMD_CFUNC simd_float2 __tg_erf(simd_float2 x) { + return simd_make_float2(__tg_erf(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_erf(simd_float3 x) { + return simd_make_float3(__tg_erf(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_erf_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_erf(simd_float4 x) { + return _simd_erf_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_erf(simd_float4 x) { + return simd_make_float4(erf(x.x), erf(x.y), erf(x.z), erf(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_erf_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_erf(simd_float8 x) { + return _simd_erf_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_erf(simd_float8 x) { + return simd_make_float8(__tg_erf(x.lo), __tg_erf(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_erf_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_erf(simd_float16 x) { + return _simd_erf_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_erf(simd_float16 x) { + return simd_make_float16(__tg_erf(x.lo), __tg_erf(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_erf_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_erf(simd_double2 x) { + return _simd_erf_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_erf(simd_double2 x) { + return simd_make_double2(erf(x.x), erf(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_erf(simd_double3 x) { + return simd_make_double3(__tg_erf(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_erf_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_erf(simd_double4 x) { + return _simd_erf_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_erf(simd_double4 x) { + return simd_make_double4(__tg_erf(x.lo), __tg_erf(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_erf_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_erf(simd_double8 x) { + return _simd_erf_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_erf(simd_double8 x) { + return simd_make_double8(__tg_erf(x.lo), __tg_erf(x.hi)); +} +#endif + +#pragma mark - erfc implementation +static inline SIMD_CFUNC simd_float2 __tg_erfc(simd_float2 x) { + return simd_make_float2(__tg_erfc(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_erfc(simd_float3 x) { + return simd_make_float3(__tg_erfc(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_erfc_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_erfc(simd_float4 x) { + return _simd_erfc_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_erfc(simd_float4 x) { + return simd_make_float4(erfc(x.x), erfc(x.y), erfc(x.z), erfc(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_erfc_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_erfc(simd_float8 x) { + return _simd_erfc_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_erfc(simd_float8 x) { + return simd_make_float8(__tg_erfc(x.lo), __tg_erfc(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_erfc_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_erfc(simd_float16 x) { + return _simd_erfc_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_erfc(simd_float16 x) { + return simd_make_float16(__tg_erfc(x.lo), __tg_erfc(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_erfc_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_erfc(simd_double2 x) { + return _simd_erfc_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_erfc(simd_double2 x) { + return simd_make_double2(erfc(x.x), erfc(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_erfc(simd_double3 x) { + return simd_make_double3(__tg_erfc(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_erfc_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_erfc(simd_double4 x) { + return _simd_erfc_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_erfc(simd_double4 x) { + return simd_make_double4(__tg_erfc(x.lo), __tg_erfc(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_erfc_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_erfc(simd_double8 x) { + return _simd_erfc_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_erfc(simd_double8 x) { + return simd_make_double8(__tg_erfc(x.lo), __tg_erfc(x.hi)); +} +#endif + +#pragma mark - tgamma implementation +static inline SIMD_CFUNC simd_float2 __tg_tgamma(simd_float2 x) { + return simd_make_float2(__tg_tgamma(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_tgamma(simd_float3 x) { + return simd_make_float3(__tg_tgamma(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_tgamma_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_tgamma(simd_float4 x) { + return _simd_tgamma_f4(x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_tgamma(simd_float4 x) { + return simd_make_float4(tgamma(x.x), tgamma(x.y), tgamma(x.z), tgamma(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_tgamma_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_tgamma(simd_float8 x) { + return _simd_tgamma_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_tgamma(simd_float8 x) { + return simd_make_float8(__tg_tgamma(x.lo), __tg_tgamma(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_tgamma_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_tgamma(simd_float16 x) { + return _simd_tgamma_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_tgamma(simd_float16 x) { + return simd_make_float16(__tg_tgamma(x.lo), __tg_tgamma(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_tgamma_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_tgamma(simd_double2 x) { + return _simd_tgamma_d2(x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_tgamma(simd_double2 x) { + return simd_make_double2(tgamma(x.x), tgamma(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_tgamma(simd_double3 x) { + return simd_make_double3(__tg_tgamma(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_tgamma_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_tgamma(simd_double4 x) { + return _simd_tgamma_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_tgamma(simd_double4 x) { + return simd_make_double4(__tg_tgamma(x.lo), __tg_tgamma(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_tgamma_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_tgamma(simd_double8 x) { + return _simd_tgamma_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_tgamma(simd_double8 x) { + return simd_make_double8(__tg_tgamma(x.lo), __tg_tgamma(x.hi)); +} +#endif + +#pragma mark - round implementation +static inline SIMD_CFUNC simd_float2 __tg_round(simd_float2 x) { + return simd_make_float2(__tg_round(simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_round(simd_float3 x) { + return simd_make_float3(__tg_round(simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_round_f4(simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_round(simd_float4 x) { +#if defined __arm64__ + return vrndaq_f32(x); +#else + return _simd_round_f4(x); +#endif +} +#else +static inline SIMD_CFUNC simd_float4 __tg_round(simd_float4 x) { + return simd_make_float4(round(x.x), round(x.y), round(x.z), round(x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_round_f8(simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_round(simd_float8 x) { + return _simd_round_f8(x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_round(simd_float8 x) { + return simd_make_float8(__tg_round(x.lo), __tg_round(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_round_f16(simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_round(simd_float16 x) { + return _simd_round_f16(x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_round(simd_float16 x) { + return simd_make_float16(__tg_round(x.lo), __tg_round(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_round_d2(simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_round(simd_double2 x) { +#if defined __arm64__ + return vrndaq_f64(x); +#else + return _simd_round_d2(x); +#endif +} +#else +static inline SIMD_CFUNC simd_double2 __tg_round(simd_double2 x) { + return simd_make_double2(round(x.x), round(x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_round(simd_double3 x) { + return simd_make_double3(__tg_round(simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_round_d4(simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_round(simd_double4 x) { + return _simd_round_d4(x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_round(simd_double4 x) { + return simd_make_double4(__tg_round(x.lo), __tg_round(x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_round_d8(simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_round(simd_double8 x) { + return _simd_round_d8(x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_round(simd_double8 x) { + return simd_make_double8(__tg_round(x.lo), __tg_round(x.hi)); +} +#endif + +#pragma mark - atan2 implementation +static inline SIMD_CFUNC simd_float2 __tg_atan2(simd_float2 y, simd_float2 x) { + return simd_make_float2(__tg_atan2(simd_make_float4(y), simd_make_float4(x))); +} + +static inline SIMD_CFUNC simd_float3 __tg_atan2(simd_float3 y, simd_float3 x) { + return simd_make_float3(__tg_atan2(simd_make_float4(y), simd_make_float4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_atan2_f4(simd_float4 y, simd_float4 x); +static inline SIMD_CFUNC simd_float4 __tg_atan2(simd_float4 y, simd_float4 x) { + return _simd_atan2_f4(y, x); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_atan2(simd_float4 y, simd_float4 x) { + return simd_make_float4(atan2(y.x, x.x), atan2(y.y, x.y), atan2(y.z, x.z), atan2(y.w, x.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_atan2_f8(simd_float8 y, simd_float8 x); +static inline SIMD_CFUNC simd_float8 __tg_atan2(simd_float8 y, simd_float8 x) { + return _simd_atan2_f8(y, x); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_atan2(simd_float8 y, simd_float8 x) { + return simd_make_float8(__tg_atan2(y.lo, x.lo), __tg_atan2(y.hi, x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_atan2_f16(simd_float16 y, simd_float16 x); +static inline SIMD_CFUNC simd_float16 __tg_atan2(simd_float16 y, simd_float16 x) { + return _simd_atan2_f16(y, x); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_atan2(simd_float16 y, simd_float16 x) { + return simd_make_float16(__tg_atan2(y.lo, x.lo), __tg_atan2(y.hi, x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_atan2_d2(simd_double2 y, simd_double2 x); +static inline SIMD_CFUNC simd_double2 __tg_atan2(simd_double2 y, simd_double2 x) { + return _simd_atan2_d2(y, x); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_atan2(simd_double2 y, simd_double2 x) { + return simd_make_double2(atan2(y.x, x.x), atan2(y.y, x.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_atan2(simd_double3 y, simd_double3 x) { + return simd_make_double3(__tg_atan2(simd_make_double4(y), simd_make_double4(x))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_atan2_d4(simd_double4 y, simd_double4 x); +static inline SIMD_CFUNC simd_double4 __tg_atan2(simd_double4 y, simd_double4 x) { + return _simd_atan2_d4(y, x); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_atan2(simd_double4 y, simd_double4 x) { + return simd_make_double4(__tg_atan2(y.lo, x.lo), __tg_atan2(y.hi, x.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_atan2_d8(simd_double8 y, simd_double8 x); +static inline SIMD_CFUNC simd_double8 __tg_atan2(simd_double8 y, simd_double8 x) { + return _simd_atan2_d8(y, x); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_atan2(simd_double8 y, simd_double8 x) { + return simd_make_double8(__tg_atan2(y.lo, x.lo), __tg_atan2(y.hi, x.hi)); +} +#endif + +#pragma mark - hypot implementation +static inline SIMD_CFUNC simd_float2 __tg_hypot(simd_float2 x, simd_float2 y) { + return simd_make_float2(__tg_hypot(simd_make_float4(x), simd_make_float4(y))); +} + +static inline SIMD_CFUNC simd_float3 __tg_hypot(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_hypot(simd_make_float4(x), simd_make_float4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_hypot_f4(simd_float4 x, simd_float4 y); +static inline SIMD_CFUNC simd_float4 __tg_hypot(simd_float4 x, simd_float4 y) { + return _simd_hypot_f4(x, y); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_hypot(simd_float4 x, simd_float4 y) { + return simd_make_float4(hypot(x.x, y.x), hypot(x.y, y.y), hypot(x.z, y.z), hypot(x.w, y.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_hypot_f8(simd_float8 x, simd_float8 y); +static inline SIMD_CFUNC simd_float8 __tg_hypot(simd_float8 x, simd_float8 y) { + return _simd_hypot_f8(x, y); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_hypot(simd_float8 x, simd_float8 y) { + return simd_make_float8(__tg_hypot(x.lo, y.lo), __tg_hypot(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_hypot_f16(simd_float16 x, simd_float16 y); +static inline SIMD_CFUNC simd_float16 __tg_hypot(simd_float16 x, simd_float16 y) { + return _simd_hypot_f16(x, y); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_hypot(simd_float16 x, simd_float16 y) { + return simd_make_float16(__tg_hypot(x.lo, y.lo), __tg_hypot(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_hypot_d2(simd_double2 x, simd_double2 y); +static inline SIMD_CFUNC simd_double2 __tg_hypot(simd_double2 x, simd_double2 y) { + return _simd_hypot_d2(x, y); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_hypot(simd_double2 x, simd_double2 y) { + return simd_make_double2(hypot(x.x, y.x), hypot(x.y, y.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_hypot(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_hypot(simd_make_double4(x), simd_make_double4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_hypot_d4(simd_double4 x, simd_double4 y); +static inline SIMD_CFUNC simd_double4 __tg_hypot(simd_double4 x, simd_double4 y) { + return _simd_hypot_d4(x, y); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_hypot(simd_double4 x, simd_double4 y) { + return simd_make_double4(__tg_hypot(x.lo, y.lo), __tg_hypot(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_hypot_d8(simd_double8 x, simd_double8 y); +static inline SIMD_CFUNC simd_double8 __tg_hypot(simd_double8 x, simd_double8 y) { + return _simd_hypot_d8(x, y); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_hypot(simd_double8 x, simd_double8 y) { + return simd_make_double8(__tg_hypot(x.lo, y.lo), __tg_hypot(x.hi, y.hi)); +} +#endif + +#pragma mark - pow implementation +static inline SIMD_CFUNC simd_float2 __tg_pow(simd_float2 x, simd_float2 y) { + return simd_make_float2(__tg_pow(simd_make_float4(x), simd_make_float4(y))); +} + +static inline SIMD_CFUNC simd_float3 __tg_pow(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_pow(simd_make_float4(x), simd_make_float4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_pow_f4(simd_float4 x, simd_float4 y); +static inline SIMD_CFUNC simd_float4 __tg_pow(simd_float4 x, simd_float4 y) { + return _simd_pow_f4(x, y); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_pow(simd_float4 x, simd_float4 y) { + return simd_make_float4(pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z), pow(x.w, y.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_pow_f8(simd_float8 x, simd_float8 y); +static inline SIMD_CFUNC simd_float8 __tg_pow(simd_float8 x, simd_float8 y) { + return _simd_pow_f8(x, y); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_pow(simd_float8 x, simd_float8 y) { + return simd_make_float8(__tg_pow(x.lo, y.lo), __tg_pow(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_pow_f16(simd_float16 x, simd_float16 y); +static inline SIMD_CFUNC simd_float16 __tg_pow(simd_float16 x, simd_float16 y) { + return _simd_pow_f16(x, y); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_pow(simd_float16 x, simd_float16 y) { + return simd_make_float16(__tg_pow(x.lo, y.lo), __tg_pow(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_pow_d2(simd_double2 x, simd_double2 y); +static inline SIMD_CFUNC simd_double2 __tg_pow(simd_double2 x, simd_double2 y) { + return _simd_pow_d2(x, y); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_pow(simd_double2 x, simd_double2 y) { + return simd_make_double2(pow(x.x, y.x), pow(x.y, y.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_pow(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_pow(simd_make_double4(x), simd_make_double4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_pow_d4(simd_double4 x, simd_double4 y); +static inline SIMD_CFUNC simd_double4 __tg_pow(simd_double4 x, simd_double4 y) { + return _simd_pow_d4(x, y); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_pow(simd_double4 x, simd_double4 y) { + return simd_make_double4(__tg_pow(x.lo, y.lo), __tg_pow(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_pow_d8(simd_double8 x, simd_double8 y); +static inline SIMD_CFUNC simd_double8 __tg_pow(simd_double8 x, simd_double8 y) { + return _simd_pow_d8(x, y); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_pow(simd_double8 x, simd_double8 y) { + return simd_make_double8(__tg_pow(x.lo, y.lo), __tg_pow(x.hi, y.hi)); +} +#endif + +#pragma mark - fmod implementation +static inline SIMD_CFUNC simd_float2 __tg_fmod(simd_float2 x, simd_float2 y) { + return simd_make_float2(__tg_fmod(simd_make_float4(x), simd_make_float4(y))); +} + +static inline SIMD_CFUNC simd_float3 __tg_fmod(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_fmod(simd_make_float4(x), simd_make_float4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_fmod_f4(simd_float4 x, simd_float4 y); +static inline SIMD_CFUNC simd_float4 __tg_fmod(simd_float4 x, simd_float4 y) { + return _simd_fmod_f4(x, y); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_fmod(simd_float4 x, simd_float4 y) { + return simd_make_float4(fmod(x.x, y.x), fmod(x.y, y.y), fmod(x.z, y.z), fmod(x.w, y.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_fmod_f8(simd_float8 x, simd_float8 y); +static inline SIMD_CFUNC simd_float8 __tg_fmod(simd_float8 x, simd_float8 y) { + return _simd_fmod_f8(x, y); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_fmod(simd_float8 x, simd_float8 y) { + return simd_make_float8(__tg_fmod(x.lo, y.lo), __tg_fmod(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_fmod_f16(simd_float16 x, simd_float16 y); +static inline SIMD_CFUNC simd_float16 __tg_fmod(simd_float16 x, simd_float16 y) { + return _simd_fmod_f16(x, y); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_fmod(simd_float16 x, simd_float16 y) { + return simd_make_float16(__tg_fmod(x.lo, y.lo), __tg_fmod(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_fmod_d2(simd_double2 x, simd_double2 y); +static inline SIMD_CFUNC simd_double2 __tg_fmod(simd_double2 x, simd_double2 y) { + return _simd_fmod_d2(x, y); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_fmod(simd_double2 x, simd_double2 y) { + return simd_make_double2(fmod(x.x, y.x), fmod(x.y, y.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_fmod(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_fmod(simd_make_double4(x), simd_make_double4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_fmod_d4(simd_double4 x, simd_double4 y); +static inline SIMD_CFUNC simd_double4 __tg_fmod(simd_double4 x, simd_double4 y) { + return _simd_fmod_d4(x, y); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_fmod(simd_double4 x, simd_double4 y) { + return simd_make_double4(__tg_fmod(x.lo, y.lo), __tg_fmod(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_fmod_d8(simd_double8 x, simd_double8 y); +static inline SIMD_CFUNC simd_double8 __tg_fmod(simd_double8 x, simd_double8 y) { + return _simd_fmod_d8(x, y); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_fmod(simd_double8 x, simd_double8 y) { + return simd_make_double8(__tg_fmod(x.lo, y.lo), __tg_fmod(x.hi, y.hi)); +} +#endif + +#pragma mark - remainder implementation +static inline SIMD_CFUNC simd_float2 __tg_remainder(simd_float2 x, simd_float2 y) { + return simd_make_float2(__tg_remainder(simd_make_float4(x), simd_make_float4(y))); +} + +static inline SIMD_CFUNC simd_float3 __tg_remainder(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_remainder(simd_make_float4(x), simd_make_float4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_remainder_f4(simd_float4 x, simd_float4 y); +static inline SIMD_CFUNC simd_float4 __tg_remainder(simd_float4 x, simd_float4 y) { + return _simd_remainder_f4(x, y); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_remainder(simd_float4 x, simd_float4 y) { + return simd_make_float4(remainder(x.x, y.x), remainder(x.y, y.y), remainder(x.z, y.z), remainder(x.w, y.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_remainder_f8(simd_float8 x, simd_float8 y); +static inline SIMD_CFUNC simd_float8 __tg_remainder(simd_float8 x, simd_float8 y) { + return _simd_remainder_f8(x, y); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_remainder(simd_float8 x, simd_float8 y) { + return simd_make_float8(__tg_remainder(x.lo, y.lo), __tg_remainder(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_remainder_f16(simd_float16 x, simd_float16 y); +static inline SIMD_CFUNC simd_float16 __tg_remainder(simd_float16 x, simd_float16 y) { + return _simd_remainder_f16(x, y); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_remainder(simd_float16 x, simd_float16 y) { + return simd_make_float16(__tg_remainder(x.lo, y.lo), __tg_remainder(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_remainder_d2(simd_double2 x, simd_double2 y); +static inline SIMD_CFUNC simd_double2 __tg_remainder(simd_double2 x, simd_double2 y) { + return _simd_remainder_d2(x, y); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_remainder(simd_double2 x, simd_double2 y) { + return simd_make_double2(remainder(x.x, y.x), remainder(x.y, y.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_remainder(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_remainder(simd_make_double4(x), simd_make_double4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_remainder_d4(simd_double4 x, simd_double4 y); +static inline SIMD_CFUNC simd_double4 __tg_remainder(simd_double4 x, simd_double4 y) { + return _simd_remainder_d4(x, y); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_remainder(simd_double4 x, simd_double4 y) { + return simd_make_double4(__tg_remainder(x.lo, y.lo), __tg_remainder(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_remainder_d8(simd_double8 x, simd_double8 y); +static inline SIMD_CFUNC simd_double8 __tg_remainder(simd_double8 x, simd_double8 y) { + return _simd_remainder_d8(x, y); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_remainder(simd_double8 x, simd_double8 y) { + return simd_make_double8(__tg_remainder(x.lo, y.lo), __tg_remainder(x.hi, y.hi)); +} +#endif + +#pragma mark - nextafter implementation +static inline SIMD_CFUNC simd_float2 __tg_nextafter(simd_float2 x, simd_float2 y) { + return simd_make_float2(__tg_nextafter(simd_make_float4(x), simd_make_float4(y))); +} + +static inline SIMD_CFUNC simd_float3 __tg_nextafter(simd_float3 x, simd_float3 y) { + return simd_make_float3(__tg_nextafter(simd_make_float4(x), simd_make_float4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_float4 _simd_nextafter_f4(simd_float4 x, simd_float4 y); +static inline SIMD_CFUNC simd_float4 __tg_nextafter(simd_float4 x, simd_float4 y) { + return _simd_nextafter_f4(x, y); +} +#else +static inline SIMD_CFUNC simd_float4 __tg_nextafter(simd_float4 x, simd_float4 y) { + return simd_make_float4(nextafter(x.x, y.x), nextafter(x.y, y.y), nextafter(x.z, y.z), nextafter(x.w, y.w)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_float8 _simd_nextafter_f8(simd_float8 x, simd_float8 y); +static inline SIMD_CFUNC simd_float8 __tg_nextafter(simd_float8 x, simd_float8 y) { + return _simd_nextafter_f8(x, y); +} +#else +static inline SIMD_CFUNC simd_float8 __tg_nextafter(simd_float8 x, simd_float8 y) { + return simd_make_float8(__tg_nextafter(x.lo, y.lo), __tg_nextafter(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_float16 _simd_nextafter_f16(simd_float16 x, simd_float16 y); +static inline SIMD_CFUNC simd_float16 __tg_nextafter(simd_float16 x, simd_float16 y) { + return _simd_nextafter_f16(x, y); +} +#else +static inline SIMD_CFUNC simd_float16 __tg_nextafter(simd_float16 x, simd_float16 y) { + return simd_make_float16(__tg_nextafter(x.lo, y.lo), __tg_nextafter(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_nextafter_d2(simd_double2 x, simd_double2 y); +static inline SIMD_CFUNC simd_double2 __tg_nextafter(simd_double2 x, simd_double2 y) { + return _simd_nextafter_d2(x, y); +} +#else +static inline SIMD_CFUNC simd_double2 __tg_nextafter(simd_double2 x, simd_double2 y) { + return simd_make_double2(nextafter(x.x, y.x), nextafter(x.y, y.y)); +} +#endif + +static inline SIMD_CFUNC simd_double3 __tg_nextafter(simd_double3 x, simd_double3 y) { + return simd_make_double3(__tg_nextafter(simd_make_double4(x), simd_make_double4(y))); +} + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX2__ +extern simd_double4 _simd_nextafter_d4(simd_double4 x, simd_double4 y); +static inline SIMD_CFUNC simd_double4 __tg_nextafter(simd_double4 x, simd_double4 y) { + return _simd_nextafter_d4(x, y); +} +#else +static inline SIMD_CFUNC simd_double4 __tg_nextafter(simd_double4 x, simd_double4 y) { + return simd_make_double4(__tg_nextafter(x.lo, y.lo), __tg_nextafter(x.hi, y.hi)); +} +#endif + +#if SIMD_LIBRARY_VERSION >= 3 && defined __x86_64__ && defined __AVX512F__ +extern simd_double8 _simd_nextafter_d8(simd_double8 x, simd_double8 y); +static inline SIMD_CFUNC simd_double8 __tg_nextafter(simd_double8 x, simd_double8 y) { + return _simd_nextafter_d8(x, y); +} +#else +static inline SIMD_CFUNC simd_double8 __tg_nextafter(simd_double8 x, simd_double8 y) { + return simd_make_double8(__tg_nextafter(x.lo, y.lo), __tg_nextafter(x.hi, y.hi)); +} +#endif + +static inline SIMD_CFUNC simd_float2 __tg_fdim(simd_float2 x, simd_float2 y) { return simd_bitselect(x-y, 0, x= 3 +extern simd_float4 _simd_fma_f4(simd_float4 x, simd_float4 y, simd_float4 z); +#endif +static inline SIMD_CFUNC simd_float4 __tg_fma(simd_float4 x, simd_float4 y, simd_float4 z) { +#if defined __arm64__ || defined __ARM_VFPV4__ + return vfmaq_f32(z, x, y); +#elif (defined __i386__ || defined __x86_64__) && defined __FMA__ + return _mm_fmadd_ps(x, y, z); +#elif SIMD_LIBRARY_VERSION >= 3 + return _simd_fma_f4(x, y, z); +#else + return simd_make_float4(fma(x.x, y.x, z.x), fma(x.y, y.y, z.y), fma(x.z, y.z, z.z), fma(x.w, y.w, z.w)); +#endif +} + +static inline SIMD_CFUNC simd_float8 __tg_fma(simd_float8 x, simd_float8 y, simd_float8 z) { +#if (defined __i386__ || defined __x86_64__) && defined __FMA__ + return _mm256_fmadd_ps(x, y, z); +#else + return simd_make_float8(__tg_fma(x.lo, y.lo, z.lo), __tg_fma(x.hi, y.hi, z.hi)); +#endif +} + +static inline SIMD_CFUNC simd_float16 __tg_fma(simd_float16 x, simd_float16 y, simd_float16 z) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_fmadd_ps(x, y, z); +#else + return simd_make_float16(__tg_fma(x.lo, y.lo, z.lo), __tg_fma(x.hi, y.hi, z.hi)); +#endif +} + +#if SIMD_LIBRARY_VERSION >= 3 +extern simd_double2 _simd_fma_d2(simd_double2 x, simd_double2 y, simd_double2 z); +#endif +static inline SIMD_CFUNC simd_double2 __tg_fma(simd_double2 x, simd_double2 y, simd_double2 z) { +#if defined __arm64__ + return vfmaq_f64(z, x, y); +#elif (defined __i386__ || defined __x86_64__) && defined __FMA__ + return _mm_fmadd_pd(x, y, z); +#elif SIMD_LIBRARY_VERSION >= 3 + return _simd_fma_d2(x, y, z); +#else + return simd_make_double2(fma(x.x, y.x, z.x), fma(x.y, y.y, z.y)); +#endif +} + +static inline SIMD_CFUNC simd_double3 __tg_fma(simd_double3 x, simd_double3 y, simd_double3 z) { + return simd_make_double3(__tg_fma(simd_make_double4(x), simd_make_double4(y), simd_make_double4(z))); +} + +static inline SIMD_CFUNC simd_double4 __tg_fma(simd_double4 x, simd_double4 y, simd_double4 z) { +#if (defined __i386__ || defined __x86_64__) && defined __FMA__ + return _mm256_fmadd_pd(x, y, z); +#else + return simd_make_double4(__tg_fma(x.lo, y.lo, z.lo), __tg_fma(x.hi, y.hi, z.hi)); +#endif +} + +static inline SIMD_CFUNC simd_double8 __tg_fma(simd_double8 x, simd_double8 y, simd_double8 z) { +#if defined __x86_64__ && defined __AVX512F__ + return _mm512_fmadd_pd(x, y, z); +#else + return simd_make_double8(__tg_fma(x.lo, y.lo, z.lo), __tg_fma(x.hi, y.hi, z.hi)); +#endif +} + +static inline SIMD_CFUNC float simd_muladd(float x, float y, float z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_float2 simd_muladd(simd_float2 x, simd_float2 y, simd_float2 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_float3 simd_muladd(simd_float3 x, simd_float3 y, simd_float3 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_float4 simd_muladd(simd_float4 x, simd_float4 y, simd_float4 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_float8 simd_muladd(simd_float8 x, simd_float8 y, simd_float8 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_float16 simd_muladd(simd_float16 x, simd_float16 y, simd_float16 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC double simd_muladd(double x, double y, double z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_double2 simd_muladd(simd_double2 x, simd_double2 y, simd_double2 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_double3 simd_muladd(simd_double3 x, simd_double3 y, simd_double3 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_double4 simd_muladd(simd_double4 x, simd_double4 y, simd_double4 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +static inline SIMD_CFUNC simd_double8 simd_muladd(simd_double8 x, simd_double8 y, simd_double8 z) { +#pragma STDC FP_CONTRACT ON + return x*y + z; +} +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* SIMD_MATH_HEADER */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/matrix.h b/lib/libc/include/any-macos.11-any/simd/matrix.h new file mode 100644 index 0000000000..a62384e133 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/matrix.h @@ -0,0 +1,1786 @@ +/* Copyright (c) 2014-2017 Apple, Inc. All rights reserved. + * + * Function Result + * ------------------------------------------------------------------ + * + * simd_diagonal_matrix(x) A square matrix with the vector x + * as its diagonal. + * + * simd_matrix(c0, c1, ... ) A matrix with the specified vectors + * as columns. + * + * simd_matrix_from_rows(r0, r1, ... ) A matrix with the specified vectors + * as rows. + * + * simd_mul(a,x) Scalar product a*x. + * + * simd_linear_combination(a,x,b,y) a*x + b*y. + * + * simd_add(x,y) Macro wrapping linear_combination + * to compute x + y. + * + * simd_sub(x,y) Macro wrapping linear_combination + * to compute x - y. + * + * simd_transpose(x) Transpose of the matrix x. + * + * simd_inverse(x) Inverse of x if x is non-singular. If + * x is singular, the result is undefined. + * + * simd_mul(x,y) If x is a matrix, returns the matrix + * product x*y, where y is either a matrix + * or a column vector. If x is a vector, + * returns the product x*y where x is + * interpreted as a row vector. + * + * simd_equal(x,y) Returns true if and only if every + * element of x is exactly equal to the + * corresponding element of y. + * + * simd_almost_equal_elements(x,y,tol) + * Returns true if and only if for each + * entry xij in x, the corresponding + * element yij in y satisfies + * |xij - yij| <= tol. + * + * simd_almost_equal_elements_relative(x,y,tol) + * Returns true if and only if for each + * entry xij in x, the corresponding + * element yij in y satisfies + * |xij - yij| <= tol*|xij|. + * + * The header also defines a few useful global matrix objects: + * matrix_identity_floatNxM and matrix_identity_doubleNxM, may be used to get + * an identity matrix of the specified size. + * + * In C++, we are able to use namespacing to make the functions more concise; + * we also overload some common arithmetic operators to work with the matrix + * types: + * + * C++ Function Equivalent C Function + * -------------------------------------------------------------------- + * simd::inverse simd_inverse + * simd::transpose simd_transpose + * operator+ simd_add + * operator- simd_sub + * operator+= N/A + * operator-= N/A + * operator* simd_mul or simd_mul + * operator*= simd_mul or simd_mul + * operator== simd_equal + * operator!= !simd_equal + * simd::almost_equal_elements simd_almost_equal_elements + * simd::almost_equal_elements_relative simd_almost_equal_elements_relative + * + * provides constructors for C++ matrix types. + */ + +#ifndef SIMD_MATRIX_HEADER +#define SIMD_MATRIX_HEADER + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +extern const simd_float2x2 matrix_identity_float2x2 __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +extern const simd_float3x3 matrix_identity_float3x3 __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +extern const simd_float4x4 matrix_identity_float4x4 __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +extern const simd_double2x2 matrix_identity_double2x2 __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +extern const simd_double3x3 matrix_identity_double3x3 __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +extern const simd_double4x4 matrix_identity_double4x4 __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); + +static simd_float2x2 SIMD_CFUNC simd_diagonal_matrix(simd_float2 __x); +static simd_float3x3 SIMD_CFUNC simd_diagonal_matrix(simd_float3 __x); +static simd_float4x4 SIMD_CFUNC simd_diagonal_matrix(simd_float4 __x); +static simd_double2x2 SIMD_CFUNC simd_diagonal_matrix(simd_double2 __x); +static simd_double3x3 SIMD_CFUNC simd_diagonal_matrix(simd_double3 __x); +static simd_double4x4 SIMD_CFUNC simd_diagonal_matrix(simd_double4 __x); +#define matrix_from_diagonal simd_diagonal_matrix + +static simd_float2x2 SIMD_CFUNC simd_matrix(simd_float2 col0, simd_float2 col1); +static simd_float3x2 SIMD_CFUNC simd_matrix(simd_float2 col0, simd_float2 col1, simd_float2 col2); +static simd_float4x2 SIMD_CFUNC simd_matrix(simd_float2 col0, simd_float2 col1, simd_float2 col2, simd_float2 col3); +static simd_float2x3 SIMD_CFUNC simd_matrix(simd_float3 col0, simd_float3 col1); +static simd_float3x3 SIMD_CFUNC simd_matrix(simd_float3 col0, simd_float3 col1, simd_float3 col2); +static simd_float4x3 SIMD_CFUNC simd_matrix(simd_float3 col0, simd_float3 col1, simd_float3 col2, simd_float3 col3); +static simd_float2x4 SIMD_CFUNC simd_matrix(simd_float4 col0, simd_float4 col1); +static simd_float3x4 SIMD_CFUNC simd_matrix(simd_float4 col0, simd_float4 col1, simd_float4 col2); +static simd_float4x4 SIMD_CFUNC simd_matrix(simd_float4 col0, simd_float4 col1, simd_float4 col2, simd_float4 col3); +static simd_double2x2 SIMD_CFUNC simd_matrix(simd_double2 col0, simd_double2 col1); +static simd_double3x2 SIMD_CFUNC simd_matrix(simd_double2 col0, simd_double2 col1, simd_double2 col2); +static simd_double4x2 SIMD_CFUNC simd_matrix(simd_double2 col0, simd_double2 col1, simd_double2 col2, simd_double2 col3); +static simd_double2x3 SIMD_CFUNC simd_matrix(simd_double3 col0, simd_double3 col1); +static simd_double3x3 SIMD_CFUNC simd_matrix(simd_double3 col0, simd_double3 col1, simd_double3 col2); +static simd_double4x3 SIMD_CFUNC simd_matrix(simd_double3 col0, simd_double3 col1, simd_double3 col2, simd_double3 col3); +static simd_double2x4 SIMD_CFUNC simd_matrix(simd_double4 col0, simd_double4 col1); +static simd_double3x4 SIMD_CFUNC simd_matrix(simd_double4 col0, simd_double4 col1, simd_double4 col2); +static simd_double4x4 SIMD_CFUNC simd_matrix(simd_double4 col0, simd_double4 col1, simd_double4 col2, simd_double4 col3); +#define matrix_from_columns simd_matrix + +static simd_float2x2 SIMD_CFUNC simd_matrix_from_rows(simd_float2 row0, simd_float2 row1); +static simd_float2x3 SIMD_CFUNC simd_matrix_from_rows(simd_float2 row0, simd_float2 row1, simd_float2 row2); +static simd_float2x4 SIMD_CFUNC simd_matrix_from_rows(simd_float2 row0, simd_float2 row1, simd_float2 row2, simd_float2 row3); +static simd_float3x2 SIMD_CFUNC simd_matrix_from_rows(simd_float3 row0, simd_float3 row1); +static simd_float3x3 SIMD_CFUNC simd_matrix_from_rows(simd_float3 row0, simd_float3 row1, simd_float3 row2); +static simd_float3x4 SIMD_CFUNC simd_matrix_from_rows(simd_float3 row0, simd_float3 row1, simd_float3 row2, simd_float3 row3); +static simd_float4x2 SIMD_CFUNC simd_matrix_from_rows(simd_float4 row0, simd_float4 row1); +static simd_float4x3 SIMD_CFUNC simd_matrix_from_rows(simd_float4 row0, simd_float4 row1, simd_float4 row2); +static simd_float4x4 SIMD_CFUNC simd_matrix_from_rows(simd_float4 row0, simd_float4 row1, simd_float4 row2, simd_float4 row3); +static simd_double2x2 SIMD_CFUNC simd_matrix_from_rows(simd_double2 row0, simd_double2 row1); +static simd_double2x3 SIMD_CFUNC simd_matrix_from_rows(simd_double2 row0, simd_double2 row1, simd_double2 row2); +static simd_double2x4 SIMD_CFUNC simd_matrix_from_rows(simd_double2 row0, simd_double2 row1, simd_double2 row2, simd_double2 row3); +static simd_double3x2 SIMD_CFUNC simd_matrix_from_rows(simd_double3 row0, simd_double3 row1); +static simd_double3x3 SIMD_CFUNC simd_matrix_from_rows(simd_double3 row0, simd_double3 row1, simd_double3 row2); +static simd_double3x4 SIMD_CFUNC simd_matrix_from_rows(simd_double3 row0, simd_double3 row1, simd_double3 row2, simd_double3 row3); +static simd_double4x2 SIMD_CFUNC simd_matrix_from_rows(simd_double4 row0, simd_double4 row1); +static simd_double4x3 SIMD_CFUNC simd_matrix_from_rows(simd_double4 row0, simd_double4 row1, simd_double4 row2); +static simd_double4x4 SIMD_CFUNC simd_matrix_from_rows(simd_double4 row0, simd_double4 row1, simd_double4 row2, simd_double4 row3); +#define matrix_from_rows simd_matrix_from_rows + +static simd_float3x3 SIMD_NOINLINE simd_matrix3x3(simd_quatf q); +static simd_float4x4 SIMD_NOINLINE simd_matrix4x4(simd_quatf q); +static simd_double3x3 SIMD_NOINLINE simd_matrix3x3(simd_quatd q); +static simd_double4x4 SIMD_NOINLINE simd_matrix4x4(simd_quatd q); + +static simd_float2x2 SIMD_CFUNC simd_mul(float __a, simd_float2x2 __x); +static simd_float3x2 SIMD_CFUNC simd_mul(float __a, simd_float3x2 __x); +static simd_float4x2 SIMD_CFUNC simd_mul(float __a, simd_float4x2 __x); +static simd_float2x3 SIMD_CFUNC simd_mul(float __a, simd_float2x3 __x); +static simd_float3x3 SIMD_CFUNC simd_mul(float __a, simd_float3x3 __x); +static simd_float4x3 SIMD_CFUNC simd_mul(float __a, simd_float4x3 __x); +static simd_float2x4 SIMD_CFUNC simd_mul(float __a, simd_float2x4 __x); +static simd_float3x4 SIMD_CFUNC simd_mul(float __a, simd_float3x4 __x); +static simd_float4x4 SIMD_CFUNC simd_mul(float __a, simd_float4x4 __x); +static simd_double2x2 SIMD_CFUNC simd_mul(double __a, simd_double2x2 __x); +static simd_double3x2 SIMD_CFUNC simd_mul(double __a, simd_double3x2 __x); +static simd_double4x2 SIMD_CFUNC simd_mul(double __a, simd_double4x2 __x); +static simd_double2x3 SIMD_CFUNC simd_mul(double __a, simd_double2x3 __x); +static simd_double3x3 SIMD_CFUNC simd_mul(double __a, simd_double3x3 __x); +static simd_double4x3 SIMD_CFUNC simd_mul(double __a, simd_double4x3 __x); +static simd_double2x4 SIMD_CFUNC simd_mul(double __a, simd_double2x4 __x); +static simd_double3x4 SIMD_CFUNC simd_mul(double __a, simd_double3x4 __x); +static simd_double4x4 SIMD_CFUNC simd_mul(double __a, simd_double4x4 __x); + +static simd_float2x2 SIMD_CFUNC simd_linear_combination(float __a, simd_float2x2 __x, float __b, simd_float2x2 __y); +static simd_float3x2 SIMD_CFUNC simd_linear_combination(float __a, simd_float3x2 __x, float __b, simd_float3x2 __y); +static simd_float4x2 SIMD_CFUNC simd_linear_combination(float __a, simd_float4x2 __x, float __b, simd_float4x2 __y); +static simd_float2x3 SIMD_CFUNC simd_linear_combination(float __a, simd_float2x3 __x, float __b, simd_float2x3 __y); +static simd_float3x3 SIMD_CFUNC simd_linear_combination(float __a, simd_float3x3 __x, float __b, simd_float3x3 __y); +static simd_float4x3 SIMD_CFUNC simd_linear_combination(float __a, simd_float4x3 __x, float __b, simd_float4x3 __y); +static simd_float2x4 SIMD_CFUNC simd_linear_combination(float __a, simd_float2x4 __x, float __b, simd_float2x4 __y); +static simd_float3x4 SIMD_CFUNC simd_linear_combination(float __a, simd_float3x4 __x, float __b, simd_float3x4 __y); +static simd_float4x4 SIMD_CFUNC simd_linear_combination(float __a, simd_float4x4 __x, float __b, simd_float4x4 __y); +static simd_double2x2 SIMD_CFUNC simd_linear_combination(double __a, simd_double2x2 __x, double __b, simd_double2x2 __y); +static simd_double3x2 SIMD_CFUNC simd_linear_combination(double __a, simd_double3x2 __x, double __b, simd_double3x2 __y); +static simd_double4x2 SIMD_CFUNC simd_linear_combination(double __a, simd_double4x2 __x, double __b, simd_double4x2 __y); +static simd_double2x3 SIMD_CFUNC simd_linear_combination(double __a, simd_double2x3 __x, double __b, simd_double2x3 __y); +static simd_double3x3 SIMD_CFUNC simd_linear_combination(double __a, simd_double3x3 __x, double __b, simd_double3x3 __y); +static simd_double4x3 SIMD_CFUNC simd_linear_combination(double __a, simd_double4x3 __x, double __b, simd_double4x3 __y); +static simd_double2x4 SIMD_CFUNC simd_linear_combination(double __a, simd_double2x4 __x, double __b, simd_double2x4 __y); +static simd_double3x4 SIMD_CFUNC simd_linear_combination(double __a, simd_double3x4 __x, double __b, simd_double3x4 __y); +static simd_double4x4 SIMD_CFUNC simd_linear_combination(double __a, simd_double4x4 __x, double __b, simd_double4x4 __y); +#define matrix_linear_combination simd_linear_combination + +static simd_float2x2 SIMD_CFUNC simd_add(simd_float2x2 __x, simd_float2x2 __y); +static simd_float3x2 SIMD_CFUNC simd_add(simd_float3x2 __x, simd_float3x2 __y); +static simd_float4x2 SIMD_CFUNC simd_add(simd_float4x2 __x, simd_float4x2 __y); +static simd_float2x3 SIMD_CFUNC simd_add(simd_float2x3 __x, simd_float2x3 __y); +static simd_float3x3 SIMD_CFUNC simd_add(simd_float3x3 __x, simd_float3x3 __y); +static simd_float4x3 SIMD_CFUNC simd_add(simd_float4x3 __x, simd_float4x3 __y); +static simd_float2x4 SIMD_CFUNC simd_add(simd_float2x4 __x, simd_float2x4 __y); +static simd_float3x4 SIMD_CFUNC simd_add(simd_float3x4 __x, simd_float3x4 __y); +static simd_float4x4 SIMD_CFUNC simd_add(simd_float4x4 __x, simd_float4x4 __y); +static simd_double2x2 SIMD_CFUNC simd_add(simd_double2x2 __x, simd_double2x2 __y); +static simd_double3x2 SIMD_CFUNC simd_add(simd_double3x2 __x, simd_double3x2 __y); +static simd_double4x2 SIMD_CFUNC simd_add(simd_double4x2 __x, simd_double4x2 __y); +static simd_double2x3 SIMD_CFUNC simd_add(simd_double2x3 __x, simd_double2x3 __y); +static simd_double3x3 SIMD_CFUNC simd_add(simd_double3x3 __x, simd_double3x3 __y); +static simd_double4x3 SIMD_CFUNC simd_add(simd_double4x3 __x, simd_double4x3 __y); +static simd_double2x4 SIMD_CFUNC simd_add(simd_double2x4 __x, simd_double2x4 __y); +static simd_double3x4 SIMD_CFUNC simd_add(simd_double3x4 __x, simd_double3x4 __y); +static simd_double4x4 SIMD_CFUNC simd_add(simd_double4x4 __x, simd_double4x4 __y); +#define matrix_add simd_add + +static simd_float2x2 SIMD_CFUNC simd_sub(simd_float2x2 __x, simd_float2x2 __y); +static simd_float3x2 SIMD_CFUNC simd_sub(simd_float3x2 __x, simd_float3x2 __y); +static simd_float4x2 SIMD_CFUNC simd_sub(simd_float4x2 __x, simd_float4x2 __y); +static simd_float2x3 SIMD_CFUNC simd_sub(simd_float2x3 __x, simd_float2x3 __y); +static simd_float3x3 SIMD_CFUNC simd_sub(simd_float3x3 __x, simd_float3x3 __y); +static simd_float4x3 SIMD_CFUNC simd_sub(simd_float4x3 __x, simd_float4x3 __y); +static simd_float2x4 SIMD_CFUNC simd_sub(simd_float2x4 __x, simd_float2x4 __y); +static simd_float3x4 SIMD_CFUNC simd_sub(simd_float3x4 __x, simd_float3x4 __y); +static simd_float4x4 SIMD_CFUNC simd_sub(simd_float4x4 __x, simd_float4x4 __y); +static simd_double2x2 SIMD_CFUNC simd_sub(simd_double2x2 __x, simd_double2x2 __y); +static simd_double3x2 SIMD_CFUNC simd_sub(simd_double3x2 __x, simd_double3x2 __y); +static simd_double4x2 SIMD_CFUNC simd_sub(simd_double4x2 __x, simd_double4x2 __y); +static simd_double2x3 SIMD_CFUNC simd_sub(simd_double2x3 __x, simd_double2x3 __y); +static simd_double3x3 SIMD_CFUNC simd_sub(simd_double3x3 __x, simd_double3x3 __y); +static simd_double4x3 SIMD_CFUNC simd_sub(simd_double4x3 __x, simd_double4x3 __y); +static simd_double2x4 SIMD_CFUNC simd_sub(simd_double2x4 __x, simd_double2x4 __y); +static simd_double3x4 SIMD_CFUNC simd_sub(simd_double3x4 __x, simd_double3x4 __y); +static simd_double4x4 SIMD_CFUNC simd_sub(simd_double4x4 __x, simd_double4x4 __y); +#define matrix_sub simd_sub + +static simd_float2x2 SIMD_CFUNC simd_transpose(simd_float2x2 __x); +static simd_float2x3 SIMD_CFUNC simd_transpose(simd_float3x2 __x); +static simd_float2x4 SIMD_CFUNC simd_transpose(simd_float4x2 __x); +static simd_float3x2 SIMD_CFUNC simd_transpose(simd_float2x3 __x); +static simd_float3x3 SIMD_CFUNC simd_transpose(simd_float3x3 __x); +static simd_float3x4 SIMD_CFUNC simd_transpose(simd_float4x3 __x); +static simd_float4x2 SIMD_CFUNC simd_transpose(simd_float2x4 __x); +static simd_float4x3 SIMD_CFUNC simd_transpose(simd_float3x4 __x); +static simd_float4x4 SIMD_CFUNC simd_transpose(simd_float4x4 __x); +static simd_double2x2 SIMD_CFUNC simd_transpose(simd_double2x2 __x); +static simd_double2x3 SIMD_CFUNC simd_transpose(simd_double3x2 __x); +static simd_double2x4 SIMD_CFUNC simd_transpose(simd_double4x2 __x); +static simd_double3x2 SIMD_CFUNC simd_transpose(simd_double2x3 __x); +static simd_double3x3 SIMD_CFUNC simd_transpose(simd_double3x3 __x); +static simd_double3x4 SIMD_CFUNC simd_transpose(simd_double4x3 __x); +static simd_double4x2 SIMD_CFUNC simd_transpose(simd_double2x4 __x); +static simd_double4x3 SIMD_CFUNC simd_transpose(simd_double3x4 __x); +static simd_double4x4 SIMD_CFUNC simd_transpose(simd_double4x4 __x); +#define matrix_transpose simd_transpose + +static float SIMD_CFUNC simd_determinant(simd_float2x2 __x); +static float SIMD_CFUNC simd_determinant(simd_float3x3 __x); +static float SIMD_CFUNC simd_determinant(simd_float4x4 __x); +static double SIMD_CFUNC simd_determinant(simd_double2x2 __x); +static double SIMD_CFUNC simd_determinant(simd_double3x3 __x); +static double SIMD_CFUNC simd_determinant(simd_double4x4 __x); +#define matrix_determinant simd_determinant + +static simd_float2x2 SIMD_CFUNC simd_inverse(simd_float2x2 __x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +static simd_float3x3 SIMD_CFUNC simd_inverse(simd_float3x3 __x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +static simd_float4x4 SIMD_CFUNC simd_inverse(simd_float4x4 __x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +static simd_double2x2 SIMD_CFUNC simd_inverse(simd_double2x2 __x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +static simd_double3x3 SIMD_CFUNC simd_inverse(simd_double3x3 __x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +static simd_double4x4 SIMD_CFUNC simd_inverse(simd_double4x4 __x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +#define matrix_invert simd_inverse + +static simd_float2 SIMD_CFUNC simd_mul(simd_float2x2 __x, simd_float2 __y); +static simd_float2 SIMD_CFUNC simd_mul(simd_float3x2 __x, simd_float3 __y); +static simd_float2 SIMD_CFUNC simd_mul(simd_float4x2 __x, simd_float4 __y); +static simd_float3 SIMD_CFUNC simd_mul(simd_float2x3 __x, simd_float2 __y); +static simd_float3 SIMD_CFUNC simd_mul(simd_float3x3 __x, simd_float3 __y); +static simd_float3 SIMD_CFUNC simd_mul(simd_float4x3 __x, simd_float4 __y); +static simd_float4 SIMD_CFUNC simd_mul(simd_float2x4 __x, simd_float2 __y); +static simd_float4 SIMD_CFUNC simd_mul(simd_float3x4 __x, simd_float3 __y); +static simd_float4 SIMD_CFUNC simd_mul(simd_float4x4 __x, simd_float4 __y); +static simd_double2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double2 __y); +static simd_double2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double3 __y); +static simd_double2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double4 __y); +static simd_double3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double2 __y); +static simd_double3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double3 __y); +static simd_double3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double4 __y); +static simd_double4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double2 __y); +static simd_double4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double3 __y); +static simd_double4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double4 __y); +static simd_float2 SIMD_CFUNC simd_mul(simd_float2 __x, simd_float2x2 __y); +static simd_float3 SIMD_CFUNC simd_mul(simd_float2 __x, simd_float3x2 __y); +static simd_float4 SIMD_CFUNC simd_mul(simd_float2 __x, simd_float4x2 __y); +static simd_float2 SIMD_CFUNC simd_mul(simd_float3 __x, simd_float2x3 __y); +static simd_float3 SIMD_CFUNC simd_mul(simd_float3 __x, simd_float3x3 __y); +static simd_float4 SIMD_CFUNC simd_mul(simd_float3 __x, simd_float4x3 __y); +static simd_float2 SIMD_CFUNC simd_mul(simd_float4 __x, simd_float2x4 __y); +static simd_float3 SIMD_CFUNC simd_mul(simd_float4 __x, simd_float3x4 __y); +static simd_float4 SIMD_CFUNC simd_mul(simd_float4 __x, simd_float4x4 __y); +static simd_double2 SIMD_CFUNC simd_mul(simd_double2 __x, simd_double2x2 __y); +static simd_double3 SIMD_CFUNC simd_mul(simd_double2 __x, simd_double3x2 __y); +static simd_double4 SIMD_CFUNC simd_mul(simd_double2 __x, simd_double4x2 __y); +static simd_double2 SIMD_CFUNC simd_mul(simd_double3 __x, simd_double2x3 __y); +static simd_double3 SIMD_CFUNC simd_mul(simd_double3 __x, simd_double3x3 __y); +static simd_double4 SIMD_CFUNC simd_mul(simd_double3 __x, simd_double4x3 __y); +static simd_double2 SIMD_CFUNC simd_mul(simd_double4 __x, simd_double2x4 __y); +static simd_double3 SIMD_CFUNC simd_mul(simd_double4 __x, simd_double3x4 __y); +static simd_double4 SIMD_CFUNC simd_mul(simd_double4 __x, simd_double4x4 __y); +static simd_float2x2 SIMD_CFUNC simd_mul(simd_float2x2 __x, simd_float2x2 __y); +static simd_float3x2 SIMD_CFUNC simd_mul(simd_float2x2 __x, simd_float3x2 __y); +static simd_float4x2 SIMD_CFUNC simd_mul(simd_float2x2 __x, simd_float4x2 __y); +static simd_float2x3 SIMD_CFUNC simd_mul(simd_float2x3 __x, simd_float2x2 __y); +static simd_float3x3 SIMD_CFUNC simd_mul(simd_float2x3 __x, simd_float3x2 __y); +static simd_float4x3 SIMD_CFUNC simd_mul(simd_float2x3 __x, simd_float4x2 __y); +static simd_float2x4 SIMD_CFUNC simd_mul(simd_float2x4 __x, simd_float2x2 __y); +static simd_float3x4 SIMD_CFUNC simd_mul(simd_float2x4 __x, simd_float3x2 __y); +static simd_float4x4 SIMD_CFUNC simd_mul(simd_float2x4 __x, simd_float4x2 __y); +static simd_double2x2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double2x2 __y); +static simd_double3x2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double3x2 __y); +static simd_double4x2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double4x2 __y); +static simd_double2x3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double2x2 __y); +static simd_double3x3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double3x2 __y); +static simd_double4x3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double4x2 __y); +static simd_double2x4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double2x2 __y); +static simd_double3x4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double3x2 __y); +static simd_double4x4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double4x2 __y); +static simd_float2x2 SIMD_CFUNC simd_mul(simd_float3x2 __x, simd_float2x3 __y); +static simd_float3x2 SIMD_CFUNC simd_mul(simd_float3x2 __x, simd_float3x3 __y); +static simd_float4x2 SIMD_CFUNC simd_mul(simd_float3x2 __x, simd_float4x3 __y); +static simd_float2x3 SIMD_CFUNC simd_mul(simd_float3x3 __x, simd_float2x3 __y); +static simd_float3x3 SIMD_CFUNC simd_mul(simd_float3x3 __x, simd_float3x3 __y); +static simd_float4x3 SIMD_CFUNC simd_mul(simd_float3x3 __x, simd_float4x3 __y); +static simd_float2x4 SIMD_CFUNC simd_mul(simd_float3x4 __x, simd_float2x3 __y); +static simd_float3x4 SIMD_CFUNC simd_mul(simd_float3x4 __x, simd_float3x3 __y); +static simd_float4x4 SIMD_CFUNC simd_mul(simd_float3x4 __x, simd_float4x3 __y); +static simd_double2x2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double2x3 __y); +static simd_double3x2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double3x3 __y); +static simd_double4x2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double4x3 __y); +static simd_double2x3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double2x3 __y); +static simd_double3x3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double3x3 __y); +static simd_double4x3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double4x3 __y); +static simd_double2x4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double2x3 __y); +static simd_double3x4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double3x3 __y); +static simd_double4x4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double4x3 __y); +static simd_float2x2 SIMD_CFUNC simd_mul(simd_float4x2 __x, simd_float2x4 __y); +static simd_float3x2 SIMD_CFUNC simd_mul(simd_float4x2 __x, simd_float3x4 __y); +static simd_float4x2 SIMD_CFUNC simd_mul(simd_float4x2 __x, simd_float4x4 __y); +static simd_float2x3 SIMD_CFUNC simd_mul(simd_float4x3 __x, simd_float2x4 __y); +static simd_float3x3 SIMD_CFUNC simd_mul(simd_float4x3 __x, simd_float3x4 __y); +static simd_float4x3 SIMD_CFUNC simd_mul(simd_float4x3 __x, simd_float4x4 __y); +static simd_float2x4 SIMD_CFUNC simd_mul(simd_float4x4 __x, simd_float2x4 __y); +static simd_float3x4 SIMD_CFUNC simd_mul(simd_float4x4 __x, simd_float3x4 __y); +static simd_float4x4 SIMD_CFUNC simd_mul(simd_float4x4 __x, simd_float4x4 __y); +static simd_double2x2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double2x4 __y); +static simd_double3x2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double3x4 __y); +static simd_double4x2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double4x4 __y); +static simd_double2x3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double2x4 __y); +static simd_double3x3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double3x4 __y); +static simd_double4x3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double4x4 __y); +static simd_double2x4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double2x4 __y); +static simd_double3x4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double3x4 __y); +static simd_double4x4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double4x4 __y); + +static simd_bool SIMD_CFUNC simd_equal(simd_float2x2 __x, simd_float2x2 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float2x3 __x, simd_float2x3 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float2x4 __x, simd_float2x4 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float3x2 __x, simd_float3x2 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float3x3 __x, simd_float3x3 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float3x4 __x, simd_float3x4 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float4x2 __x, simd_float4x2 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float4x3 __x, simd_float4x3 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_float4x4 __x, simd_float4x4 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double2x2 __x, simd_double2x2 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double2x3 __x, simd_double2x3 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double2x4 __x, simd_double2x4 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double3x2 __x, simd_double3x2 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double3x3 __x, simd_double3x3 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double3x4 __x, simd_double3x4 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double4x2 __x, simd_double4x2 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double4x3 __x, simd_double4x3 __y); +static simd_bool SIMD_CFUNC simd_equal(simd_double4x4 __x, simd_double4x4 __y); +#define matrix_equal simd_equal + +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float2x2 __x, simd_float2x2 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float2x3 __x, simd_float2x3 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float2x4 __x, simd_float2x4 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float3x2 __x, simd_float3x2 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float3x3 __x, simd_float3x3 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float3x4 __x, simd_float3x4 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float4x2 __x, simd_float4x2 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float4x3 __x, simd_float4x3 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float4x4 __x, simd_float4x4 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double2x2 __x, simd_double2x2 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double2x3 __x, simd_double2x3 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double2x4 __x, simd_double2x4 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double3x2 __x, simd_double3x2 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double3x3 __x, simd_double3x3 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double3x4 __x, simd_double3x4 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double4x2 __x, simd_double4x2 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double4x3 __x, simd_double4x3 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double4x4 __x, simd_double4x4 __y, double __tol); +#define matrix_almost_equal_elements simd_almost_equal_elements + +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float2x2 __x, simd_float2x2 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float2x3 __x, simd_float2x3 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float2x4 __x, simd_float2x4 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float3x2 __x, simd_float3x2 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float3x3 __x, simd_float3x3 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float3x4 __x, simd_float3x4 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float4x2 __x, simd_float4x2 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float4x3 __x, simd_float4x3 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float4x4 __x, simd_float4x4 __y, float __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double2x2 __x, simd_double2x2 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double2x3 __x, simd_double2x3 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double2x4 __x, simd_double2x4 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double3x2 __x, simd_double3x2 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double3x3 __x, simd_double3x3 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double3x4 __x, simd_double3x4 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double4x2 __x, simd_double4x2 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double4x3 __x, simd_double4x3 __y, double __tol); +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double4x4 __x, simd_double4x4 __y, double __tol); +#define matrix_almost_equal_elements_relative simd_almost_equal_elements_relative + +#ifdef __cplusplus +} /* extern "C" */ + +namespace simd { + static SIMD_CPPFUNC float2x2 operator+(const float2x2 x, const float2x2 y) { return float2x2(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float2x3 operator+(const float2x3 x, const float2x3 y) { return float2x3(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float2x4 operator+(const float2x4 x, const float2x4 y) { return float2x4(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float3x2 operator+(const float3x2 x, const float3x2 y) { return float3x2(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float3x3 operator+(const float3x3 x, const float3x3 y) { return float3x3(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float3x4 operator+(const float3x4 x, const float3x4 y) { return float3x4(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float4x2 operator+(const float4x2 x, const float4x2 y) { return float4x2(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float4x3 operator+(const float4x3 x, const float4x3 y) { return float4x3(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC float4x4 operator+(const float4x4 x, const float4x4 y) { return float4x4(::simd_linear_combination(1, x, 1, y)); } + + static SIMD_CPPFUNC float2x2 operator-(const float2x2 x, const float2x2 y) { return float2x2(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float2x3 operator-(const float2x3 x, const float2x3 y) { return float2x3(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float2x4 operator-(const float2x4 x, const float2x4 y) { return float2x4(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float3x2 operator-(const float3x2 x, const float3x2 y) { return float3x2(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float3x3 operator-(const float3x3 x, const float3x3 y) { return float3x3(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float3x4 operator-(const float3x4 x, const float3x4 y) { return float3x4(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float4x2 operator-(const float4x2 x, const float4x2 y) { return float4x2(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float4x3 operator-(const float4x3 x, const float4x3 y) { return float4x3(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC float4x4 operator-(const float4x4 x, const float4x4 y) { return float4x4(::simd_linear_combination(1, x, -1, y)); } + + static SIMD_CPPFUNC float2x2& operator+=(float2x2& x, const float2x2 y) { x = x + y; return x; } + static SIMD_CPPFUNC float2x3& operator+=(float2x3& x, const float2x3 y) { x = x + y; return x; } + static SIMD_CPPFUNC float2x4& operator+=(float2x4& x, const float2x4 y) { x = x + y; return x; } + static SIMD_CPPFUNC float3x2& operator+=(float3x2& x, const float3x2 y) { x = x + y; return x; } + static SIMD_CPPFUNC float3x3& operator+=(float3x3& x, const float3x3 y) { x = x + y; return x; } + static SIMD_CPPFUNC float3x4& operator+=(float3x4& x, const float3x4 y) { x = x + y; return x; } + static SIMD_CPPFUNC float4x2& operator+=(float4x2& x, const float4x2 y) { x = x + y; return x; } + static SIMD_CPPFUNC float4x3& operator+=(float4x3& x, const float4x3 y) { x = x + y; return x; } + static SIMD_CPPFUNC float4x4& operator+=(float4x4& x, const float4x4 y) { x = x + y; return x; } + + static SIMD_CPPFUNC float2x2& operator-=(float2x2& x, const float2x2 y) { x = x - y; return x; } + static SIMD_CPPFUNC float2x3& operator-=(float2x3& x, const float2x3 y) { x = x - y; return x; } + static SIMD_CPPFUNC float2x4& operator-=(float2x4& x, const float2x4 y) { x = x - y; return x; } + static SIMD_CPPFUNC float3x2& operator-=(float3x2& x, const float3x2 y) { x = x - y; return x; } + static SIMD_CPPFUNC float3x3& operator-=(float3x3& x, const float3x3 y) { x = x - y; return x; } + static SIMD_CPPFUNC float3x4& operator-=(float3x4& x, const float3x4 y) { x = x - y; return x; } + static SIMD_CPPFUNC float4x2& operator-=(float4x2& x, const float4x2 y) { x = x - y; return x; } + static SIMD_CPPFUNC float4x3& operator-=(float4x3& x, const float4x3 y) { x = x - y; return x; } + static SIMD_CPPFUNC float4x4& operator-=(float4x4& x, const float4x4 y) { x = x - y; return x; } + + static SIMD_CPPFUNC float2x2 transpose(const float2x2 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float2x3 transpose(const float3x2 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float2x4 transpose(const float4x2 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float3x2 transpose(const float2x3 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float3x3 transpose(const float3x3 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float3x4 transpose(const float4x3 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float4x2 transpose(const float2x4 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float4x3 transpose(const float3x4 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC float4x4 transpose(const float4x4 x) { return ::simd_transpose(x); } + + static SIMD_CPPFUNC float determinant(const float2x2 x) { return ::simd_determinant(x); } + static SIMD_CPPFUNC float determinant(const float3x3 x) { return ::simd_determinant(x); } + static SIMD_CPPFUNC float determinant(const float4x4 x) { return ::simd_determinant(x); } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + static SIMD_CPPFUNC float2x2 inverse(const float2x2 x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) { return ::simd_inverse(x); } + static SIMD_CPPFUNC float3x3 inverse(const float3x3 x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) { return ::simd_inverse(x); } + static SIMD_CPPFUNC float4x4 inverse(const float4x4 x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) { return ::simd_inverse(x); } +#pragma clang diagnostic pop + + static SIMD_CPPFUNC float2x2 operator*(const float a, const float2x2 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float2x3 operator*(const float a, const float2x3 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float2x4 operator*(const float a, const float2x4 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float3x2 operator*(const float a, const float3x2 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float3x3 operator*(const float a, const float3x3 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float3x4 operator*(const float a, const float3x4 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float4x2 operator*(const float a, const float4x2 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float4x3 operator*(const float a, const float4x3 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float4x4 operator*(const float a, const float4x4 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float2x2 operator*(const float2x2 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float2x3 operator*(const float2x3 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float2x4 operator*(const float2x4 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float3x2 operator*(const float3x2 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float3x3 operator*(const float3x3 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float3x4 operator*(const float3x4 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float4x2 operator*(const float4x2 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float4x3 operator*(const float4x3 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float4x4 operator*(const float4x4 x, const float a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC float2x2& operator*=(float2x2& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float2x3& operator*=(float2x3& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float2x4& operator*=(float2x4& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float3x2& operator*=(float3x2& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float3x3& operator*=(float3x3& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float3x4& operator*=(float3x4& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float4x2& operator*=(float4x2& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float4x3& operator*=(float4x3& x, const float a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC float4x4& operator*=(float4x4& x, const float a) { x = ::simd_mul(a, x); return x; } + + static SIMD_CPPFUNC float2 operator*(const float2 x, const float2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3 operator*(const float2 x, const float3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4 operator*(const float2 x, const float4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2 operator*(const float3 x, const float2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3 operator*(const float3 x, const float3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4 operator*(const float3 x, const float4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2 operator*(const float4 x, const float2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3 operator*(const float4 x, const float3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4 operator*(const float4 x, const float4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2 operator*(const float2x2 x, const float2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2 operator*(const float3x2 x, const float3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2 operator*(const float4x2 x, const float4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3 operator*(const float2x3 x, const float2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3 operator*(const float3x3 x, const float3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3 operator*(const float4x3 x, const float4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4 operator*(const float2x4 x, const float2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4 operator*(const float3x4 x, const float3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4 operator*(const float4x4 x, const float4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2& operator*=(float2& x, const float2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float3& operator*=(float3& x, const float3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float4& operator*=(float4& x, const float4x4 y) { x = ::simd_mul(x, y); return x; } + + static SIMD_CPPFUNC float2x2 operator*(const float2x2 x, const float2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x2 operator*(const float2x2 x, const float3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x2 operator*(const float2x2 x, const float4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x3 operator*(const float2x3 x, const float2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x3 operator*(const float2x3 x, const float3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x3 operator*(const float2x3 x, const float4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x4 operator*(const float2x4 x, const float2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x4 operator*(const float2x4 x, const float3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x4 operator*(const float2x4 x, const float4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x2 operator*(const float3x2 x, const float2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x2 operator*(const float3x2 x, const float3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x2 operator*(const float3x2 x, const float4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x3 operator*(const float3x3 x, const float2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x3 operator*(const float3x3 x, const float3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x3 operator*(const float3x3 x, const float4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x4 operator*(const float3x4 x, const float2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x4 operator*(const float3x4 x, const float3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x4 operator*(const float3x4 x, const float4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x2 operator*(const float4x2 x, const float2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x2 operator*(const float4x2 x, const float3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x2 operator*(const float4x2 x, const float4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x3 operator*(const float4x3 x, const float2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x3 operator*(const float4x3 x, const float3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x3 operator*(const float4x3 x, const float4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x4 operator*(const float4x4 x, const float2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float3x4 operator*(const float4x4 x, const float3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float4x4 operator*(const float4x4 x, const float4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC float2x2& operator*=(float2x2& x, const float2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float2x3& operator*=(float2x3& x, const float2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float2x4& operator*=(float2x4& x, const float2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float3x2& operator*=(float3x2& x, const float3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float3x3& operator*=(float3x3& x, const float3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float3x4& operator*=(float3x4& x, const float3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float4x2& operator*=(float4x2& x, const float4x4 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float4x3& operator*=(float4x3& x, const float4x4 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC float4x4& operator*=(float4x4& x, const float4x4 y) { x = ::simd_mul(x, y); return x; } + + static SIMD_CPPFUNC bool operator==(const float2x2& x, const float2x2& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float2x3& x, const float2x3& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float2x4& x, const float2x4& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float3x2& x, const float3x2& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float3x3& x, const float3x3& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float3x4& x, const float3x4& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float4x2& x, const float4x2& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float4x3& x, const float4x3& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const float4x4& x, const float4x4& y) { return ::simd_equal(x, y); } + + static SIMD_CPPFUNC bool operator!=(const float2x2& x, const float2x2& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float2x3& x, const float2x3& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float2x4& x, const float2x4& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float3x2& x, const float3x2& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float3x3& x, const float3x3& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float3x4& x, const float3x4& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float4x2& x, const float4x2& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float4x3& x, const float4x3& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const float4x4& x, const float4x4& y) { return !(x == y); } + + static SIMD_CPPFUNC bool almost_equal_elements(const float2x2 x, const float2x2 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float2x3 x, const float2x3 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float2x4 x, const float2x4 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float3x2 x, const float3x2 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float3x3 x, const float3x3 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float3x4 x, const float3x4 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float4x2 x, const float4x2 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float4x3 x, const float4x3 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const float4x4 x, const float4x4 y, const float tol) { return ::simd_almost_equal_elements(x, y, tol); } + + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float2x2 x, const float2x2 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float2x3 x, const float2x3 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float2x4 x, const float2x4 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float3x2 x, const float3x2 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float3x3 x, const float3x3 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float3x4 x, const float3x4 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float4x2 x, const float4x2 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float4x3 x, const float4x3 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const float4x4 x, const float4x4 y, const float tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + + static SIMD_CPPFUNC double2x2 operator+(const double2x2 x, const double2x2 y) { return double2x2(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double2x3 operator+(const double2x3 x, const double2x3 y) { return double2x3(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double2x4 operator+(const double2x4 x, const double2x4 y) { return double2x4(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double3x2 operator+(const double3x2 x, const double3x2 y) { return double3x2(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double3x3 operator+(const double3x3 x, const double3x3 y) { return double3x3(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double3x4 operator+(const double3x4 x, const double3x4 y) { return double3x4(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double4x2 operator+(const double4x2 x, const double4x2 y) { return double4x2(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double4x3 operator+(const double4x3 x, const double4x3 y) { return double4x3(::simd_linear_combination(1, x, 1, y)); } + static SIMD_CPPFUNC double4x4 operator+(const double4x4 x, const double4x4 y) { return double4x4(::simd_linear_combination(1, x, 1, y)); } + + static SIMD_CPPFUNC double2x2 operator-(const double2x2 x, const double2x2 y) { return double2x2(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double2x3 operator-(const double2x3 x, const double2x3 y) { return double2x3(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double2x4 operator-(const double2x4 x, const double2x4 y) { return double2x4(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double3x2 operator-(const double3x2 x, const double3x2 y) { return double3x2(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double3x3 operator-(const double3x3 x, const double3x3 y) { return double3x3(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double3x4 operator-(const double3x4 x, const double3x4 y) { return double3x4(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double4x2 operator-(const double4x2 x, const double4x2 y) { return double4x2(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double4x3 operator-(const double4x3 x, const double4x3 y) { return double4x3(::simd_linear_combination(1, x, -1, y)); } + static SIMD_CPPFUNC double4x4 operator-(const double4x4 x, const double4x4 y) { return double4x4(::simd_linear_combination(1, x, -1, y)); } + + static SIMD_CPPFUNC double2x2& operator+=(double2x2& x, const double2x2 y) { x = x + y; return x; } + static SIMD_CPPFUNC double2x3& operator+=(double2x3& x, const double2x3 y) { x = x + y; return x; } + static SIMD_CPPFUNC double2x4& operator+=(double2x4& x, const double2x4 y) { x = x + y; return x; } + static SIMD_CPPFUNC double3x2& operator+=(double3x2& x, const double3x2 y) { x = x + y; return x; } + static SIMD_CPPFUNC double3x3& operator+=(double3x3& x, const double3x3 y) { x = x + y; return x; } + static SIMD_CPPFUNC double3x4& operator+=(double3x4& x, const double3x4 y) { x = x + y; return x; } + static SIMD_CPPFUNC double4x2& operator+=(double4x2& x, const double4x2 y) { x = x + y; return x; } + static SIMD_CPPFUNC double4x3& operator+=(double4x3& x, const double4x3 y) { x = x + y; return x; } + static SIMD_CPPFUNC double4x4& operator+=(double4x4& x, const double4x4 y) { x = x + y; return x; } + + static SIMD_CPPFUNC double2x2& operator-=(double2x2& x, const double2x2 y) { x = x - y; return x; } + static SIMD_CPPFUNC double2x3& operator-=(double2x3& x, const double2x3 y) { x = x - y; return x; } + static SIMD_CPPFUNC double2x4& operator-=(double2x4& x, const double2x4 y) { x = x - y; return x; } + static SIMD_CPPFUNC double3x2& operator-=(double3x2& x, const double3x2 y) { x = x - y; return x; } + static SIMD_CPPFUNC double3x3& operator-=(double3x3& x, const double3x3 y) { x = x - y; return x; } + static SIMD_CPPFUNC double3x4& operator-=(double3x4& x, const double3x4 y) { x = x - y; return x; } + static SIMD_CPPFUNC double4x2& operator-=(double4x2& x, const double4x2 y) { x = x - y; return x; } + static SIMD_CPPFUNC double4x3& operator-=(double4x3& x, const double4x3 y) { x = x - y; return x; } + static SIMD_CPPFUNC double4x4& operator-=(double4x4& x, const double4x4 y) { x = x - y; return x; } + + static SIMD_CPPFUNC double2x2 transpose(const double2x2 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double2x3 transpose(const double3x2 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double2x4 transpose(const double4x2 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double3x2 transpose(const double2x3 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double3x3 transpose(const double3x3 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double3x4 transpose(const double4x3 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double4x2 transpose(const double2x4 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double4x3 transpose(const double3x4 x) { return ::simd_transpose(x); } + static SIMD_CPPFUNC double4x4 transpose(const double4x4 x) { return ::simd_transpose(x); } + + static SIMD_CPPFUNC double determinant(const double2x2 x) { return ::simd_determinant(x); } + static SIMD_CPPFUNC double determinant(const double3x3 x) { return ::simd_determinant(x); } + static SIMD_CPPFUNC double determinant(const double4x4 x) { return ::simd_determinant(x); } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + static SIMD_CPPFUNC double2x2 inverse(const double2x2 x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) { return ::simd_inverse(x); } + static SIMD_CPPFUNC double3x3 inverse(const double3x3 x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) { return ::simd_inverse(x); } + static SIMD_CPPFUNC double4x4 inverse(const double4x4 x) __API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) { return ::simd_inverse(x); } +#pragma clang diagnostic pop + + static SIMD_CPPFUNC double2x2 operator*(const double a, const double2x2 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double2x3 operator*(const double a, const double2x3 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double2x4 operator*(const double a, const double2x4 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double3x2 operator*(const double a, const double3x2 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double3x3 operator*(const double a, const double3x3 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double3x4 operator*(const double a, const double3x4 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double4x2 operator*(const double a, const double4x2 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double4x3 operator*(const double a, const double4x3 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double4x4 operator*(const double a, const double4x4 x) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double2x2 operator*(const double2x2 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double2x3 operator*(const double2x3 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double2x4 operator*(const double2x4 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double3x2 operator*(const double3x2 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double3x3 operator*(const double3x3 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double3x4 operator*(const double3x4 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double4x2 operator*(const double4x2 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double4x3 operator*(const double4x3 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double4x4 operator*(const double4x4 x, const double a) { return ::simd_mul(a, x); } + static SIMD_CPPFUNC double2x2& operator*=(double2x2& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double2x3& operator*=(double2x3& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double2x4& operator*=(double2x4& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double3x2& operator*=(double3x2& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double3x3& operator*=(double3x3& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double3x4& operator*=(double3x4& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double4x2& operator*=(double4x2& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double4x3& operator*=(double4x3& x, const double a) { x = ::simd_mul(a, x); return x; } + static SIMD_CPPFUNC double4x4& operator*=(double4x4& x, const double a) { x = ::simd_mul(a, x); return x; } + + static SIMD_CPPFUNC double2 operator*(const double2 x, const double2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3 operator*(const double2 x, const double3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4 operator*(const double2 x, const double4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2 operator*(const double3 x, const double2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3 operator*(const double3 x, const double3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4 operator*(const double3 x, const double4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2 operator*(const double4 x, const double2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3 operator*(const double4 x, const double3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4 operator*(const double4 x, const double4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2 operator*(const double2x2 x, const double2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2 operator*(const double3x2 x, const double3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2 operator*(const double4x2 x, const double4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3 operator*(const double2x3 x, const double2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3 operator*(const double3x3 x, const double3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3 operator*(const double4x3 x, const double4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4 operator*(const double2x4 x, const double2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4 operator*(const double3x4 x, const double3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4 operator*(const double4x4 x, const double4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2& operator*=(double2& x, const double2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double3& operator*=(double3& x, const double3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double4& operator*=(double4& x, const double4x4 y) { x = ::simd_mul(x, y); return x; } + + static SIMD_CPPFUNC double2x2 operator*(const double2x2 x, const double2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x2 operator*(const double2x2 x, const double3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x2 operator*(const double2x2 x, const double4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x3 operator*(const double2x3 x, const double2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x3 operator*(const double2x3 x, const double3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x3 operator*(const double2x3 x, const double4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x4 operator*(const double2x4 x, const double2x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x4 operator*(const double2x4 x, const double3x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x4 operator*(const double2x4 x, const double4x2 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x2 operator*(const double3x2 x, const double2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x2 operator*(const double3x2 x, const double3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x2 operator*(const double3x2 x, const double4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x3 operator*(const double3x3 x, const double2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x3 operator*(const double3x3 x, const double3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x3 operator*(const double3x3 x, const double4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x4 operator*(const double3x4 x, const double2x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x4 operator*(const double3x4 x, const double3x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x4 operator*(const double3x4 x, const double4x3 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x2 operator*(const double4x2 x, const double2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x2 operator*(const double4x2 x, const double3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x2 operator*(const double4x2 x, const double4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x3 operator*(const double4x3 x, const double2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x3 operator*(const double4x3 x, const double3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x3 operator*(const double4x3 x, const double4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x4 operator*(const double4x4 x, const double2x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double3x4 operator*(const double4x4 x, const double3x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double4x4 operator*(const double4x4 x, const double4x4 y) { return ::simd_mul(x, y); } + static SIMD_CPPFUNC double2x2& operator*=(double2x2& x, const double2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double2x3& operator*=(double2x3& x, const double2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double2x4& operator*=(double2x4& x, const double2x2 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double3x2& operator*=(double3x2& x, const double3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double3x3& operator*=(double3x3& x, const double3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double3x4& operator*=(double3x4& x, const double3x3 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double4x2& operator*=(double4x2& x, const double4x4 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double4x3& operator*=(double4x3& x, const double4x4 y) { x = ::simd_mul(x, y); return x; } + static SIMD_CPPFUNC double4x4& operator*=(double4x4& x, const double4x4 y) { x = ::simd_mul(x, y); return x; } + + static SIMD_CPPFUNC bool operator==(const double2x2& x, const double2x2& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double2x3& x, const double2x3& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double2x4& x, const double2x4& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double3x2& x, const double3x2& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double3x3& x, const double3x3& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double3x4& x, const double3x4& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double4x2& x, const double4x2& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double4x3& x, const double4x3& y) { return ::simd_equal(x, y); } + static SIMD_CPPFUNC bool operator==(const double4x4& x, const double4x4& y) { return ::simd_equal(x, y); } + + static SIMD_CPPFUNC bool operator!=(const double2x2& x, const double2x2& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double2x3& x, const double2x3& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double2x4& x, const double2x4& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double3x2& x, const double3x2& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double3x3& x, const double3x3& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double3x4& x, const double3x4& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double4x2& x, const double4x2& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double4x3& x, const double4x3& y) { return !(x == y); } + static SIMD_CPPFUNC bool operator!=(const double4x4& x, const double4x4& y) { return !(x == y); } + + static SIMD_CPPFUNC bool almost_equal_elements(const double2x2 x, const double2x2 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double2x3 x, const double2x3 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double2x4 x, const double2x4 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double3x2 x, const double3x2 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double3x3 x, const double3x3 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double3x4 x, const double3x4 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double4x2 x, const double4x2 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double4x3 x, const double4x3 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements(const double4x4 x, const double4x4 y, const double tol) { return ::simd_almost_equal_elements(x, y, tol); } + + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double2x2 x, const double2x2 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double2x3 x, const double2x3 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double2x4 x, const double2x4 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double3x2 x, const double3x2 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double3x3 x, const double3x3 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double3x4 x, const double3x4 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double4x2 x, const double4x2 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double4x3 x, const double4x3 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } + static SIMD_CPPFUNC bool almost_equal_elements_relative(const double4x4 x, const double4x4 y, const double tol) { return ::simd_almost_equal_elements_relative(x, y, tol); } +} + +extern "C" { +#endif /* __cplusplus */ + +#pragma mark - Implementation + +static simd_float2x2 SIMD_CFUNC simd_diagonal_matrix(simd_float2 __x) { simd_float2x2 __r = { .columns[0] = {__x.x,0}, .columns[1] = {0,__x.y} }; return __r; } +static simd_double2x2 SIMD_CFUNC simd_diagonal_matrix(simd_double2 __x) { simd_double2x2 __r = { .columns[0] = {__x.x,0}, .columns[1] = {0,__x.y} }; return __r; } +static simd_float3x3 SIMD_CFUNC simd_diagonal_matrix(simd_float3 __x) { simd_float3x3 __r = { .columns[0] = {__x.x,0,0}, .columns[1] = {0,__x.y,0}, .columns[2] = {0,0,__x.z} }; return __r; } +static simd_double3x3 SIMD_CFUNC simd_diagonal_matrix(simd_double3 __x) { simd_double3x3 __r = { .columns[0] = {__x.x,0,0}, .columns[1] = {0,__x.y,0}, .columns[2] = {0,0,__x.z} }; return __r; } +static simd_float4x4 SIMD_CFUNC simd_diagonal_matrix(simd_float4 __x) { simd_float4x4 __r = { .columns[0] = {__x.x,0,0,0}, .columns[1] = {0,__x.y,0,0}, .columns[2] = {0,0,__x.z,0}, .columns[3] = {0,0,0,__x.w} }; return __r; } +static simd_double4x4 SIMD_CFUNC simd_diagonal_matrix(simd_double4 __x) { simd_double4x4 __r = { .columns[0] = {__x.x,0,0,0}, .columns[1] = {0,__x.y,0,0}, .columns[2] = {0,0,__x.z,0}, .columns[3] = {0,0,0,__x.w} }; return __r; } + +static simd_float2x2 SIMD_CFUNC simd_matrix(simd_float2 col0, simd_float2 col1) { simd_float2x2 __r = { .columns[0] = col0, .columns[1] = col1 }; return __r; } +static simd_float2x3 SIMD_CFUNC simd_matrix(simd_float3 col0, simd_float3 col1) { simd_float2x3 __r = { .columns[0] = col0, .columns[1] = col1 }; return __r; } +static simd_float2x4 SIMD_CFUNC simd_matrix(simd_float4 col0, simd_float4 col1) { simd_float2x4 __r = { .columns[0] = col0, .columns[1] = col1 }; return __r; } +static simd_double2x2 SIMD_CFUNC simd_matrix(simd_double2 col0, simd_double2 col1) { simd_double2x2 __r = { .columns[0] = col0, .columns[1] = col1 }; return __r; } +static simd_double2x3 SIMD_CFUNC simd_matrix(simd_double3 col0, simd_double3 col1) { simd_double2x3 __r = { .columns[0] = col0, .columns[1] = col1 }; return __r; } +static simd_double2x4 SIMD_CFUNC simd_matrix(simd_double4 col0, simd_double4 col1) { simd_double2x4 __r = { .columns[0] = col0, .columns[1] = col1 }; return __r; } +static simd_float3x2 SIMD_CFUNC simd_matrix(simd_float2 col0, simd_float2 col1, simd_float2 col2) { simd_float3x2 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2 }; return __r; } +static simd_float3x3 SIMD_CFUNC simd_matrix(simd_float3 col0, simd_float3 col1, simd_float3 col2) { simd_float3x3 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2 }; return __r; } +static simd_float3x4 SIMD_CFUNC simd_matrix(simd_float4 col0, simd_float4 col1, simd_float4 col2) { simd_float3x4 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2 }; return __r; } +static simd_double3x2 SIMD_CFUNC simd_matrix(simd_double2 col0, simd_double2 col1, simd_double2 col2) { simd_double3x2 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2 }; return __r; } +static simd_double3x3 SIMD_CFUNC simd_matrix(simd_double3 col0, simd_double3 col1, simd_double3 col2) { simd_double3x3 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2 }; return __r; } +static simd_double3x4 SIMD_CFUNC simd_matrix(simd_double4 col0, simd_double4 col1, simd_double4 col2) { simd_double3x4 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2 }; return __r; } +static simd_float4x2 SIMD_CFUNC simd_matrix(simd_float2 col0, simd_float2 col1, simd_float2 col2, simd_float2 col3) { simd_float4x2 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2, .columns[3] = col3 }; return __r; } +static simd_float4x3 SIMD_CFUNC simd_matrix(simd_float3 col0, simd_float3 col1, simd_float3 col2, simd_float3 col3) { simd_float4x3 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2, .columns[3] = col3 }; return __r; } +static simd_float4x4 SIMD_CFUNC simd_matrix(simd_float4 col0, simd_float4 col1, simd_float4 col2, simd_float4 col3) { simd_float4x4 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2, .columns[3] = col3 }; return __r; } +static simd_double4x2 SIMD_CFUNC simd_matrix(simd_double2 col0, simd_double2 col1, simd_double2 col2, simd_double2 col3) { simd_double4x2 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2, .columns[3] = col3 }; return __r; } +static simd_double4x3 SIMD_CFUNC simd_matrix(simd_double3 col0, simd_double3 col1, simd_double3 col2, simd_double3 col3) { simd_double4x3 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2, .columns[3] = col3 }; return __r; } +static simd_double4x4 SIMD_CFUNC simd_matrix(simd_double4 col0, simd_double4 col1, simd_double4 col2, simd_double4 col3) { simd_double4x4 __r = { .columns[0] = col0, .columns[1] = col1, .columns[2] = col2, .columns[3] = col3 }; return __r; } + +static simd_float2x2 SIMD_CFUNC simd_matrix_from_rows(simd_float2 row0, simd_float2 row1) { return simd_transpose(simd_matrix(row0, row1)); } +static simd_float3x2 SIMD_CFUNC simd_matrix_from_rows(simd_float3 row0, simd_float3 row1) { return simd_transpose(simd_matrix(row0, row1)); } +static simd_float4x2 SIMD_CFUNC simd_matrix_from_rows(simd_float4 row0, simd_float4 row1) { return simd_transpose(simd_matrix(row0, row1)); } +static simd_double2x2 SIMD_CFUNC simd_matrix_from_rows(simd_double2 row0, simd_double2 row1) { return simd_transpose(simd_matrix(row0, row1)); } +static simd_double3x2 SIMD_CFUNC simd_matrix_from_rows(simd_double3 row0, simd_double3 row1) { return simd_transpose(simd_matrix(row0, row1)); } +static simd_double4x2 SIMD_CFUNC simd_matrix_from_rows(simd_double4 row0, simd_double4 row1) { return simd_transpose(simd_matrix(row0, row1)); } +static simd_float2x3 SIMD_CFUNC simd_matrix_from_rows(simd_float2 row0, simd_float2 row1, simd_float2 row2) { return simd_transpose(simd_matrix(row0, row1, row2)); } +static simd_float3x3 SIMD_CFUNC simd_matrix_from_rows(simd_float3 row0, simd_float3 row1, simd_float3 row2) { return simd_transpose(simd_matrix(row0, row1, row2)); } +static simd_float4x3 SIMD_CFUNC simd_matrix_from_rows(simd_float4 row0, simd_float4 row1, simd_float4 row2) { return simd_transpose(simd_matrix(row0, row1, row2)); } +static simd_double2x3 SIMD_CFUNC simd_matrix_from_rows(simd_double2 row0, simd_double2 row1, simd_double2 row2) { return simd_transpose(simd_matrix(row0, row1, row2)); } +static simd_double3x3 SIMD_CFUNC simd_matrix_from_rows(simd_double3 row0, simd_double3 row1, simd_double3 row2) { return simd_transpose(simd_matrix(row0, row1, row2)); } +static simd_double4x3 SIMD_CFUNC simd_matrix_from_rows(simd_double4 row0, simd_double4 row1, simd_double4 row2) { return simd_transpose(simd_matrix(row0, row1, row2)); } +static simd_float2x4 SIMD_CFUNC simd_matrix_from_rows(simd_float2 row0, simd_float2 row1, simd_float2 row2, simd_float2 row3) { return simd_transpose(simd_matrix(row0, row1, row2, row3)); } +static simd_float3x4 SIMD_CFUNC simd_matrix_from_rows(simd_float3 row0, simd_float3 row1, simd_float3 row2, simd_float3 row3) { return simd_transpose(simd_matrix(row0, row1, row2, row3)); } +static simd_float4x4 SIMD_CFUNC simd_matrix_from_rows(simd_float4 row0, simd_float4 row1, simd_float4 row2, simd_float4 row3) { return simd_transpose(simd_matrix(row0, row1, row2, row3)); } +static simd_double2x4 SIMD_CFUNC simd_matrix_from_rows(simd_double2 row0, simd_double2 row1, simd_double2 row2, simd_double2 row3) { return simd_transpose(simd_matrix(row0, row1, row2, row3)); } +static simd_double3x4 SIMD_CFUNC simd_matrix_from_rows(simd_double3 row0, simd_double3 row1, simd_double3 row2, simd_double3 row3) { return simd_transpose(simd_matrix(row0, row1, row2, row3)); } +static simd_double4x4 SIMD_CFUNC simd_matrix_from_rows(simd_double4 row0, simd_double4 row1, simd_double4 row2, simd_double4 row3) { return simd_transpose(simd_matrix(row0, row1, row2, row3)); } + +static simd_float3x3 SIMD_NOINLINE simd_matrix3x3(simd_quatf q) { + simd_float4x4 r = simd_matrix4x4(q); + return (simd_float3x3){ r.columns[0].xyz, r.columns[1].xyz, r.columns[2].xyz }; +} + +static simd_float4x4 SIMD_NOINLINE simd_matrix4x4(simd_quatf q) { + simd_float4 v = q.vector; + simd_float4x4 r = { + .columns[0] = { 1 - 2*(v.y*v.y + v.z*v.z), + 2*(v.x*v.y + v.z*v.w), + 2*(v.x*v.z - v.y*v.w), 0 }, + .columns[1] = { 2*(v.x*v.y - v.z*v.w), + 1 - 2*(v.z*v.z + v.x*v.x), + 2*(v.y*v.z + v.x*v.w), 0 }, + .columns[2] = { 2*(v.z*v.x + v.y*v.w), + 2*(v.y*v.z - v.x*v.w), + 1 - 2*(v.y*v.y + v.x*v.x), 0 }, + .columns[3] = { 0, 0, 0, 1 } + }; + return r; +} + +static simd_double3x3 SIMD_NOINLINE simd_matrix3x3(simd_quatd q) { + simd_double4x4 r = simd_matrix4x4(q); + return (simd_double3x3){ r.columns[0].xyz, r.columns[1].xyz, r.columns[2].xyz }; +} + +static simd_double4x4 SIMD_NOINLINE simd_matrix4x4(simd_quatd q) { + simd_double4 v = q.vector; + simd_double4x4 r = { + .columns[0] = { 1 - 2*(v.y*v.y + v.z*v.z), + 2*(v.x*v.y + v.z*v.w), + 2*(v.x*v.z - v.y*v.w), 0 }, + .columns[1] = { 2*(v.x*v.y - v.z*v.w), + 1 - 2*(v.z*v.z + v.x*v.x), + 2*(v.y*v.z + v.x*v.w), 0 }, + .columns[2] = { 2*(v.z*v.x + v.y*v.w), + 2*(v.y*v.z - v.x*v.w), + 1 - 2*(v.y*v.y + v.x*v.x), 0 }, + .columns[3] = { 0, 0, 0, 1 } + }; + return r; +} + +static simd_float2x2 SIMD_CFUNC matrix_scale(float __a, simd_float2x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_float3x2 SIMD_CFUNC matrix_scale(float __a, simd_float3x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_float4x2 SIMD_CFUNC matrix_scale(float __a, simd_float4x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_float2x3 SIMD_CFUNC matrix_scale(float __a, simd_float2x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_float3x3 SIMD_CFUNC matrix_scale(float __a, simd_float3x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_float4x3 SIMD_CFUNC matrix_scale(float __a, simd_float4x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_float2x4 SIMD_CFUNC matrix_scale(float __a, simd_float2x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_float3x4 SIMD_CFUNC matrix_scale(float __a, simd_float3x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_float4x4 SIMD_CFUNC matrix_scale(float __a, simd_float4x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_double2x2 SIMD_CFUNC matrix_scale(double __a, simd_double2x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_double3x2 SIMD_CFUNC matrix_scale(double __a, simd_double3x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_double4x2 SIMD_CFUNC matrix_scale(double __a, simd_double4x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_double2x3 SIMD_CFUNC matrix_scale(double __a, simd_double2x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_double3x3 SIMD_CFUNC matrix_scale(double __a, simd_double3x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_double4x3 SIMD_CFUNC matrix_scale(double __a, simd_double4x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_double2x4 SIMD_CFUNC matrix_scale(double __a, simd_double2x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_double3x4 SIMD_CFUNC matrix_scale(double __a, simd_double3x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_double4x4 SIMD_CFUNC matrix_scale(double __a, simd_double4x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } + +static simd_float2x2 SIMD_CFUNC simd_mul(float __a, simd_float2x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_float3x2 SIMD_CFUNC simd_mul(float __a, simd_float3x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_float4x2 SIMD_CFUNC simd_mul(float __a, simd_float4x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_float2x3 SIMD_CFUNC simd_mul(float __a, simd_float2x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_float3x3 SIMD_CFUNC simd_mul(float __a, simd_float3x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_float4x3 SIMD_CFUNC simd_mul(float __a, simd_float4x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_float2x4 SIMD_CFUNC simd_mul(float __a, simd_float2x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_float3x4 SIMD_CFUNC simd_mul(float __a, simd_float3x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_float4x4 SIMD_CFUNC simd_mul(float __a, simd_float4x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_double2x2 SIMD_CFUNC simd_mul(double __a, simd_double2x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_double3x2 SIMD_CFUNC simd_mul(double __a, simd_double3x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_double4x2 SIMD_CFUNC simd_mul(double __a, simd_double4x2 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_double2x3 SIMD_CFUNC simd_mul(double __a, simd_double2x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_double3x3 SIMD_CFUNC simd_mul(double __a, simd_double3x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_double4x3 SIMD_CFUNC simd_mul(double __a, simd_double4x3 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } +static simd_double2x4 SIMD_CFUNC simd_mul(double __a, simd_double2x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; return __x; } +static simd_double3x4 SIMD_CFUNC simd_mul(double __a, simd_double3x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; return __x; } +static simd_double4x4 SIMD_CFUNC simd_mul(double __a, simd_double4x4 __x) { __x.columns[0] *= __a; __x.columns[1] *= __a; __x.columns[2] *= __a; __x.columns[3] *= __a; return __x; } + +static simd_float2x2 SIMD_CFUNC simd_linear_combination(float __a, simd_float2x2 __x, float __b, simd_float2x2 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + return __x; +} +static simd_float3x2 SIMD_CFUNC simd_linear_combination(float __a, simd_float3x2 __x, float __b, simd_float3x2 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + return __x; +} +static simd_float4x2 SIMD_CFUNC simd_linear_combination(float __a, simd_float4x2 __x, float __b, simd_float4x2 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + __x.columns[3] = __a*__x.columns[3] + __b*__y.columns[3]; + return __x; +} +static simd_float2x3 SIMD_CFUNC simd_linear_combination(float __a, simd_float2x3 __x, float __b, simd_float2x3 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + return __x; +} +static simd_float3x3 SIMD_CFUNC simd_linear_combination(float __a, simd_float3x3 __x, float __b, simd_float3x3 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + return __x; +} +static simd_float4x3 SIMD_CFUNC simd_linear_combination(float __a, simd_float4x3 __x, float __b, simd_float4x3 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + __x.columns[3] = __a*__x.columns[3] + __b*__y.columns[3]; + return __x; +} +static simd_float2x4 SIMD_CFUNC simd_linear_combination(float __a, simd_float2x4 __x, float __b, simd_float2x4 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + return __x; +} +static simd_float3x4 SIMD_CFUNC simd_linear_combination(float __a, simd_float3x4 __x, float __b, simd_float3x4 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + return __x; +} +static simd_float4x4 SIMD_CFUNC simd_linear_combination(float __a, simd_float4x4 __x, float __b, simd_float4x4 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + __x.columns[3] = __a*__x.columns[3] + __b*__y.columns[3]; + return __x; +} +static simd_double2x2 SIMD_CFUNC simd_linear_combination(double __a, simd_double2x2 __x, double __b, simd_double2x2 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + return __x; +} +static simd_double3x2 SIMD_CFUNC simd_linear_combination(double __a, simd_double3x2 __x, double __b, simd_double3x2 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + return __x; +} +static simd_double4x2 SIMD_CFUNC simd_linear_combination(double __a, simd_double4x2 __x, double __b, simd_double4x2 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + __x.columns[3] = __a*__x.columns[3] + __b*__y.columns[3]; + return __x; +} +static simd_double2x3 SIMD_CFUNC simd_linear_combination(double __a, simd_double2x3 __x, double __b, simd_double2x3 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + return __x; +} +static simd_double3x3 SIMD_CFUNC simd_linear_combination(double __a, simd_double3x3 __x, double __b, simd_double3x3 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + return __x; +} +static simd_double4x3 SIMD_CFUNC simd_linear_combination(double __a, simd_double4x3 __x, double __b, simd_double4x3 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + __x.columns[3] = __a*__x.columns[3] + __b*__y.columns[3]; + return __x; +} +static simd_double2x4 SIMD_CFUNC simd_linear_combination(double __a, simd_double2x4 __x, double __b, simd_double2x4 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + return __x; +} +static simd_double3x4 SIMD_CFUNC simd_linear_combination(double __a, simd_double3x4 __x, double __b, simd_double3x4 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + return __x; +} +static simd_double4x4 SIMD_CFUNC simd_linear_combination(double __a, simd_double4x4 __x, double __b, simd_double4x4 __y) { + __x.columns[0] = __a*__x.columns[0] + __b*__y.columns[0]; + __x.columns[1] = __a*__x.columns[1] + __b*__y.columns[1]; + __x.columns[2] = __a*__x.columns[2] + __b*__y.columns[2]; + __x.columns[3] = __a*__x.columns[3] + __b*__y.columns[3]; + return __x; +} + +static simd_float2x2 SIMD_CFUNC simd_add(simd_float2x2 __x, simd_float2x2 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float3x2 SIMD_CFUNC simd_add(simd_float3x2 __x, simd_float3x2 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float4x2 SIMD_CFUNC simd_add(simd_float4x2 __x, simd_float4x2 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float2x3 SIMD_CFUNC simd_add(simd_float2x3 __x, simd_float2x3 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float3x3 SIMD_CFUNC simd_add(simd_float3x3 __x, simd_float3x3 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float4x3 SIMD_CFUNC simd_add(simd_float4x3 __x, simd_float4x3 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float2x4 SIMD_CFUNC simd_add(simd_float2x4 __x, simd_float2x4 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float3x4 SIMD_CFUNC simd_add(simd_float3x4 __x, simd_float3x4 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_float4x4 SIMD_CFUNC simd_add(simd_float4x4 __x, simd_float4x4 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double2x2 SIMD_CFUNC simd_add(simd_double2x2 __x, simd_double2x2 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double3x2 SIMD_CFUNC simd_add(simd_double3x2 __x, simd_double3x2 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double4x2 SIMD_CFUNC simd_add(simd_double4x2 __x, simd_double4x2 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double2x3 SIMD_CFUNC simd_add(simd_double2x3 __x, simd_double2x3 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double3x3 SIMD_CFUNC simd_add(simd_double3x3 __x, simd_double3x3 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double4x3 SIMD_CFUNC simd_add(simd_double4x3 __x, simd_double4x3 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double2x4 SIMD_CFUNC simd_add(simd_double2x4 __x, simd_double2x4 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double3x4 SIMD_CFUNC simd_add(simd_double3x4 __x, simd_double3x4 __y) { return simd_linear_combination(1, __x, 1, __y); } +static simd_double4x4 SIMD_CFUNC simd_add(simd_double4x4 __x, simd_double4x4 __y) { return simd_linear_combination(1, __x, 1, __y); } + +static simd_float2x2 SIMD_CFUNC simd_sub(simd_float2x2 __x, simd_float2x2 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float3x2 SIMD_CFUNC simd_sub(simd_float3x2 __x, simd_float3x2 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float4x2 SIMD_CFUNC simd_sub(simd_float4x2 __x, simd_float4x2 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float2x3 SIMD_CFUNC simd_sub(simd_float2x3 __x, simd_float2x3 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float3x3 SIMD_CFUNC simd_sub(simd_float3x3 __x, simd_float3x3 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float4x3 SIMD_CFUNC simd_sub(simd_float4x3 __x, simd_float4x3 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float2x4 SIMD_CFUNC simd_sub(simd_float2x4 __x, simd_float2x4 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float3x4 SIMD_CFUNC simd_sub(simd_float3x4 __x, simd_float3x4 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_float4x4 SIMD_CFUNC simd_sub(simd_float4x4 __x, simd_float4x4 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double2x2 SIMD_CFUNC simd_sub(simd_double2x2 __x, simd_double2x2 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double3x2 SIMD_CFUNC simd_sub(simd_double3x2 __x, simd_double3x2 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double4x2 SIMD_CFUNC simd_sub(simd_double4x2 __x, simd_double4x2 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double2x3 SIMD_CFUNC simd_sub(simd_double2x3 __x, simd_double2x3 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double3x3 SIMD_CFUNC simd_sub(simd_double3x3 __x, simd_double3x3 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double4x3 SIMD_CFUNC simd_sub(simd_double4x3 __x, simd_double4x3 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double2x4 SIMD_CFUNC simd_sub(simd_double2x4 __x, simd_double2x4 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double3x4 SIMD_CFUNC simd_sub(simd_double3x4 __x, simd_double3x4 __y) { return simd_linear_combination(1, __x, -1, __y); } +static simd_double4x4 SIMD_CFUNC simd_sub(simd_double4x4 __x, simd_double4x4 __y) { return simd_linear_combination(1, __x, -1, __y); } + +static simd_float2x2 SIMD_CFUNC simd_transpose(simd_float2x2 __x) { +#if defined __SSE__ + simd_float4 __x0, __x1; + __x0.xy = __x.columns[0]; + __x1.xy = __x.columns[1]; + simd_float4 __r01 = _mm_unpacklo_ps(__x0, __x1); + return simd_matrix(__r01.lo, __r01.hi); +#else + return simd_matrix((simd_float2){__x.columns[0][0], __x.columns[1][0]}, + (simd_float2){__x.columns[0][1], __x.columns[1][1]}); +#endif +} + +static simd_float3x2 SIMD_CFUNC simd_transpose(simd_float2x3 __x) { +#if defined __SSE__ + simd_float4 __x0, __x1; + __x0.xyz = __x.columns[0]; + __x1.xyz = __x.columns[1]; + simd_float4 __r01 = _mm_unpacklo_ps(__x0, __x1); + simd_float4 __r2x = _mm_unpackhi_ps(__x0, __x1); + return simd_matrix(__r01.lo, __r01.hi, __r2x.lo); +#else + return simd_matrix((simd_float2){__x.columns[0][0], __x.columns[1][0]}, + (simd_float2){__x.columns[0][1], __x.columns[1][1]}, + (simd_float2){__x.columns[0][2], __x.columns[1][2]}); +#endif +} + +static simd_float4x2 SIMD_CFUNC simd_transpose(simd_float2x4 __x) { +#if defined __SSE__ + simd_float4 __r01 = _mm_unpacklo_ps(__x.columns[0], __x.columns[1]); + simd_float4 __r23 = _mm_unpackhi_ps(__x.columns[0], __x.columns[1]); + return simd_matrix(__r01.lo, __r01.hi, __r23.lo, __r23.hi); +#else + return simd_matrix((simd_float2){__x.columns[0][0], __x.columns[1][0]}, + (simd_float2){__x.columns[0][1], __x.columns[1][1]}, + (simd_float2){__x.columns[0][2], __x.columns[1][2]}, + (simd_float2){__x.columns[0][3], __x.columns[1][3]}); +#endif +} + +static simd_float2x3 SIMD_CFUNC simd_transpose(simd_float3x2 __x) { +#if defined __SSE__ + simd_float4 __x0, __x1, __x2; + __x0.xy = __x.columns[0]; + __x1.xy = __x.columns[1]; + __x2.xy = __x.columns[2]; + simd_float4 __t = _mm_unpacklo_ps(__x0, __x1); + simd_float4 __r0 = _mm_shuffle_ps(__t,__x2,0xc4); + simd_float4 __r1 = _mm_shuffle_ps(__t,__x2,0xde); + return simd_matrix(__r0.xyz, __r1.xyz); +#else + return simd_matrix((simd_float3){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0]}, + (simd_float3){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1]}); +#endif +} + +static simd_float3x3 SIMD_CFUNC simd_transpose(simd_float3x3 __x) { +#if defined __SSE__ + simd_float4 __x0, __x1, __x2; + __x0.xyz = __x.columns[0]; + __x1.xyz = __x.columns[1]; + __x2.xyz = __x.columns[2]; + simd_float4 __t0 = _mm_unpacklo_ps(__x0, __x1); + simd_float4 __t1 = _mm_unpackhi_ps(__x0, __x1); + simd_float4 __r0 = __t0; __r0.hi = __x2.lo; + simd_float4 __r1 = _mm_shuffle_ps(__t0, __x2, 0xde); + simd_float4 __r2 = __x2; __r2.lo = __t1.lo; + return simd_matrix(__r0.xyz, __r1.xyz, __r2.xyz); +#else + return simd_matrix((simd_float3){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0]}, + (simd_float3){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1]}, + (simd_float3){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2]}); +#endif +} + +static simd_float4x3 SIMD_CFUNC simd_transpose(simd_float3x4 __x) { +#if defined __SSE__ + simd_float4 __t0 = _mm_unpacklo_ps(__x.columns[0],__x.columns[1]); /* 00 10 01 11 */ + simd_float4 __t1 = _mm_unpackhi_ps(__x.columns[0],__x.columns[1]); /* 02 12 03 13 */ + simd_float4 __r0 = __t0; __r0.hi = __x.columns[2].lo; + simd_float4 __r1 = _mm_shuffle_ps(__t0, __x.columns[2], 0xde); + simd_float4 __r2 = __x.columns[2]; __r2.lo = __t1.lo; + simd_float4 __r3 = _mm_shuffle_ps(__t1, __x.columns[2], 0xfe); + return simd_matrix(__r0.xyz, __r1.xyz, __r2.xyz, __r3.xyz); +#else + return simd_matrix((simd_float3){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0]}, + (simd_float3){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1]}, + (simd_float3){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2]}, + (simd_float3){__x.columns[0][3], __x.columns[1][3], __x.columns[2][3]}); +#endif +} + +static simd_float2x4 SIMD_CFUNC simd_transpose(simd_float4x2 __x) { +#if defined __SSE__ + simd_float4 __x0, __x1, __x2, __x3; + __x0.xy = __x.columns[0]; + __x1.xy = __x.columns[1]; + __x2.xy = __x.columns[2]; + __x3.xy = __x.columns[3]; + simd_float4 __t0 = _mm_unpacklo_ps(__x0,__x2); + simd_float4 __t1 = _mm_unpacklo_ps(__x1,__x3); + simd_float4 __r0 = _mm_unpacklo_ps(__t0,__t1); + simd_float4 __r1 = _mm_unpackhi_ps(__t0,__t1); + return simd_matrix(__r0,__r1); +#else + return simd_matrix((simd_float4){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0], __x.columns[3][0]}, + (simd_float4){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1], __x.columns[3][1]}); +#endif +} + +static simd_float3x4 SIMD_CFUNC simd_transpose(simd_float4x3 __x) { +#if defined __SSE__ + simd_float4 __x0, __x1, __x2, __x3; + __x0.xyz = __x.columns[0]; + __x1.xyz = __x.columns[1]; + __x2.xyz = __x.columns[2]; + __x3.xyz = __x.columns[3]; + simd_float4 __t0 = _mm_unpacklo_ps(__x0,__x2); + simd_float4 __t1 = _mm_unpackhi_ps(__x0,__x2); + simd_float4 __t2 = _mm_unpacklo_ps(__x1,__x3); + simd_float4 __t3 = _mm_unpackhi_ps(__x1,__x3); + simd_float4 __r0 = _mm_unpacklo_ps(__t0,__t2); + simd_float4 __r1 = _mm_unpackhi_ps(__t0,__t2); + simd_float4 __r2 = _mm_unpacklo_ps(__t1,__t3); + return simd_matrix(__r0,__r1,__r2); +#else + return simd_matrix((simd_float4){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0], __x.columns[3][0]}, + (simd_float4){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1], __x.columns[3][1]}, + (simd_float4){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2], __x.columns[3][2]}); +#endif +} + +static simd_float4x4 SIMD_CFUNC simd_transpose(simd_float4x4 __x) { +#if defined __SSE__ + simd_float4 __t0 = _mm_unpacklo_ps(__x.columns[0],__x.columns[2]); + simd_float4 __t1 = _mm_unpackhi_ps(__x.columns[0],__x.columns[2]); + simd_float4 __t2 = _mm_unpacklo_ps(__x.columns[1],__x.columns[3]); + simd_float4 __t3 = _mm_unpackhi_ps(__x.columns[1],__x.columns[3]); + simd_float4 __r0 = _mm_unpacklo_ps(__t0,__t2); + simd_float4 __r1 = _mm_unpackhi_ps(__t0,__t2); + simd_float4 __r2 = _mm_unpacklo_ps(__t1,__t3); + simd_float4 __r3 = _mm_unpackhi_ps(__t1,__t3); + return simd_matrix(__r0,__r1,__r2,__r3); +#else + return simd_matrix((simd_float4){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0], __x.columns[3][0]}, + (simd_float4){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1], __x.columns[3][1]}, + (simd_float4){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2], __x.columns[3][2]}, + (simd_float4){__x.columns[0][3], __x.columns[1][3], __x.columns[2][3], __x.columns[3][3]}); +#endif +} + +static simd_double2x2 SIMD_CFUNC simd_transpose(simd_double2x2 __x) { + return simd_matrix((simd_double2){__x.columns[0][0], __x.columns[1][0]}, + (simd_double2){__x.columns[0][1], __x.columns[1][1]}); +} + +static simd_double3x2 SIMD_CFUNC simd_transpose(simd_double2x3 __x) { + return simd_matrix((simd_double2){__x.columns[0][0], __x.columns[1][0]}, + (simd_double2){__x.columns[0][1], __x.columns[1][1]}, + (simd_double2){__x.columns[0][2], __x.columns[1][2]}); +} + +static simd_double4x2 SIMD_CFUNC simd_transpose(simd_double2x4 __x) { + return simd_matrix((simd_double2){__x.columns[0][0], __x.columns[1][0]}, + (simd_double2){__x.columns[0][1], __x.columns[1][1]}, + (simd_double2){__x.columns[0][2], __x.columns[1][2]}, + (simd_double2){__x.columns[0][3], __x.columns[1][3]}); +} + +static simd_double2x3 SIMD_CFUNC simd_transpose(simd_double3x2 __x) { + return simd_matrix((simd_double3){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0]}, + (simd_double3){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1]}); +} + +static simd_double3x3 SIMD_CFUNC simd_transpose(simd_double3x3 __x) { + return simd_matrix((simd_double3){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0]}, + (simd_double3){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1]}, + (simd_double3){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2]}); +} + +static simd_double4x3 SIMD_CFUNC simd_transpose(simd_double3x4 __x) { + return simd_matrix((simd_double3){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0]}, + (simd_double3){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1]}, + (simd_double3){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2]}, + (simd_double3){__x.columns[0][3], __x.columns[1][3], __x.columns[2][3]}); +} + +static simd_double2x4 SIMD_CFUNC simd_transpose(simd_double4x2 __x) { + return simd_matrix((simd_double4){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0], __x.columns[3][0]}, + (simd_double4){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1], __x.columns[3][1]}); +} + +static simd_double3x4 SIMD_CFUNC simd_transpose(simd_double4x3 __x) { + return simd_matrix((simd_double4){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0], __x.columns[3][0]}, + (simd_double4){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1], __x.columns[3][1]}, + (simd_double4){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2], __x.columns[3][2]}); +} + +static simd_double4x4 SIMD_CFUNC simd_transpose(simd_double4x4 __x) { + return simd_matrix((simd_double4){__x.columns[0][0], __x.columns[1][0], __x.columns[2][0], __x.columns[3][0]}, + (simd_double4){__x.columns[0][1], __x.columns[1][1], __x.columns[2][1], __x.columns[3][1]}, + (simd_double4){__x.columns[0][2], __x.columns[1][2], __x.columns[2][2], __x.columns[3][2]}, + (simd_double4){__x.columns[0][3], __x.columns[1][3], __x.columns[2][3], __x.columns[3][3]}); +} + +static simd_float3 SIMD_CFUNC __rotate1( simd_float3 __x) { return __builtin_shufflevector(__x,__x,1,2,0); } +static simd_float3 SIMD_CFUNC __rotate2( simd_float3 __x) { return __builtin_shufflevector(__x,__x,2,0,1); } +static simd_float4 SIMD_CFUNC __rotate1( simd_float4 __x) { return __builtin_shufflevector(__x,__x,1,2,3,0); } +static simd_float4 SIMD_CFUNC __rotate2( simd_float4 __x) { return __builtin_shufflevector(__x,__x,2,3,0,1); } +static simd_float4 SIMD_CFUNC __rotate3( simd_float4 __x) { return __builtin_shufflevector(__x,__x,3,0,1,2); } +static simd_double3 SIMD_CFUNC __rotate1(simd_double3 __x) { return __builtin_shufflevector(__x,__x,1,2,0); } +static simd_double3 SIMD_CFUNC __rotate2(simd_double3 __x) { return __builtin_shufflevector(__x,__x,2,0,1); } +static simd_double4 SIMD_CFUNC __rotate1(simd_double4 __x) { return __builtin_shufflevector(__x,__x,1,2,3,0); } +static simd_double4 SIMD_CFUNC __rotate2(simd_double4 __x) { return __builtin_shufflevector(__x,__x,2,3,0,1); } +static simd_double4 SIMD_CFUNC __rotate3(simd_double4 __x) { return __builtin_shufflevector(__x,__x,3,0,1,2); } + +static float SIMD_CFUNC simd_determinant( simd_float2x2 __x) { return __x.columns[0][0]*__x.columns[1][1] - __x.columns[0][1]*__x.columns[1][0]; } +static double SIMD_CFUNC simd_determinant(simd_double2x2 __x) { return __x.columns[0][0]*__x.columns[1][1] - __x.columns[0][1]*__x.columns[1][0]; } +static float SIMD_CFUNC simd_determinant( simd_float3x3 __x) { return simd_reduce_add(__x.columns[0]*(__rotate1(__x.columns[1])*__rotate2(__x.columns[2]) - __rotate2(__x.columns[1])*__rotate1(__x.columns[2]))); } +static double SIMD_CFUNC simd_determinant(simd_double3x3 __x) { return simd_reduce_add(__x.columns[0]*(__rotate1(__x.columns[1])*__rotate2(__x.columns[2]) - __rotate2(__x.columns[1])*__rotate1(__x.columns[2]))); } +static float SIMD_CFUNC simd_determinant( simd_float4x4 __x) { + simd_float4 codet = __x.columns[0]*(__rotate1(__x.columns[1])*(__rotate2(__x.columns[2])*__rotate3(__x.columns[3])-__rotate3(__x.columns[2])*__rotate2(__x.columns[3])) + + __rotate2(__x.columns[1])*(__rotate3(__x.columns[2])*__rotate1(__x.columns[3])-__rotate1(__x.columns[2])*__rotate3(__x.columns[3])) + + __rotate3(__x.columns[1])*(__rotate1(__x.columns[2])*__rotate2(__x.columns[3])-__rotate2(__x.columns[2])*__rotate1(__x.columns[3]))); + return simd_reduce_add(codet.even - codet.odd); +} +static double SIMD_CFUNC simd_determinant(simd_double4x4 __x) { + simd_double4 codet = __x.columns[0]*(__rotate1(__x.columns[1])*(__rotate2(__x.columns[2])*__rotate3(__x.columns[3])-__rotate3(__x.columns[2])*__rotate2(__x.columns[3])) + + __rotate2(__x.columns[1])*(__rotate3(__x.columns[2])*__rotate1(__x.columns[3])-__rotate1(__x.columns[2])*__rotate3(__x.columns[3])) + + __rotate3(__x.columns[1])*(__rotate1(__x.columns[2])*__rotate2(__x.columns[3])-__rotate2(__x.columns[2])*__rotate1(__x.columns[3]))); + return simd_reduce_add(codet.even - codet.odd); +} + +static simd_float2x2 SIMD_CFUNC simd_inverse( simd_float2x2 __x) { return __invert_f2(__x); } +static simd_float3x3 SIMD_CFUNC simd_inverse( simd_float3x3 __x) { return __invert_f3(__x); } +static simd_float4x4 SIMD_CFUNC simd_inverse( simd_float4x4 __x) { return __invert_f4(__x); } +static simd_double2x2 SIMD_CFUNC simd_inverse(simd_double2x2 __x) { return __invert_d2(__x); } +static simd_double3x3 SIMD_CFUNC simd_inverse(simd_double3x3 __x) { return __invert_d3(__x); } +static simd_double4x4 SIMD_CFUNC simd_inverse(simd_double4x4 __x) { return __invert_d4(__x); } + +static simd_float2 SIMD_CFUNC simd_mul( simd_float2x2 __x, simd_float2 __y) { simd_float2 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); return __r; } +static simd_float3 SIMD_CFUNC simd_mul( simd_float2x3 __x, simd_float2 __y) { simd_float3 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); return __r; } +static simd_float4 SIMD_CFUNC simd_mul( simd_float2x4 __x, simd_float2 __y) { simd_float4 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); return __r; } +static simd_float2 SIMD_CFUNC simd_mul( simd_float3x2 __x, simd_float3 __y) { simd_float2 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); return __r; } +static simd_float3 SIMD_CFUNC simd_mul( simd_float3x3 __x, simd_float3 __y) { simd_float3 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); return __r; } +static simd_float4 SIMD_CFUNC simd_mul( simd_float3x4 __x, simd_float3 __y) { simd_float4 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); return __r; } +static simd_float2 SIMD_CFUNC simd_mul( simd_float4x2 __x, simd_float4 __y) { simd_float2 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); __r = simd_muladd( __x.columns[3], __y[3],__r); return __r; } +static simd_float3 SIMD_CFUNC simd_mul( simd_float4x3 __x, simd_float4 __y) { simd_float3 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); __r = simd_muladd( __x.columns[3], __y[3],__r); return __r; } +static simd_float4 SIMD_CFUNC simd_mul( simd_float4x4 __x, simd_float4 __y) { simd_float4 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); __r = simd_muladd( __x.columns[3], __y[3],__r); return __r; } +static simd_double2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double2 __y) { simd_double2 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); return __r; } +static simd_double3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double2 __y) { simd_double3 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); return __r; } +static simd_double4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double2 __y) { simd_double4 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); return __r; } +static simd_double2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double3 __y) { simd_double2 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); return __r; } +static simd_double3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double3 __y) { simd_double3 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); return __r; } +static simd_double4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double3 __y) { simd_double4 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); return __r; } +static simd_double2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double4 __y) { simd_double2 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); __r = simd_muladd( __x.columns[3], __y[3],__r); return __r; } +static simd_double3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double4 __y) { simd_double3 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); __r = simd_muladd( __x.columns[3], __y[3],__r); return __r; } +static simd_double4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double4 __y) { simd_double4 __r = __x.columns[0]*__y[0]; __r = simd_muladd( __x.columns[1], __y[1],__r); __r = simd_muladd( __x.columns[2], __y[2],__r); __r = simd_muladd( __x.columns[3], __y[3],__r); return __r; } + +static simd_float2 SIMD_CFUNC simd_mul( simd_float2 __x, simd_float2x2 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float3 SIMD_CFUNC simd_mul( simd_float2 __x, simd_float3x2 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float4 SIMD_CFUNC simd_mul( simd_float2 __x, simd_float4x2 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float2 SIMD_CFUNC simd_mul( simd_float3 __x, simd_float2x3 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float3 SIMD_CFUNC simd_mul( simd_float3 __x, simd_float3x3 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float4 SIMD_CFUNC simd_mul( simd_float3 __x, simd_float4x3 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float2 SIMD_CFUNC simd_mul( simd_float4 __x, simd_float2x4 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float3 SIMD_CFUNC simd_mul( simd_float4 __x, simd_float3x4 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_float4 SIMD_CFUNC simd_mul( simd_float4 __x, simd_float4x4 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double2 SIMD_CFUNC simd_mul(simd_double2 __x, simd_double2x2 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double3 SIMD_CFUNC simd_mul(simd_double2 __x, simd_double3x2 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double4 SIMD_CFUNC simd_mul(simd_double2 __x, simd_double4x2 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double2 SIMD_CFUNC simd_mul(simd_double3 __x, simd_double2x3 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double3 SIMD_CFUNC simd_mul(simd_double3 __x, simd_double3x3 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double4 SIMD_CFUNC simd_mul(simd_double3 __x, simd_double4x3 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double2 SIMD_CFUNC simd_mul(simd_double4 __x, simd_double2x4 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double3 SIMD_CFUNC simd_mul(simd_double4 __x, simd_double3x4 __y) { return simd_mul(simd_transpose(__y), __x); } +static simd_double4 SIMD_CFUNC simd_mul(simd_double4 __x, simd_double4x4 __y) { return simd_mul(simd_transpose(__y), __x); } + +static simd_float2x2 SIMD_CFUNC simd_mul( simd_float2x2 __x, simd_float2x2 __y) { simd_float2x2 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double2x2 __y) { simd_double2x2 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x3 SIMD_CFUNC simd_mul( simd_float2x3 __x, simd_float2x2 __y) { simd_float2x3 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double2x2 __y) { simd_double2x3 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x4 SIMD_CFUNC simd_mul( simd_float2x4 __x, simd_float2x2 __y) { simd_float2x4 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double2x2 __y) { simd_double2x4 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x2 SIMD_CFUNC simd_mul( simd_float3x2 __x, simd_float2x3 __y) { simd_float2x2 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double2x3 __y) { simd_double2x2 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x3 SIMD_CFUNC simd_mul( simd_float3x3 __x, simd_float2x3 __y) { simd_float2x3 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double2x3 __y) { simd_double2x3 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x4 SIMD_CFUNC simd_mul( simd_float3x4 __x, simd_float2x3 __y) { simd_float2x4 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double2x3 __y) { simd_double2x4 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x2 SIMD_CFUNC simd_mul( simd_float4x2 __x, simd_float2x4 __y) { simd_float2x2 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double2x4 __y) { simd_double2x2 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x3 SIMD_CFUNC simd_mul( simd_float4x3 __x, simd_float2x4 __y) { simd_float2x3 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double2x4 __y) { simd_double2x3 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float2x4 SIMD_CFUNC simd_mul( simd_float4x4 __x, simd_float2x4 __y) { simd_float2x4 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double2x4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double2x4 __y) { simd_double2x4 __r; for (int i=0; i<2; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } + +static simd_float3x2 SIMD_CFUNC simd_mul( simd_float2x2 __x, simd_float3x2 __y) { simd_float3x2 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double3x2 __y) { simd_double3x2 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x3 SIMD_CFUNC simd_mul( simd_float2x3 __x, simd_float3x2 __y) { simd_float3x3 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double3x2 __y) { simd_double3x3 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x4 SIMD_CFUNC simd_mul( simd_float2x4 __x, simd_float3x2 __y) { simd_float3x4 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double3x2 __y) { simd_double3x4 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x2 SIMD_CFUNC simd_mul( simd_float3x2 __x, simd_float3x3 __y) { simd_float3x2 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double3x3 __y) { simd_double3x2 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x3 SIMD_CFUNC simd_mul( simd_float3x3 __x, simd_float3x3 __y) { simd_float3x3 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double3x3 __y) { simd_double3x3 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x4 SIMD_CFUNC simd_mul( simd_float3x4 __x, simd_float3x3 __y) { simd_float3x4 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double3x3 __y) { simd_double3x4 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x2 SIMD_CFUNC simd_mul( simd_float4x2 __x, simd_float3x4 __y) { simd_float3x2 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double3x4 __y) { simd_double3x2 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x3 SIMD_CFUNC simd_mul( simd_float4x3 __x, simd_float3x4 __y) { simd_float3x3 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double3x4 __y) { simd_double3x3 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float3x4 SIMD_CFUNC simd_mul( simd_float4x4 __x, simd_float3x4 __y) { simd_float3x4 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double3x4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double3x4 __y) { simd_double3x4 __r; for (int i=0; i<3; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } + +static simd_float4x2 SIMD_CFUNC simd_mul( simd_float2x2 __x, simd_float4x2 __y) { simd_float4x2 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x2 SIMD_CFUNC simd_mul(simd_double2x2 __x, simd_double4x2 __y) { simd_double4x2 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x3 SIMD_CFUNC simd_mul( simd_float2x3 __x, simd_float4x2 __y) { simd_float4x3 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x3 SIMD_CFUNC simd_mul(simd_double2x3 __x, simd_double4x2 __y) { simd_double4x3 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x4 SIMD_CFUNC simd_mul( simd_float2x4 __x, simd_float4x2 __y) { simd_float4x4 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x4 SIMD_CFUNC simd_mul(simd_double2x4 __x, simd_double4x2 __y) { simd_double4x4 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x2 SIMD_CFUNC simd_mul( simd_float3x2 __x, simd_float4x3 __y) { simd_float4x2 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x2 SIMD_CFUNC simd_mul(simd_double3x2 __x, simd_double4x3 __y) { simd_double4x2 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x3 SIMD_CFUNC simd_mul( simd_float3x3 __x, simd_float4x3 __y) { simd_float4x3 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x3 SIMD_CFUNC simd_mul(simd_double3x3 __x, simd_double4x3 __y) { simd_double4x3 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x4 SIMD_CFUNC simd_mul( simd_float3x4 __x, simd_float4x3 __y) { simd_float4x4 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x4 SIMD_CFUNC simd_mul(simd_double3x4 __x, simd_double4x3 __y) { simd_double4x4 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x2 SIMD_CFUNC simd_mul( simd_float4x2 __x, simd_float4x4 __y) { simd_float4x2 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x2 SIMD_CFUNC simd_mul(simd_double4x2 __x, simd_double4x4 __y) { simd_double4x2 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x3 SIMD_CFUNC simd_mul( simd_float4x3 __x, simd_float4x4 __y) { simd_float4x3 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x3 SIMD_CFUNC simd_mul(simd_double4x3 __x, simd_double4x4 __y) { simd_double4x3 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_float4x4 SIMD_CFUNC simd_mul( simd_float4x4 __x, simd_float4x4 __y) { simd_float4x4 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } +static simd_double4x4 SIMD_CFUNC simd_mul(simd_double4x4 __x, simd_double4x4 __y) { simd_double4x4 __r; for (int i=0; i<4; ++i) __r.columns[i] = simd_mul(__x, __y.columns[i]); return __r; } + +static simd_float2 SIMD_CFUNC matrix_multiply( simd_float2x2 __x, simd_float2 __y) { return simd_mul(__x, __y); } +static simd_float3 SIMD_CFUNC matrix_multiply( simd_float2x3 __x, simd_float2 __y) { return simd_mul(__x, __y); } +static simd_float4 SIMD_CFUNC matrix_multiply( simd_float2x4 __x, simd_float2 __y) { return simd_mul(__x, __y); } +static simd_float2 SIMD_CFUNC matrix_multiply( simd_float3x2 __x, simd_float3 __y) { return simd_mul(__x, __y); } +static simd_float3 SIMD_CFUNC matrix_multiply( simd_float3x3 __x, simd_float3 __y) { return simd_mul(__x, __y); } +static simd_float4 SIMD_CFUNC matrix_multiply( simd_float3x4 __x, simd_float3 __y) { return simd_mul(__x, __y); } +static simd_float2 SIMD_CFUNC matrix_multiply( simd_float4x2 __x, simd_float4 __y) { return simd_mul(__x, __y); } +static simd_float3 SIMD_CFUNC matrix_multiply( simd_float4x3 __x, simd_float4 __y) { return simd_mul(__x, __y); } +static simd_float4 SIMD_CFUNC matrix_multiply( simd_float4x4 __x, simd_float4 __y) { return simd_mul(__x, __y); } +static simd_double2 SIMD_CFUNC matrix_multiply(simd_double2x2 __x, simd_double2 __y) { return simd_mul(__x, __y); } +static simd_double3 SIMD_CFUNC matrix_multiply(simd_double2x3 __x, simd_double2 __y) { return simd_mul(__x, __y); } +static simd_double4 SIMD_CFUNC matrix_multiply(simd_double2x4 __x, simd_double2 __y) { return simd_mul(__x, __y); } +static simd_double2 SIMD_CFUNC matrix_multiply(simd_double3x2 __x, simd_double3 __y) { return simd_mul(__x, __y); } +static simd_double3 SIMD_CFUNC matrix_multiply(simd_double3x3 __x, simd_double3 __y) { return simd_mul(__x, __y); } +static simd_double4 SIMD_CFUNC matrix_multiply(simd_double3x4 __x, simd_double3 __y) { return simd_mul(__x, __y); } +static simd_double2 SIMD_CFUNC matrix_multiply(simd_double4x2 __x, simd_double4 __y) { return simd_mul(__x, __y); } +static simd_double3 SIMD_CFUNC matrix_multiply(simd_double4x3 __x, simd_double4 __y) { return simd_mul(__x, __y); } +static simd_double4 SIMD_CFUNC matrix_multiply(simd_double4x4 __x, simd_double4 __y) { return simd_mul(__x, __y); } + +static simd_float2 SIMD_CFUNC matrix_multiply( simd_float2 __x, simd_float2x2 __y) { return simd_mul(__x, __y); } +static simd_float3 SIMD_CFUNC matrix_multiply( simd_float2 __x, simd_float3x2 __y) { return simd_mul(__x, __y); } +static simd_float4 SIMD_CFUNC matrix_multiply( simd_float2 __x, simd_float4x2 __y) { return simd_mul(__x, __y); } +static simd_float2 SIMD_CFUNC matrix_multiply( simd_float3 __x, simd_float2x3 __y) { return simd_mul(__x, __y); } +static simd_float3 SIMD_CFUNC matrix_multiply( simd_float3 __x, simd_float3x3 __y) { return simd_mul(__x, __y); } +static simd_float4 SIMD_CFUNC matrix_multiply( simd_float3 __x, simd_float4x3 __y) { return simd_mul(__x, __y); } +static simd_float2 SIMD_CFUNC matrix_multiply( simd_float4 __x, simd_float2x4 __y) { return simd_mul(__x, __y); } +static simd_float3 SIMD_CFUNC matrix_multiply( simd_float4 __x, simd_float3x4 __y) { return simd_mul(__x, __y); } +static simd_float4 SIMD_CFUNC matrix_multiply( simd_float4 __x, simd_float4x4 __y) { return simd_mul(__x, __y); } +static simd_double2 SIMD_CFUNC matrix_multiply(simd_double2 __x, simd_double2x2 __y) { return simd_mul(__x, __y); } +static simd_double3 SIMD_CFUNC matrix_multiply(simd_double2 __x, simd_double3x2 __y) { return simd_mul(__x, __y); } +static simd_double4 SIMD_CFUNC matrix_multiply(simd_double2 __x, simd_double4x2 __y) { return simd_mul(__x, __y); } +static simd_double2 SIMD_CFUNC matrix_multiply(simd_double3 __x, simd_double2x3 __y) { return simd_mul(__x, __y); } +static simd_double3 SIMD_CFUNC matrix_multiply(simd_double3 __x, simd_double3x3 __y) { return simd_mul(__x, __y); } +static simd_double4 SIMD_CFUNC matrix_multiply(simd_double3 __x, simd_double4x3 __y) { return simd_mul(__x, __y); } +static simd_double2 SIMD_CFUNC matrix_multiply(simd_double4 __x, simd_double2x4 __y) { return simd_mul(__x, __y); } +static simd_double3 SIMD_CFUNC matrix_multiply(simd_double4 __x, simd_double3x4 __y) { return simd_mul(__x, __y); } +static simd_double4 SIMD_CFUNC matrix_multiply(simd_double4 __x, simd_double4x4 __y) { return simd_mul(__x, __y); } + +static simd_float2x2 SIMD_CFUNC matrix_multiply( simd_float2x2 __x, simd_float2x2 __y) { return simd_mul(__x, __y); } +static simd_double2x2 SIMD_CFUNC matrix_multiply(simd_double2x2 __x, simd_double2x2 __y) { return simd_mul(__x, __y); } +static simd_float2x3 SIMD_CFUNC matrix_multiply( simd_float2x3 __x, simd_float2x2 __y) { return simd_mul(__x, __y); } +static simd_double2x3 SIMD_CFUNC matrix_multiply(simd_double2x3 __x, simd_double2x2 __y) { return simd_mul(__x, __y); } +static simd_float2x4 SIMD_CFUNC matrix_multiply( simd_float2x4 __x, simd_float2x2 __y) { return simd_mul(__x, __y); } +static simd_double2x4 SIMD_CFUNC matrix_multiply(simd_double2x4 __x, simd_double2x2 __y) { return simd_mul(__x, __y); } +static simd_float2x2 SIMD_CFUNC matrix_multiply( simd_float3x2 __x, simd_float2x3 __y) { return simd_mul(__x, __y); } +static simd_double2x2 SIMD_CFUNC matrix_multiply(simd_double3x2 __x, simd_double2x3 __y) { return simd_mul(__x, __y); } +static simd_float2x3 SIMD_CFUNC matrix_multiply( simd_float3x3 __x, simd_float2x3 __y) { return simd_mul(__x, __y); } +static simd_double2x3 SIMD_CFUNC matrix_multiply(simd_double3x3 __x, simd_double2x3 __y) { return simd_mul(__x, __y); } +static simd_float2x4 SIMD_CFUNC matrix_multiply( simd_float3x4 __x, simd_float2x3 __y) { return simd_mul(__x, __y); } +static simd_double2x4 SIMD_CFUNC matrix_multiply(simd_double3x4 __x, simd_double2x3 __y) { return simd_mul(__x, __y); } +static simd_float2x2 SIMD_CFUNC matrix_multiply( simd_float4x2 __x, simd_float2x4 __y) { return simd_mul(__x, __y); } +static simd_double2x2 SIMD_CFUNC matrix_multiply(simd_double4x2 __x, simd_double2x4 __y) { return simd_mul(__x, __y); } +static simd_float2x3 SIMD_CFUNC matrix_multiply( simd_float4x3 __x, simd_float2x4 __y) { return simd_mul(__x, __y); } +static simd_double2x3 SIMD_CFUNC matrix_multiply(simd_double4x3 __x, simd_double2x4 __y) { return simd_mul(__x, __y); } +static simd_float2x4 SIMD_CFUNC matrix_multiply( simd_float4x4 __x, simd_float2x4 __y) { return simd_mul(__x, __y); } +static simd_double2x4 SIMD_CFUNC matrix_multiply(simd_double4x4 __x, simd_double2x4 __y) { return simd_mul(__x, __y); } + +static simd_float3x2 SIMD_CFUNC matrix_multiply( simd_float2x2 __x, simd_float3x2 __y) { return simd_mul(__x, __y); } +static simd_double3x2 SIMD_CFUNC matrix_multiply(simd_double2x2 __x, simd_double3x2 __y) { return simd_mul(__x, __y); } +static simd_float3x3 SIMD_CFUNC matrix_multiply( simd_float2x3 __x, simd_float3x2 __y) { return simd_mul(__x, __y); } +static simd_double3x3 SIMD_CFUNC matrix_multiply(simd_double2x3 __x, simd_double3x2 __y) { return simd_mul(__x, __y); } +static simd_float3x4 SIMD_CFUNC matrix_multiply( simd_float2x4 __x, simd_float3x2 __y) { return simd_mul(__x, __y); } +static simd_double3x4 SIMD_CFUNC matrix_multiply(simd_double2x4 __x, simd_double3x2 __y) { return simd_mul(__x, __y); } +static simd_float3x2 SIMD_CFUNC matrix_multiply( simd_float3x2 __x, simd_float3x3 __y) { return simd_mul(__x, __y); } +static simd_double3x2 SIMD_CFUNC matrix_multiply(simd_double3x2 __x, simd_double3x3 __y) { return simd_mul(__x, __y); } +static simd_float3x3 SIMD_CFUNC matrix_multiply( simd_float3x3 __x, simd_float3x3 __y) { return simd_mul(__x, __y); } +static simd_double3x3 SIMD_CFUNC matrix_multiply(simd_double3x3 __x, simd_double3x3 __y) { return simd_mul(__x, __y); } +static simd_float3x4 SIMD_CFUNC matrix_multiply( simd_float3x4 __x, simd_float3x3 __y) { return simd_mul(__x, __y); } +static simd_double3x4 SIMD_CFUNC matrix_multiply(simd_double3x4 __x, simd_double3x3 __y) { return simd_mul(__x, __y); } +static simd_float3x2 SIMD_CFUNC matrix_multiply( simd_float4x2 __x, simd_float3x4 __y) { return simd_mul(__x, __y); } +static simd_double3x2 SIMD_CFUNC matrix_multiply(simd_double4x2 __x, simd_double3x4 __y) { return simd_mul(__x, __y); } +static simd_float3x3 SIMD_CFUNC matrix_multiply( simd_float4x3 __x, simd_float3x4 __y) { return simd_mul(__x, __y); } +static simd_double3x3 SIMD_CFUNC matrix_multiply(simd_double4x3 __x, simd_double3x4 __y) { return simd_mul(__x, __y); } +static simd_float3x4 SIMD_CFUNC matrix_multiply( simd_float4x4 __x, simd_float3x4 __y) { return simd_mul(__x, __y); } +static simd_double3x4 SIMD_CFUNC matrix_multiply(simd_double4x4 __x, simd_double3x4 __y) { return simd_mul(__x, __y); } + +static simd_float4x2 SIMD_CFUNC matrix_multiply( simd_float2x2 __x, simd_float4x2 __y) { return simd_mul(__x, __y); } +static simd_double4x2 SIMD_CFUNC matrix_multiply(simd_double2x2 __x, simd_double4x2 __y) { return simd_mul(__x, __y); } +static simd_float4x3 SIMD_CFUNC matrix_multiply( simd_float2x3 __x, simd_float4x2 __y) { return simd_mul(__x, __y); } +static simd_double4x3 SIMD_CFUNC matrix_multiply(simd_double2x3 __x, simd_double4x2 __y) { return simd_mul(__x, __y); } +static simd_float4x4 SIMD_CFUNC matrix_multiply( simd_float2x4 __x, simd_float4x2 __y) { return simd_mul(__x, __y); } +static simd_double4x4 SIMD_CFUNC matrix_multiply(simd_double2x4 __x, simd_double4x2 __y) { return simd_mul(__x, __y); } +static simd_float4x2 SIMD_CFUNC matrix_multiply( simd_float3x2 __x, simd_float4x3 __y) { return simd_mul(__x, __y); } +static simd_double4x2 SIMD_CFUNC matrix_multiply(simd_double3x2 __x, simd_double4x3 __y) { return simd_mul(__x, __y); } +static simd_float4x3 SIMD_CFUNC matrix_multiply( simd_float3x3 __x, simd_float4x3 __y) { return simd_mul(__x, __y); } +static simd_double4x3 SIMD_CFUNC matrix_multiply(simd_double3x3 __x, simd_double4x3 __y) { return simd_mul(__x, __y); } +static simd_float4x4 SIMD_CFUNC matrix_multiply( simd_float3x4 __x, simd_float4x3 __y) { return simd_mul(__x, __y); } +static simd_double4x4 SIMD_CFUNC matrix_multiply(simd_double3x4 __x, simd_double4x3 __y) { return simd_mul(__x, __y); } +static simd_float4x2 SIMD_CFUNC matrix_multiply( simd_float4x2 __x, simd_float4x4 __y) { return simd_mul(__x, __y); } +static simd_double4x2 SIMD_CFUNC matrix_multiply(simd_double4x2 __x, simd_double4x4 __y) { return simd_mul(__x, __y); } +static simd_float4x3 SIMD_CFUNC matrix_multiply( simd_float4x3 __x, simd_float4x4 __y) { return simd_mul(__x, __y); } +static simd_double4x3 SIMD_CFUNC matrix_multiply(simd_double4x3 __x, simd_double4x4 __y) { return simd_mul(__x, __y); } +static simd_float4x4 SIMD_CFUNC matrix_multiply( simd_float4x4 __x, simd_float4x4 __y) { return simd_mul(__x, __y); } +static simd_double4x4 SIMD_CFUNC matrix_multiply(simd_double4x4 __x, simd_double4x4 __y) { return simd_mul(__x, __y); } + +static simd_bool SIMD_CFUNC simd_equal(simd_float2x2 __x, simd_float2x2 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float2x3 __x, simd_float2x3 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float2x4 __x, simd_float2x4 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float3x2 __x, simd_float3x2 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float3x3 __x, simd_float3x3 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float3x4 __x, simd_float3x4 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float4x2 __x, simd_float4x2 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2]) & + (__x.columns[3] == __y.columns[3])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float4x3 __x, simd_float4x3 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2]) & + (__x.columns[3] == __y.columns[3])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_float4x4 __x, simd_float4x4 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2]) & + (__x.columns[3] == __y.columns[3])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double2x2 __x, simd_double2x2 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double2x3 __x, simd_double2x3 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double2x4 __x, simd_double2x4 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double3x2 __x, simd_double3x2 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double3x3 __x, simd_double3x3 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double3x4 __x, simd_double3x4 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double4x2 __x, simd_double4x2 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2]) & + (__x.columns[3] == __y.columns[3])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double4x3 __x, simd_double4x3 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2]) & + (__x.columns[3] == __y.columns[3])); +} +static simd_bool SIMD_CFUNC simd_equal(simd_double4x4 __x, simd_double4x4 __y) { + return simd_all((__x.columns[0] == __y.columns[0]) & + (__x.columns[1] == __y.columns[1]) & + (__x.columns[2] == __y.columns[2]) & + (__x.columns[3] == __y.columns[3])); +} + +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float2x2 __x, simd_float2x2 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float2x3 __x, simd_float2x3 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float2x4 __x, simd_float2x4 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float3x2 __x, simd_float3x2 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float3x3 __x, simd_float3x3 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float3x4 __x, simd_float3x4 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float4x2 __x, simd_float4x2 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float4x3 __x, simd_float4x3 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_float4x4 __x, simd_float4x4 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double2x2 __x, simd_double2x2 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double2x3 __x, simd_double2x3 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double2x4 __x, simd_double2x4 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double3x2 __x, simd_double3x2 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double3x3 __x, simd_double3x3 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double3x4 __x, simd_double3x4 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double4x2 __x, simd_double4x2 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double4x3 __x, simd_double4x3 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol)); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements(simd_double4x4 __x, simd_double4x4 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol)); +} + +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float2x2 __x, simd_float2x2 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float2x3 __x, simd_float2x3 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float2x4 __x, simd_float2x4 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float3x2 __x, simd_float3x2 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float3x3 __x, simd_float3x3 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float3x4 __x, simd_float3x4 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float4x2 __x, simd_float4x2 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2])) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol*__tg_fabs(__x.columns[3]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float4x3 __x, simd_float4x3 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2])) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol*__tg_fabs(__x.columns[3]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_float4x4 __x, simd_float4x4 __y, float __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2])) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol*__tg_fabs(__x.columns[3]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double2x2 __x, simd_double2x2 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double2x3 __x, simd_double2x3 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double2x4 __x, simd_double2x4 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double3x2 __x, simd_double3x2 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double3x3 __x, simd_double3x3 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double3x4 __x, simd_double3x4 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double4x2 __x, simd_double4x2 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2])) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol*__tg_fabs(__x.columns[3]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double4x3 __x, simd_double4x3 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2])) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol*__tg_fabs(__x.columns[3]))); +} +static simd_bool SIMD_CFUNC simd_almost_equal_elements_relative(simd_double4x4 __x, simd_double4x4 __y, double __tol) { + return simd_all((__tg_fabs(__x.columns[0] - __y.columns[0]) <= __tol*__tg_fabs(__x.columns[0])) & + (__tg_fabs(__x.columns[1] - __y.columns[1]) <= __tol*__tg_fabs(__x.columns[1])) & + (__tg_fabs(__x.columns[2] - __y.columns[2]) <= __tol*__tg_fabs(__x.columns[2])) & + (__tg_fabs(__x.columns[3] - __y.columns[3]) <= __tol*__tg_fabs(__x.columns[3]))); +} + +#ifdef __cplusplus +} +#endif +#endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* __SIMD_HEADER__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/matrix_types.h b/lib/libc/include/any-macos.11-any/simd/matrix_types.h new file mode 100644 index 0000000000..904df687a6 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/matrix_types.h @@ -0,0 +1,264 @@ +/* Copyright (c) 2014-2017 Apple, Inc. All rights reserved. + * + * This header defines nine matrix types for each of float and double, which + * are intended for use together with the vector types defined in + * . + * + * For compatibility with common graphics libraries, these matrices are stored + * in column-major order, and implemented as arrays of column vectors. + * Column-major storage order may seem a little strange if you aren't used to + * it, but for most usage the memory layout of the matrices shouldn't matter + * at all; instead you should think of matrices as abstract mathematical + * objects that you use to perform arithmetic without worrying about the + * details of the underlying representation. + * + * WARNING: vectors of length three are internally represented as length four + * vectors with one element of padding (for alignment purposes). This means + * that when a floatNx3 or doubleNx3 is viewed as a vector, it appears to + * have 4*N elements instead of the expected 3*N (with one padding element + * at the end of each column). The matrix elements are laid out in memory + * as follows: + * + * { 0, 1, 2, x, 3, 4, 5, x, ... } + * + * (where the scalar indices used above indicate the conceptual column- + * major storage order). If you aren't monkeying around with the internal + * storage details of matrices, you don't need to worry about this at all. + * Consider this yet another good reason to avoid doing so. */ + +#ifndef SIMD_MATRIX_TYPES_HEADER +#define SIMD_MATRIX_TYPES_HEADER + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES + +/* Matrix types available in C, Objective-C, and C++ */ +typedef simd_float2x2 matrix_float2x2; +typedef simd_float3x2 matrix_float3x2; +typedef simd_float4x2 matrix_float4x2; + +typedef simd_float2x3 matrix_float2x3; +typedef simd_float3x3 matrix_float3x3; +typedef simd_float4x3 matrix_float4x3; + +typedef simd_float2x4 matrix_float2x4; +typedef simd_float3x4 matrix_float3x4; +typedef simd_float4x4 matrix_float4x4; + +typedef simd_double2x2 matrix_double2x2; +typedef simd_double3x2 matrix_double3x2; +typedef simd_double4x2 matrix_double4x2; + +typedef simd_double2x3 matrix_double2x3; +typedef simd_double3x3 matrix_double3x3; +typedef simd_double4x3 matrix_double4x3; + +typedef simd_double2x4 matrix_double2x4; +typedef simd_double3x4 matrix_double3x4; +typedef simd_double4x4 matrix_double4x4; + +#ifdef __cplusplus +#if defined SIMD_MATRIX_HEADER +static simd_float3x3 SIMD_NOINLINE simd_matrix3x3(simd_quatf q); +static simd_float4x4 SIMD_NOINLINE simd_matrix4x4(simd_quatf q); +static simd_double3x3 SIMD_NOINLINE simd_matrix3x3(simd_quatd q); +static simd_double4x4 SIMD_NOINLINE simd_matrix4x4(simd_quatd q); +#endif + +namespace simd { + + struct float2x2 : ::simd_float2x2 { + float2x2() { columns[0] = 0; columns[1] = 0; } +#if __has_feature(cxx_delegating_constructors) + float2x2(float diagonal) : float2x2((float2)diagonal) { } +#endif + float2x2(float2 v) { columns[0] = (float2){v.x,0}; columns[1] = (float2){0,v.y}; } + float2x2(float2 c0, float2 c1) { columns[0] = c0; columns[1] = c1; } + float2x2(::simd_float2x2 m) : ::simd_float2x2(m) { } + }; + + struct float3x2 : ::simd_float3x2 { + float3x2() { columns[0] = 0; columns[1] = 0; columns[2] = 0; } +#if __has_feature(cxx_delegating_constructors) + float3x2(float diagonal) : float3x2((float2)diagonal) { } +#endif + float3x2(float2 v) { columns[0] = (float2){v.x,0}; columns[1] = (float2){0,v.y}; columns[2] = 0; } + float3x2(float2 c0, float2 c1, float2 c2) { columns[0] = c0; columns[1] = c1; columns[2] = c2; } + float3x2(::simd_float3x2 m) : ::simd_float3x2(m) { } + }; + + struct float4x2 : ::simd_float4x2 { + float4x2() { columns[0] = 0; columns[1] = 0; columns[2] = 0; columns[3] = 0; } +#if __has_feature(cxx_delegating_constructors) + float4x2(float diagonal) : float4x2((float2)diagonal) { } +#endif + float4x2(float2 v) { columns[0] = (float2){v.x,0}; columns[1] = (float2){0,v.y}; columns[2] = 0; columns[3] = 0; } + float4x2(float2 c0, float2 c1, float2 c2, float2 c3) { columns[0] = c0; columns[1] = c1; columns[2] = c2; columns[3] = c3; } + float4x2(::simd_float4x2 m) : ::simd_float4x2(m) { } + }; + + struct float2x3 : ::simd_float2x3 { + float2x3() { columns[0] = 0; columns[1] = 0; } +#if __has_feature(cxx_delegating_constructors) + float2x3(float diagonal) : float2x3((float2)diagonal) { } +#endif + float2x3(float2 v) { columns[0] = (float3){v.x,0,0}; columns[1] = (float3){0,v.y,0}; } + float2x3(float3 c0, float3 c1) { columns[0] = c0; columns[1] = c1; } + float2x3(::simd_float2x3 m) : ::simd_float2x3(m) { } + }; + + struct float3x3 : ::simd_float3x3 { + float3x3() { columns[0] = 0; columns[1] = 0; columns[2] = 0; } +#if __has_feature(cxx_delegating_constructors) + float3x3(float diagonal) : float3x3((float3)diagonal) { } +#endif + float3x3(float3 v) { columns[0] = (float3){v.x,0,0}; columns[1] = (float3){0,v.y,0}; columns[2] = (float3){0,0,v.z}; } + float3x3(float3 c0, float3 c1, float3 c2) { columns[0] = c0; columns[1] = c1; columns[2] = c2; } + float3x3(::simd_float3x3 m) : ::simd_float3x3(m) { } +#if defined SIMD_MATRIX_HEADER + float3x3(::simd_quatf q) : ::simd_float3x3(::simd_matrix3x3(q)) { } +#endif + }; + + struct float4x3 : ::simd_float4x3 { + float4x3() { columns[0] = 0; columns[1] = 0; columns[2] = 0; columns[3] = 0; } +#if __has_feature(cxx_delegating_constructors) + float4x3(float diagonal) : float4x3((float3)diagonal) { } +#endif + float4x3(float3 v) { columns[0] = (float3){v.x,0,0}; columns[1] = (float3){0,v.y,0}; columns[2] = (float3){0,0,v.z}; columns[3] = 0; } + float4x3(float3 c0, float3 c1, float3 c2, float3 c3) { columns[0] = c0; columns[1] = c1; columns[2] = c2; columns[3] = c3; } + float4x3(::simd_float4x3 m) : ::simd_float4x3(m) { } + }; + + struct float2x4 : ::simd_float2x4 { + float2x4() { columns[0] = 0; columns[1] = 0; } +#if __has_feature(cxx_delegating_constructors) + float2x4(float diagonal) : float2x4((float2)diagonal) { } +#endif + float2x4(float2 v) { columns[0] = (float4){v.x,0,0,0}; columns[1] = (float4){0,v.y,0,0}; } + float2x4(float4 c0, float4 c1) { columns[0] = c0; columns[1] = c1; } + float2x4(::simd_float2x4 m) : ::simd_float2x4(m) { } + }; + + struct float3x4 : ::simd_float3x4 { + float3x4() { columns[0] = 0; columns[1] = 0; columns[2] = 0; } +#if __has_feature(cxx_delegating_constructors) + float3x4(float diagonal) : float3x4((float3)diagonal) { } +#endif + float3x4(float3 v) { columns[0] = (float4){v.x,0,0,0}; columns[1] = (float4){0,v.y,0,0}; columns[2] = (float4){0,0,v.z,0}; } + float3x4(float4 c0, float4 c1, float4 c2) { columns[0] = c0; columns[1] = c1; columns[2] = c2; } + float3x4(::simd_float3x4 m) : ::simd_float3x4(m) { } + }; + + struct float4x4 : ::simd_float4x4 { + float4x4() { columns[0] = 0; columns[1] = 0; columns[2] = 0; columns[3] = 0; } +#if __has_feature(cxx_delegating_constructors) + float4x4(float diagonal) : float4x4((float4)diagonal) { } +#endif + float4x4(float4 v) { columns[0] = (float4){v.x,0,0,0}; columns[1] = (float4){0,v.y,0,0}; columns[2] = (float4){0,0,v.z,0}; columns[3] = (float4){0,0,0,v.w}; } + float4x4(float4 c0, float4 c1, float4 c2, float4 c3) { columns[0] = c0; columns[1] = c1; columns[2] = c2; columns[3] = c3; } + float4x4(::simd_float4x4 m) : ::simd_float4x4(m) { } +#if defined SIMD_MATRIX_HEADER + float4x4(::simd_quatf q) : ::simd_float4x4(::simd_matrix4x4(q)) { } +#endif + }; + + struct double2x2 : ::simd_double2x2 { + double2x2() { columns[0] = 0; columns[1] = 0; } +#if __has_feature(cxx_delegating_constructors) + double2x2(double diagonal) : double2x2((double2)diagonal) { } +#endif + double2x2(double2 v) { columns[0] = (double2){v.x,0}; columns[1] = (double2){0,v.y}; } + double2x2(double2 c0, double2 c1) { columns[0] = c0; columns[1] = c1; } + double2x2(::simd_double2x2 m) : ::simd_double2x2(m) { } + }; + + struct double3x2 : ::simd_double3x2 { + double3x2() { columns[0] = 0; columns[1] = 0; columns[2] = 0; } +#if __has_feature(cxx_delegating_constructors) + double3x2(double diagonal) : double3x2((double2)diagonal) { } +#endif + double3x2(double2 v) { columns[0] = (double2){v.x,0}; columns[1] = (double2){0,v.y}; columns[2] = 0; } + double3x2(double2 c0, double2 c1, double2 c2) { columns[0] = c0; columns[1] = c1; columns[2] = c2; } + double3x2(::simd_double3x2 m) : ::simd_double3x2(m) { } + }; + + struct double4x2 : ::simd_double4x2 { + double4x2() { columns[0] = 0; columns[1] = 0; columns[2] = 0; columns[3] = 0; } +#if __has_feature(cxx_delegating_constructors) + double4x2(double diagonal) : double4x2((double2)diagonal) { } +#endif + double4x2(double2 v) { columns[0] = (double2){v.x,0}; columns[1] = (double2){0,v.y}; columns[2] = 0; columns[3] = 0; } + double4x2(double2 c0, double2 c1, double2 c2, double2 c3) { columns[0] = c0; columns[1] = c1; columns[2] = c2; columns[3] = c3; } + double4x2(::simd_double4x2 m) : ::simd_double4x2(m) { } + }; + + struct double2x3 : ::simd_double2x3 { + double2x3() { columns[0] = 0; columns[1] = 0; } +#if __has_feature(cxx_delegating_constructors) + double2x3(double diagonal) : double2x3((double2)diagonal) { } +#endif + double2x3(double2 v) { columns[0] = (double3){v.x,0,0}; columns[1] = (double3){0,v.y,0}; } + double2x3(double3 c0, double3 c1) { columns[0] = c0; columns[1] = c1; } + double2x3(::simd_double2x3 m) : ::simd_double2x3(m) { } + }; + + struct double3x3 : ::simd_double3x3 { + double3x3() { columns[0] = 0; columns[1] = 0; columns[2] = 0; } +#if __has_feature(cxx_delegating_constructors) + double3x3(double diagonal) : double3x3((double3)diagonal) { } +#endif + double3x3(double3 v) { columns[0] = (double3){v.x,0,0}; columns[1] = (double3){0,v.y,0}; columns[2] = (double3){0,0,v.z}; } + double3x3(double3 c0, double3 c1, double3 c2) { columns[0] = c0; columns[1] = c1; columns[2] = c2; } + double3x3(::simd_double3x3 m) : ::simd_double3x3(m) { } +#if defined SIMD_MATRIX_HEADER + double3x3(::simd_quatd q) : ::simd_double3x3(::simd_matrix3x3(q)) { } +#endif + }; + + struct double4x3 : ::simd_double4x3 { + double4x3() { columns[0] = 0; columns[1] = 0; columns[2] = 0; columns[3] = 0; } +#if __has_feature(cxx_delegating_constructors) + double4x3(double diagonal) : double4x3((double3)diagonal) { } +#endif + double4x3(double3 v) { columns[0] = (double3){v.x,0,0}; columns[1] = (double3){0,v.y,0}; columns[2] = (double3){0,0,v.z}; columns[3] = 0; } + double4x3(double3 c0, double3 c1, double3 c2, double3 c3) { columns[0] = c0; columns[1] = c1; columns[2] = c2; columns[3] = c3; } + double4x3(::simd_double4x3 m) : ::simd_double4x3(m) { } + }; + + struct double2x4 : ::simd_double2x4 { + double2x4() { columns[0] = 0; columns[1] = 0; } +#if __has_feature(cxx_delegating_constructors) + double2x4(double diagonal) : double2x4((double2)diagonal) { } +#endif + double2x4(double2 v) { columns[0] = (double4){v.x,0,0,0}; columns[1] = (double4){0,v.y,0,0}; } + double2x4(double4 c0, double4 c1) { columns[0] = c0; columns[1] = c1; } + double2x4(::simd_double2x4 m) : ::simd_double2x4(m) { } + }; + + struct double3x4 : ::simd_double3x4 { + double3x4() { columns[0] = 0; columns[1] = 0; columns[2] = 0; } +#if __has_feature(cxx_delegating_constructors) + double3x4(double diagonal) : double3x4((double3)diagonal) { } +#endif + double3x4(double3 v) { columns[0] = (double4){v.x,0,0,0}; columns[1] = (double4){0,v.y,0,0}; columns[2] = (double4){0,0,v.z,0}; } + double3x4(double4 c0, double4 c1, double4 c2) { columns[0] = c0; columns[1] = c1; columns[2] = c2; } + double3x4(::simd_double3x4 m) : ::simd_double3x4(m) { } + }; + + struct double4x4 : ::simd_double4x4 { + double4x4() { columns[0] = 0; columns[1] = 0; columns[2] = 0; columns[3] = 0; } +#if __has_feature(cxx_delegating_constructors) + double4x4(double diagonal) : double4x4((double4)diagonal) { } +#endif + double4x4(double4 v) { columns[0] = (double4){v.x,0,0,0}; columns[1] = (double4){0,v.y,0,0}; columns[2] = (double4){0,0,v.z,0}; columns[3] = (double4){0,0,0,v.w}; } + double4x4(double4 c0, double4 c1, double4 c2, double4 c3) { columns[0] = c0; columns[1] = c1; columns[2] = c2; columns[3] = c3; } + double4x4(::simd_double4x4 m) : ::simd_double4x4(m) { } +#if defined SIMD_MATRIX_HEADER + double4x4(::simd_quatd q) : ::simd_double4x4(::simd_matrix4x4(q)) { } +#endif + }; +} +#endif /* __cplusplus */ +#endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* SIMD_MATRIX_TYPES_HEADER */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/quaternion.h b/lib/libc/include/any-macos.11-any/simd/quaternion.h new file mode 100644 index 0000000000..b7c5e2909d --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/quaternion.h @@ -0,0 +1,1194 @@ +/*! @header + * This header defines functions for constructing and using quaternions. + * @copyright 2015-2016 Apple, Inc. All rights reserved. + * @unsorted */ + +#ifndef SIMD_QUATERNIONS +#define SIMD_QUATERNIONS + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* MARK: - C and Objective-C float interfaces */ + +/*! @abstract Constructs a quaternion from four scalar values. + * + * @param ix The first component of the imaginary (vector) part. + * @param iy The second component of the imaginary (vector) part. + * @param iz The third component of the imaginary (vector) part. + * + * @param r The real (scalar) part. */ +static inline SIMD_CFUNC simd_quatf simd_quaternion(float ix, float iy, float iz, float r) { + return (simd_quatf){ { ix, iy, iz, r } }; +} + +/*! @abstract Constructs a quaternion from an array of four scalars. + * + * @discussion Note that the imaginary part of the quaternion comes from + * array elements 0, 1, and 2, and the real part comes from element 3. */ +static inline SIMD_NONCONST simd_quatf simd_quaternion(const float xyzr[4]) { + return (simd_quatf){ *(const simd_packed_float4 *)xyzr }; +} + +/*! @abstract Constructs a quaternion from a four-element vector. + * + * @discussion Note that the imaginary (vector) part of the quaternion comes + * from lanes 0, 1, and 2 of the vector, and the real (scalar) part comes from + * lane 3. */ +static inline SIMD_CFUNC simd_quatf simd_quaternion(simd_float4 xyzr) { + return (simd_quatf){ xyzr }; +} + +/*! @abstract Constructs a quaternion that rotates by `angle` radians about + * `axis`. */ +static inline SIMD_CFUNC simd_quatf simd_quaternion(float angle, simd_float3 axis); + +/*! @abstract Construct a quaternion that rotates from one vector to another. + * + * @param from A normalized three-element vector. + * @param to A normalized three-element vector. + * + * @discussion The rotation axis is `simd_cross(from, to)`. If `from` and + * `to` point in opposite directions (to within machine precision), an + * arbitrary rotation axis is chosen, and the angle is pi radians. */ +static SIMD_NOINLINE simd_quatf simd_quaternion(simd_float3 from, simd_float3 to); + +/*! @abstract Construct a quaternion from a 3x3 rotation `matrix`. + * + * @discussion If `matrix` is not orthogonal with determinant 1, the result + * is undefined. */ +static SIMD_NOINLINE simd_quatf simd_quaternion(simd_float3x3 matrix); + +/*! @abstract Construct a quaternion from a 4x4 rotation `matrix`. + * + * @discussion The last row and column of the matrix are ignored. This + * function is equivalent to calling simd_quaternion with the upper-left 3x3 + * submatrix . */ +static SIMD_NOINLINE simd_quatf simd_quaternion(simd_float4x4 matrix); + +/*! @abstract The real (scalar) part of the quaternion `q`. */ +static inline SIMD_CFUNC float simd_real(simd_quatf q) { + return q.vector.w; +} + +/*! @abstract The imaginary (vector) part of the quaternion `q`. */ +static inline SIMD_CFUNC simd_float3 simd_imag(simd_quatf q) { + return q.vector.xyz; +} + +/*! @abstract The angle (in radians) of rotation represented by `q`. */ +static inline SIMD_CFUNC float simd_angle(simd_quatf q); + +/*! @abstract The normalized axis (a 3-element vector) around which the + * action of the quaternion `q` rotates. */ +static inline SIMD_CFUNC simd_float3 simd_axis(simd_quatf q); + +/*! @abstract The sum of the quaternions `p` and `q`. */ +static inline SIMD_CFUNC simd_quatf simd_add(simd_quatf p, simd_quatf q); + +/*! @abstract The difference of the quaternions `p` and `q`. */ +static inline SIMD_CFUNC simd_quatf simd_sub(simd_quatf p, simd_quatf q); + +/*! @abstract The product of the quaternions `p` and `q`. */ +static inline SIMD_CFUNC simd_quatf simd_mul(simd_quatf p, simd_quatf q); + +/*! @abstract The quaternion `q` scaled by the real value `a`. */ +static inline SIMD_CFUNC simd_quatf simd_mul(simd_quatf q, float a); + +/*! @abstract The quaternion `q` scaled by the real value `a`. */ +static inline SIMD_CFUNC simd_quatf simd_mul(float a, simd_quatf q); + +/*! @abstract The conjugate of the quaternion `q`. */ +static inline SIMD_CFUNC simd_quatf simd_conjugate(simd_quatf q); + +/*! @abstract The (multiplicative) inverse of the quaternion `q`. */ +static inline SIMD_CFUNC simd_quatf simd_inverse(simd_quatf q); + +/*! @abstract The negation (additive inverse) of the quaternion `q`. */ +static inline SIMD_CFUNC simd_quatf simd_negate(simd_quatf q); + +/*! @abstract The dot product of the quaternions `p` and `q` interpreted as + * four-dimensional vectors. */ +static inline SIMD_CFUNC float simd_dot(simd_quatf p, simd_quatf q); + +/*! @abstract The length of the quaternion `q`. */ +static inline SIMD_CFUNC float simd_length(simd_quatf q); + +/*! @abstract The unit quaternion obtained by normalizing `q`. */ +static inline SIMD_CFUNC simd_quatf simd_normalize(simd_quatf q); + +/*! @abstract Rotates the vector `v` by the quaternion `q`. */ +static inline SIMD_CFUNC simd_float3 simd_act(simd_quatf q, simd_float3 v); + +/*! @abstract Logarithm of the quaternion `q`. + * @discussion Do not call this function directly; use `log(q)` instead. + * + * We can write a quaternion `q` in the form: `r(cos(t) + sin(t)v)` where + * `r` is the length of `q`, `t` is an angle, and `v` is a unit 3-vector. + * The logarithm of `q` is `log(r) + tv`, just like the logarithm of the + * complex number `r*(cos(t) + i sin(t))` is `log(r) + it`. + * + * Note that this function is not robust against poorly-scaled non-unit + * quaternions, because it is primarily used for spline interpolation of + * unit quaternions. If you need to compute a robust logarithm of general + * quaternions, you can use the following approach: + * + * scale = simd_reduce_max(simd_abs(q.vector)); + * logq = log(simd_recip(scale)*q); + * logq.real += log(scale); + * return logq; */ +static SIMD_NOINLINE simd_quatf __tg_log(simd_quatf q); + +/*! @abstract Inverse of `log( )`; the exponential map on quaternions. + * @discussion Do not call this function directly; use `exp(q)` instead. */ +static SIMD_NOINLINE simd_quatf __tg_exp(simd_quatf q); + +/*! @abstract Spherical linear interpolation along the shortest arc between + * quaternions `q0` and `q1`. */ +static SIMD_NOINLINE simd_quatf simd_slerp(simd_quatf q0, simd_quatf q1, float t); + +/*! @abstract Spherical linear interpolation along the longest arc between + * quaternions `q0` and `q1`. */ +static SIMD_NOINLINE simd_quatf simd_slerp_longest(simd_quatf q0, simd_quatf q1, float t); + +/*! @abstract Interpolate between quaternions along a spherical cubic spline. + * + * @discussion The function interpolates between q1 and q2. q0 is the left + * endpoint of the previous interval, and q3 is the right endpoint of the next + * interval. Use this function to smoothly interpolate between a sequence of + * rotations. */ +static SIMD_NOINLINE simd_quatf simd_spline(simd_quatf q0, simd_quatf q1, simd_quatf q2, simd_quatf q3, float t); + +/*! @abstract Spherical cubic Bezier interpolation between quaternions. + * + * @discussion The function treats q0 ... q3 as control points and uses slerp + * in place of lerp in the De Castlejeau algorithm. The endpoints of + * interpolation are thus q0 and q3, and the curve will not generally pass + * through q1 or q2. Note that the convex hull property of "standard" Bezier + * curve does not hold on the sphere. */ +static SIMD_NOINLINE simd_quatf simd_bezier(simd_quatf q0, simd_quatf q1, simd_quatf q2, simd_quatf q3, float t); + +#ifdef __cplusplus +} /* extern "C" */ +/* MARK: - C++ float interfaces */ + +namespace simd { + struct quatf : ::simd_quatf { + /*! @abstract The identity quaternion. */ + quatf( ) : ::simd_quatf(::simd_quaternion((float4){0,0,0,1})) { } + + /*! @abstract Constructs a C++ quaternion from a C quaternion. */ + quatf(::simd_quatf q) : ::simd_quatf(q) { } + + /*! @abstract Constructs a quaternion from components. */ + quatf(float ix, float iy, float iz, float r) : ::simd_quatf(::simd_quaternion(ix, iy, iz, r)) { } + + /*! @abstract Constructs a quaternion from an array of scalars. */ + quatf(const float xyzr[4]) : ::simd_quatf(::simd_quaternion(xyzr)) { } + + /*! @abstract Constructs a quaternion from a vector. */ + quatf(float4 xyzr) : ::simd_quatf(::simd_quaternion(xyzr)) { } + + /*! @abstract Quaternion representing rotation about `axis` by `angle` + * radians. */ + quatf(float angle, float3 axis) : ::simd_quatf(::simd_quaternion(angle, axis)) { } + + /*! @abstract Quaternion that rotates `from` into `to`. */ + quatf(float3 from, float3 to) : ::simd_quatf(::simd_quaternion(from, to)) { } + + /*! @abstract Constructs a quaternion from a rotation matrix. */ + quatf(::simd_float3x3 matrix) : ::simd_quatf(::simd_quaternion(matrix)) { } + + /*! @abstract Constructs a quaternion from a rotation matrix. */ + quatf(::simd_float4x4 matrix) : ::simd_quatf(::simd_quaternion(matrix)) { } + + /*! @abstract The real (scalar) part of the quaternion. */ + float real(void) const { return ::simd_real(*this); } + + /*! @abstract The imaginary (vector) part of the quaternion. */ + float3 imag(void) const { return ::simd_imag(*this); } + + /*! @abstract The angle the quaternion rotates by. */ + float angle(void) const { return ::simd_angle(*this); } + + /*! @abstract The axis the quaternion rotates about. */ + float3 axis(void) const { return ::simd_axis(*this); } + + /*! @abstract The length of the quaternion. */ + float length(void) const { return ::simd_length(*this); } + + /*! @abstract Act on the vector `v` by rotation. */ + float3 operator()(const ::simd_float3 v) const { return ::simd_act(*this, v); } + }; + + static SIMD_CPPFUNC quatf operator+(const ::simd_quatf p, const ::simd_quatf q) { return ::simd_add(p, q); } + static SIMD_CPPFUNC quatf operator-(const ::simd_quatf p, const ::simd_quatf q) { return ::simd_sub(p, q); } + static SIMD_CPPFUNC quatf operator-(const ::simd_quatf p) { return ::simd_negate(p); } + static SIMD_CPPFUNC quatf operator*(const float r, const ::simd_quatf p) { return ::simd_mul(r, p); } + static SIMD_CPPFUNC quatf operator*(const ::simd_quatf p, const float r) { return ::simd_mul(p, r); } + static SIMD_CPPFUNC quatf operator*(const ::simd_quatf p, const ::simd_quatf q) { return ::simd_mul(p, q); } + static SIMD_CPPFUNC quatf operator/(const ::simd_quatf p, const ::simd_quatf q) { return ::simd_mul(p, ::simd_inverse(q)); } + static SIMD_CPPFUNC quatf operator+=(quatf &p, const ::simd_quatf q) { return p = p+q; } + static SIMD_CPPFUNC quatf operator-=(quatf &p, const ::simd_quatf q) { return p = p-q; } + static SIMD_CPPFUNC quatf operator*=(quatf &p, const float r) { return p = p*r; } + static SIMD_CPPFUNC quatf operator*=(quatf &p, const ::simd_quatf q) { return p = p*q; } + static SIMD_CPPFUNC quatf operator/=(quatf &p, const ::simd_quatf q) { return p = p/q; } + + /*! @abstract The conjugate of the quaternion `q`. */ + static SIMD_CPPFUNC quatf conjugate(const ::simd_quatf p) { return ::simd_conjugate(p); } + + /*! @abstract The (multiplicative) inverse of the quaternion `q`. */ + static SIMD_CPPFUNC quatf inverse(const ::simd_quatf p) { return ::simd_inverse(p); } + + /*! @abstract The dot product of the quaternions `p` and `q` interpreted as + * four-dimensional vectors. */ + static SIMD_CPPFUNC float dot(const ::simd_quatf p, const ::simd_quatf q) { return ::simd_dot(p, q); } + + /*! @abstract The unit quaternion obtained by normalizing `q`. */ + static SIMD_CPPFUNC quatf normalize(const ::simd_quatf p) { return ::simd_normalize(p); } + + /*! @abstract logarithm of the quaternion `q`. */ + static SIMD_CPPFUNC quatf log(const ::simd_quatf q) { return ::__tg_log(q); } + + /*! @abstract exponential map of quaterion `q`. */ + static SIMD_CPPFUNC quatf exp(const ::simd_quatf q) { return ::__tg_exp(q); } + + /*! @abstract Spherical linear interpolation along the shortest arc between + * quaternions `q0` and `q1`. */ + static SIMD_CPPFUNC quatf slerp(const ::simd_quatf p0, const ::simd_quatf p1, float t) { return ::simd_slerp(p0, p1, t); } + + /*! @abstract Spherical linear interpolation along the longest arc between + * quaternions `q0` and `q1`. */ + static SIMD_CPPFUNC quatf slerp_longest(const ::simd_quatf p0, const ::simd_quatf p1, float t) { return ::simd_slerp_longest(p0, p1, t); } + + /*! @abstract Interpolate between quaternions along a spherical cubic spline. + * + * @discussion The function interpolates between q1 and q2. q0 is the left + * endpoint of the previous interval, and q3 is the right endpoint of the next + * interval. Use this function to smoothly interpolate between a sequence of + * rotations. */ + static SIMD_CPPFUNC quatf spline(const ::simd_quatf p0, const ::simd_quatf p1, const ::simd_quatf p2, const ::simd_quatf p3, float t) { return ::simd_spline(p0, p1, p2, p3, t); } + + /*! @abstract Spherical cubic Bezier interpolation between quaternions. + * + * @discussion The function treats q0 ... q3 as control points and uses slerp + * in place of lerp in the De Castlejeau algorithm. The endpoints of + * interpolation are thus q0 and q3, and the curve will not generally pass + * through q1 or q2. Note that the convex hull property of "standard" Bezier + * curve does not hold on the sphere. */ + static SIMD_CPPFUNC quatf bezier(const ::simd_quatf p0, const ::simd_quatf p1, const ::simd_quatf p2, const ::simd_quatf p3, float t) { return ::simd_bezier(p0, p1, p2, p3, t); } +} + +extern "C" { +#endif /* __cplusplus */ + +/* MARK: - float implementations */ + +#include +#include + +/* tg_promote is implementation gobbledygook that enables the compile-time + * dispatching in tgmath.h to work its magic. */ +static simd_quatf __attribute__((__overloadable__)) __tg_promote(simd_quatf); + +/*! @abstract Constructs a quaternion from imaginary and real parts. + * @discussion This function is hidden behind an underscore to avoid confusion + * with the angle-axis constructor. */ +static inline SIMD_CFUNC simd_quatf _simd_quaternion(simd_float3 imag, float real) { + return simd_quaternion(simd_make_float4(imag, real)); +} + +static inline SIMD_CFUNC simd_quatf simd_quaternion(float angle, simd_float3 axis) { + return _simd_quaternion(sin(angle/2) * axis, cos(angle/2)); +} + +static inline SIMD_CFUNC float simd_angle(simd_quatf q) { + return 2*atan2(simd_length(q.vector.xyz), q.vector.w); +} + +static inline SIMD_CFUNC simd_float3 simd_axis(simd_quatf q) { + return simd_normalize(q.vector.xyz); +} + +static inline SIMD_CFUNC simd_quatf simd_add(simd_quatf p, simd_quatf q) { + return simd_quaternion(p.vector + q.vector); +} + +static inline SIMD_CFUNC simd_quatf simd_sub(simd_quatf p, simd_quatf q) { + return simd_quaternion(p.vector - q.vector); +} + +static inline SIMD_CFUNC simd_quatf simd_mul(simd_quatf p, simd_quatf q) { + #pragma STDC FP_CONTRACT ON + return simd_quaternion((p.vector.x * __builtin_shufflevector(q.vector, -q.vector, 3,6,1,4) + + p.vector.y * __builtin_shufflevector(q.vector, -q.vector, 2,3,4,5)) + + (p.vector.z * __builtin_shufflevector(q.vector, -q.vector, 5,0,3,6) + + p.vector.w * q.vector)); +} + +static inline SIMD_CFUNC simd_quatf simd_mul(simd_quatf q, float a) { + return simd_quaternion(a * q.vector); +} + +static inline SIMD_CFUNC simd_quatf simd_mul(float a, simd_quatf q) { + return simd_mul(q,a); +} + +static inline SIMD_CFUNC simd_quatf simd_conjugate(simd_quatf q) { + return simd_quaternion(q.vector * (simd_float4){-1,-1,-1, 1}); +} + +static inline SIMD_CFUNC simd_quatf simd_inverse(simd_quatf q) { + return simd_quaternion(simd_conjugate(q).vector * simd_recip(simd_length_squared(q.vector))); +} + +static inline SIMD_CFUNC simd_quatf simd_negate(simd_quatf q) { + return simd_quaternion(-q.vector); +} + +static inline SIMD_CFUNC float simd_dot(simd_quatf p, simd_quatf q) { + return simd_dot(p.vector, q.vector); +} + +static inline SIMD_CFUNC float simd_length(simd_quatf q) { + return simd_length(q.vector); +} + +static inline SIMD_CFUNC simd_quatf simd_normalize(simd_quatf q) { + float length_squared = simd_length_squared(q.vector); + if (length_squared == 0) { + return simd_quaternion((simd_float4){0,0,0,1}); + } + return simd_quaternion(q.vector * simd_rsqrt(length_squared)); +} + +#if defined __arm__ || defined __arm64__ +/*! @abstract Multiplies the vector `v` by the quaternion `q`. + * + * @discussion This IS NOT the action of `q` on `v` (i.e. this is not rotation + * by `q`. That operation is provided by `simd_act(q, v)`. This function is an + * implementation detail and you should not call it directly. It may be + * removed or modified in future versions of the simd module. */ +static inline SIMD_CFUNC simd_quatf _simd_mul_vq(simd_float3 v, simd_quatf q) { + #pragma STDC FP_CONTRACT ON + return simd_quaternion(v.x * __builtin_shufflevector(q.vector, -q.vector, 3,6,1,4) + + v.y * __builtin_shufflevector(q.vector, -q.vector, 2,3,4,5) + + v.z * __builtin_shufflevector(q.vector, -q.vector, 5,0,3,6)); +} +#endif + +static inline SIMD_CFUNC simd_float3 simd_act(simd_quatf q, simd_float3 v) { +#if defined __arm__ || defined __arm64__ + return simd_mul(q, _simd_mul_vq(v, simd_conjugate(q))).vector.xyz; +#else + #pragma STDC FP_CONTRACT ON + simd_float3 t = 2*simd_cross(simd_imag(q),v); + return v + simd_real(q)*t + simd_cross(simd_imag(q), t); +#endif +} + +static SIMD_NOINLINE simd_quatf __tg_log(simd_quatf q) { + float real = __tg_log(simd_length_squared(q.vector))/2; + if (simd_equal(simd_imag(q), 0)) return _simd_quaternion(0, real); + simd_float3 imag = __tg_acos(simd_real(q)/simd_length(q)) * simd_normalize(simd_imag(q)); + return _simd_quaternion(imag, real); +} + +static SIMD_NOINLINE simd_quatf __tg_exp(simd_quatf q) { + // angle is actually *twice* the angle of the rotation corresponding to + // the resulting quaternion, which is why we don't simply use the (angle, + // axis) constructor to generate `unit`. + float angle = simd_length(simd_imag(q)); + if (angle == 0) return _simd_quaternion(0, exp(simd_real(q))); + simd_float3 axis = simd_normalize(simd_imag(q)); + simd_quatf unit = _simd_quaternion(sin(angle)*axis, cosf(angle)); + return simd_mul(exp(simd_real(q)), unit); +} + +/*! @abstract Implementation detail of the `simd_quaternion(from, to)` + * initializer. + * + * @discussion Computes the quaternion rotation `from` to `to` if they are + * separated by less than 90 degrees. Not numerically stable for larger + * angles. This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static inline SIMD_CFUNC simd_quatf _simd_quaternion_reduced(simd_float3 from, simd_float3 to) { + simd_float3 half = simd_normalize(from + to); + return _simd_quaternion(simd_cross(from, half), simd_dot(from, half)); +} + +static SIMD_NOINLINE simd_quatf simd_quaternion(simd_float3 from, simd_float3 to) { + + // If the angle between from and to is not too big, we can compute the + // rotation accurately using a simple implementation. + if (simd_dot(from, to) >= 0) { + return _simd_quaternion_reduced(from, to); + } + + // Because from and to are more than 90 degrees apart, we compute the + // rotation in two stages (from -> half), (half -> to) to preserve numerical + // accuracy. + simd_float3 half = from + to; + + if (simd_length_squared(half) == 0) { + // half is nearly zero, so from and to point in nearly opposite directions + // and the rotation is numerically underspecified. Pick an axis orthogonal + // to the vectors, and use an angle of pi radians. + simd_float3 abs_from = simd_abs(from); + if (abs_from.x <= abs_from.y && abs_from.x <= abs_from.z) + return _simd_quaternion(simd_normalize(simd_cross(from, (simd_float3){1,0,0})), 0.f); + else if (abs_from.y <= abs_from.z) + return _simd_quaternion(simd_normalize(simd_cross(from, (simd_float3){0,1,0})), 0.f); + else + return _simd_quaternion(simd_normalize(simd_cross(from, (simd_float3){0,0,1})), 0.f); + } + + // Compute the two-step rotation. */ + half = simd_normalize(half); + return simd_mul(_simd_quaternion_reduced(from, half), + _simd_quaternion_reduced(half, to)); +} + +static SIMD_NOINLINE simd_quatf simd_quaternion(simd_float3x3 matrix) { + const simd_float3 *mat = matrix.columns; + float trace = mat[0][0] + mat[1][1] + mat[2][2]; + if (trace >= 0.0) { + float r = 2*sqrt(1 + trace); + float rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[1][2] - mat[2][1]), + rinv*(mat[2][0] - mat[0][2]), + rinv*(mat[0][1] - mat[1][0]), + r/4); + } else if (mat[0][0] >= mat[1][1] && mat[0][0] >= mat[2][2]) { + float r = 2*sqrt(1 - mat[1][1] - mat[2][2] + mat[0][0]); + float rinv = simd_recip(r); + return simd_quaternion(r/4, + rinv*(mat[0][1] + mat[1][0]), + rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] - mat[2][1])); + } else if (mat[1][1] >= mat[2][2]) { + float r = 2*sqrt(1 - mat[0][0] - mat[2][2] + mat[1][1]); + float rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][1] + mat[1][0]), + r/4, + rinv*(mat[1][2] + mat[2][1]), + rinv*(mat[2][0] - mat[0][2])); + } else { + float r = 2*sqrt(1 - mat[0][0] - mat[1][1] + mat[2][2]); + float rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] + mat[2][1]), + r/4, + rinv*(mat[0][1] - mat[1][0])); + } +} + +static SIMD_NOINLINE simd_quatf simd_quaternion(simd_float4x4 matrix) { + const simd_float4 *mat = matrix.columns; + float trace = mat[0][0] + mat[1][1] + mat[2][2]; + if (trace >= 0.0) { + float r = 2*sqrt(1 + trace); + float rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[1][2] - mat[2][1]), + rinv*(mat[2][0] - mat[0][2]), + rinv*(mat[0][1] - mat[1][0]), + r/4); + } else if (mat[0][0] >= mat[1][1] && mat[0][0] >= mat[2][2]) { + float r = 2*sqrt(1 - mat[1][1] - mat[2][2] + mat[0][0]); + float rinv = simd_recip(r); + return simd_quaternion(r/4, + rinv*(mat[0][1] + mat[1][0]), + rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] - mat[2][1])); + } else if (mat[1][1] >= mat[2][2]) { + float r = 2*sqrt(1 - mat[0][0] - mat[2][2] + mat[1][1]); + float rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][1] + mat[1][0]), + r/4, + rinv*(mat[1][2] + mat[2][1]), + rinv*(mat[2][0] - mat[0][2])); + } else { + float r = 2*sqrt(1 - mat[0][0] - mat[1][1] + mat[2][2]); + float rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] + mat[2][1]), + r/4, + rinv*(mat[0][1] - mat[1][0])); + } +} + +/*! @abstract The angle between p and q interpreted as 4-dimensional vectors. + * + * @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_NOINLINE float _simd_angle(simd_quatf p, simd_quatf q) { + return 2*atan2(simd_length(p.vector - q.vector), simd_length(p.vector + q.vector)); +} + +/*! @abstract sin(x)/x. + * + * @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_CFUNC float _simd_sinc(float x) { + if (x == 0) return 1; + return sin(x)/x; +} + +/*! @abstract Spherical lerp between q0 and q1. + * + * @discussion This function may interpolate along either the longer or + * shorter path between q0 and q1; it is used as an implementation detail + * in `simd_slerp` and `simd_slerp_longest`; you should use those functions + * instead of calling this directly. */ +static SIMD_NOINLINE simd_quatf _simd_slerp_internal(simd_quatf q0, simd_quatf q1, float t) { + float s = 1 - t; + float a = _simd_angle(q0, q1); + float r = simd_recip(_simd_sinc(a)); + return simd_normalize(simd_quaternion(_simd_sinc(s*a)*r*s*q0.vector + _simd_sinc(t*a)*r*t*q1.vector)); +} + +static SIMD_NOINLINE simd_quatf simd_slerp(simd_quatf q0, simd_quatf q1, float t) { + if (simd_dot(q0, q1) >= 0) + return _simd_slerp_internal(q0, q1, t); + return _simd_slerp_internal(q0, simd_negate(q1), t); +} + +static SIMD_NOINLINE simd_quatf simd_slerp_longest(simd_quatf q0, simd_quatf q1, float t) { + if (simd_dot(q0, q1) >= 0) + return _simd_slerp_internal(q0, simd_negate(q1), t); + return _simd_slerp_internal(q0, q1, t); +} + +/*! @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_NOINLINE simd_quatf _simd_intermediate(simd_quatf q0, simd_quatf q1, simd_quatf q2) { + simd_quatf p0 = __tg_log(simd_mul(q0, simd_inverse(q1))); + simd_quatf p2 = __tg_log(simd_mul(q2, simd_inverse(q1))); + return simd_normalize(simd_mul(q1, __tg_exp(simd_mul(-0.25, simd_add(p0,p2))))); +} + +/*! @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_NOINLINE simd_quatf _simd_squad(simd_quatf q0, simd_quatf qa, simd_quatf qb, simd_quatf q1, float t) { + simd_quatf r0 = _simd_slerp_internal(q0, q1, t); + simd_quatf r1 = _simd_slerp_internal(qa, qb, t); + return _simd_slerp_internal(r0, r1, 2*t*(1 - t)); +} + +static SIMD_NOINLINE simd_quatf simd_spline(simd_quatf q0, simd_quatf q1, simd_quatf q2, simd_quatf q3, float t) { + simd_quatf qa = _simd_intermediate(q0, q1, q2); + simd_quatf qb = _simd_intermediate(q1, q2, q3); + return _simd_squad(q1, qa, qb, q2, t); +} + +static SIMD_NOINLINE simd_quatf simd_bezier(simd_quatf q0, simd_quatf q1, simd_quatf q2, simd_quatf q3, float t) { + simd_quatf q01 = _simd_slerp_internal(q0, q1, t); + simd_quatf q12 = _simd_slerp_internal(q1, q2, t); + simd_quatf q23 = _simd_slerp_internal(q2, q3, t); + simd_quatf q012 = _simd_slerp_internal(q01, q12, t); + simd_quatf q123 = _simd_slerp_internal(q12, q23, t); + return _simd_slerp_internal(q012, q123, t); +} + +/* MARK: - C and Objective-C double interfaces */ + +/*! @abstract Constructs a quaternion from four scalar values. + * + * @param ix The first component of the imaginary (vector) part. + * @param iy The second component of the imaginary (vector) part. + * @param iz The third component of the imaginary (vector) part. + * + * @param r The real (scalar) part. */ +static inline SIMD_CFUNC simd_quatd simd_quaternion(double ix, double iy, double iz, double r) { + return (simd_quatd){ { ix, iy, iz, r } }; +} + +/*! @abstract Constructs a quaternion from an array of four scalars. + * + * @discussion Note that the imaginary part of the quaternion comes from + * array elements 0, 1, and 2, and the real part comes from element 3. */ +static inline SIMD_NONCONST simd_quatd simd_quaternion(const double xyzr[4]) { + return (simd_quatd){ *(const simd_packed_double4 *)xyzr }; +} + +/*! @abstract Constructs a quaternion from a four-element vector. + * + * @discussion Note that the imaginary (vector) part of the quaternion comes + * from lanes 0, 1, and 2 of the vector, and the real (scalar) part comes from + * lane 3. */ +static inline SIMD_CFUNC simd_quatd simd_quaternion(simd_double4 xyzr) { + return (simd_quatd){ xyzr }; +} + +/*! @abstract Constructs a quaternion that rotates by `angle` radians about + * `axis`. */ +static inline SIMD_CFUNC simd_quatd simd_quaternion(double angle, simd_double3 axis); + +/*! @abstract Construct a quaternion that rotates from one vector to another. + * + * @param from A normalized three-element vector. + * @param to A normalized three-element vector. + * + * @discussion The rotation axis is `simd_cross(from, to)`. If `from` and + * `to` point in opposite directions (to within machine precision), an + * arbitrary rotation axis is chosen, and the angle is pi radians. */ +static SIMD_NOINLINE simd_quatd simd_quaternion(simd_double3 from, simd_double3 to); + +/*! @abstract Construct a quaternion from a 3x3 rotation `matrix`. + * + * @discussion If `matrix` is not orthogonal with determinant 1, the result + * is undefined. */ +static SIMD_NOINLINE simd_quatd simd_quaternion(simd_double3x3 matrix); + +/*! @abstract Construct a quaternion from a 4x4 rotation `matrix`. + * + * @discussion The last row and column of the matrix are ignored. This + * function is equivalent to calling simd_quaternion with the upper-left 3x3 + * submatrix . */ +static SIMD_NOINLINE simd_quatd simd_quaternion(simd_double4x4 matrix); + +/*! @abstract The real (scalar) part of the quaternion `q`. */ +static inline SIMD_CFUNC double simd_real(simd_quatd q) { + return q.vector.w; +} + +/*! @abstract The imaginary (vector) part of the quaternion `q`. */ +static inline SIMD_CFUNC simd_double3 simd_imag(simd_quatd q) { + return q.vector.xyz; +} + +/*! @abstract The angle (in radians) of rotation represented by `q`. */ +static inline SIMD_CFUNC double simd_angle(simd_quatd q); + +/*! @abstract The normalized axis (a 3-element vector) around which the + * action of the quaternion `q` rotates. */ +static inline SIMD_CFUNC simd_double3 simd_axis(simd_quatd q); + +/*! @abstract The sum of the quaternions `p` and `q`. */ +static inline SIMD_CFUNC simd_quatd simd_add(simd_quatd p, simd_quatd q); + +/*! @abstract The difference of the quaternions `p` and `q`. */ +static inline SIMD_CFUNC simd_quatd simd_sub(simd_quatd p, simd_quatd q); + +/*! @abstract The product of the quaternions `p` and `q`. */ +static inline SIMD_CFUNC simd_quatd simd_mul(simd_quatd p, simd_quatd q); + +/*! @abstract The quaternion `q` scaled by the real value `a`. */ +static inline SIMD_CFUNC simd_quatd simd_mul(simd_quatd q, double a); + +/*! @abstract The quaternion `q` scaled by the real value `a`. */ +static inline SIMD_CFUNC simd_quatd simd_mul(double a, simd_quatd q); + +/*! @abstract The conjugate of the quaternion `q`. */ +static inline SIMD_CFUNC simd_quatd simd_conjugate(simd_quatd q); + +/*! @abstract The (multiplicative) inverse of the quaternion `q`. */ +static inline SIMD_CFUNC simd_quatd simd_inverse(simd_quatd q); + +/*! @abstract The negation (additive inverse) of the quaternion `q`. */ +static inline SIMD_CFUNC simd_quatd simd_negate(simd_quatd q); + +/*! @abstract The dot product of the quaternions `p` and `q` interpreted as + * four-dimensional vectors. */ +static inline SIMD_CFUNC double simd_dot(simd_quatd p, simd_quatd q); + +/*! @abstract The length of the quaternion `q`. */ +static inline SIMD_CFUNC double simd_length(simd_quatd q); + +/*! @abstract The unit quaternion obtained by normalizing `q`. */ +static inline SIMD_CFUNC simd_quatd simd_normalize(simd_quatd q); + +/*! @abstract Rotates the vector `v` by the quaternion `q`. */ +static inline SIMD_CFUNC simd_double3 simd_act(simd_quatd q, simd_double3 v); + +/*! @abstract Logarithm of the quaternion `q`. + * @discussion Do not call this function directly; use `log(q)` instead. + * + * We can write a quaternion `q` in the form: `r(cos(t) + sin(t)v)` where + * `r` is the length of `q`, `t` is an angle, and `v` is a unit 3-vector. + * The logarithm of `q` is `log(r) + tv`, just like the logarithm of the + * complex number `r*(cos(t) + i sin(t))` is `log(r) + it`. + * + * Note that this function is not robust against poorly-scaled non-unit + * quaternions, because it is primarily used for spline interpolation of + * unit quaternions. If you need to compute a robust logarithm of general + * quaternions, you can use the following approach: + * + * scale = simd_reduce_max(simd_abs(q.vector)); + * logq = log(simd_recip(scale)*q); + * logq.real += log(scale); + * return logq; */ +static SIMD_NOINLINE simd_quatd __tg_log(simd_quatd q); + +/*! @abstract Inverse of `log( )`; the exponential map on quaternions. + * @discussion Do not call this function directly; use `exp(q)` instead. */ +static SIMD_NOINLINE simd_quatd __tg_exp(simd_quatd q); + +/*! @abstract Spherical linear interpolation along the shortest arc between + * quaternions `q0` and `q1`. */ +static SIMD_NOINLINE simd_quatd simd_slerp(simd_quatd q0, simd_quatd q1, double t); + +/*! @abstract Spherical linear interpolation along the longest arc between + * quaternions `q0` and `q1`. */ +static SIMD_NOINLINE simd_quatd simd_slerp_longest(simd_quatd q0, simd_quatd q1, double t); + +/*! @abstract Interpolate between quaternions along a spherical cubic spline. + * + * @discussion The function interpolates between q1 and q2. q0 is the left + * endpoint of the previous interval, and q3 is the right endpoint of the next + * interval. Use this function to smoothly interpolate between a sequence of + * rotations. */ +static SIMD_NOINLINE simd_quatd simd_spline(simd_quatd q0, simd_quatd q1, simd_quatd q2, simd_quatd q3, double t); + +/*! @abstract Spherical cubic Bezier interpolation between quaternions. + * + * @discussion The function treats q0 ... q3 as control points and uses slerp + * in place of lerp in the De Castlejeau algorithm. The endpoints of + * interpolation are thus q0 and q3, and the curve will not generally pass + * through q1 or q2. Note that the convex hull property of "standard" Bezier + * curve does not hold on the sphere. */ +static SIMD_NOINLINE simd_quatd simd_bezier(simd_quatd q0, simd_quatd q1, simd_quatd q2, simd_quatd q3, double t); + +#ifdef __cplusplus +} /* extern "C" */ +/* MARK: - C++ double interfaces */ + +namespace simd { + struct quatd : ::simd_quatd { + /*! @abstract The identity quaternion. */ + quatd( ) : ::simd_quatd(::simd_quaternion((double4){0,0,0,1})) { } + + /*! @abstract Constructs a C++ quaternion from a C quaternion. */ + quatd(::simd_quatd q) : ::simd_quatd(q) { } + + /*! @abstract Constructs a quaternion from components. */ + quatd(double ix, double iy, double iz, double r) : ::simd_quatd(::simd_quaternion(ix, iy, iz, r)) { } + + /*! @abstract Constructs a quaternion from an array of scalars. */ + quatd(const double xyzr[4]) : ::simd_quatd(::simd_quaternion(xyzr)) { } + + /*! @abstract Constructs a quaternion from a vector. */ + quatd(double4 xyzr) : ::simd_quatd(::simd_quaternion(xyzr)) { } + + /*! @abstract Quaternion representing rotation about `axis` by `angle` + * radians. */ + quatd(double angle, double3 axis) : ::simd_quatd(::simd_quaternion(angle, axis)) { } + + /*! @abstract Quaternion that rotates `from` into `to`. */ + quatd(double3 from, double3 to) : ::simd_quatd(::simd_quaternion(from, to)) { } + + /*! @abstract Constructs a quaternion from a rotation matrix. */ + quatd(::simd_double3x3 matrix) : ::simd_quatd(::simd_quaternion(matrix)) { } + + /*! @abstract Constructs a quaternion from a rotation matrix. */ + quatd(::simd_double4x4 matrix) : ::simd_quatd(::simd_quaternion(matrix)) { } + + /*! @abstract The real (scalar) part of the quaternion. */ + double real(void) const { return ::simd_real(*this); } + + /*! @abstract The imaginary (vector) part of the quaternion. */ + double3 imag(void) const { return ::simd_imag(*this); } + + /*! @abstract The angle the quaternion rotates by. */ + double angle(void) const { return ::simd_angle(*this); } + + /*! @abstract The axis the quaternion rotates about. */ + double3 axis(void) const { return ::simd_axis(*this); } + + /*! @abstract The length of the quaternion. */ + double length(void) const { return ::simd_length(*this); } + + /*! @abstract Act on the vector `v` by rotation. */ + double3 operator()(const ::simd_double3 v) const { return ::simd_act(*this, v); } + }; + + static SIMD_CPPFUNC quatd operator+(const ::simd_quatd p, const ::simd_quatd q) { return ::simd_add(p, q); } + static SIMD_CPPFUNC quatd operator-(const ::simd_quatd p, const ::simd_quatd q) { return ::simd_sub(p, q); } + static SIMD_CPPFUNC quatd operator-(const ::simd_quatd p) { return ::simd_negate(p); } + static SIMD_CPPFUNC quatd operator*(const double r, const ::simd_quatd p) { return ::simd_mul(r, p); } + static SIMD_CPPFUNC quatd operator*(const ::simd_quatd p, const double r) { return ::simd_mul(p, r); } + static SIMD_CPPFUNC quatd operator*(const ::simd_quatd p, const ::simd_quatd q) { return ::simd_mul(p, q); } + static SIMD_CPPFUNC quatd operator/(const ::simd_quatd p, const ::simd_quatd q) { return ::simd_mul(p, ::simd_inverse(q)); } + static SIMD_CPPFUNC quatd operator+=(quatd &p, const ::simd_quatd q) { return p = p+q; } + static SIMD_CPPFUNC quatd operator-=(quatd &p, const ::simd_quatd q) { return p = p-q; } + static SIMD_CPPFUNC quatd operator*=(quatd &p, const double r) { return p = p*r; } + static SIMD_CPPFUNC quatd operator*=(quatd &p, const ::simd_quatd q) { return p = p*q; } + static SIMD_CPPFUNC quatd operator/=(quatd &p, const ::simd_quatd q) { return p = p/q; } + + /*! @abstract The conjugate of the quaternion `q`. */ + static SIMD_CPPFUNC quatd conjugate(const ::simd_quatd p) { return ::simd_conjugate(p); } + + /*! @abstract The (multiplicative) inverse of the quaternion `q`. */ + static SIMD_CPPFUNC quatd inverse(const ::simd_quatd p) { return ::simd_inverse(p); } + + /*! @abstract The dot product of the quaternions `p` and `q` interpreted as + * four-dimensional vectors. */ + static SIMD_CPPFUNC double dot(const ::simd_quatd p, const ::simd_quatd q) { return ::simd_dot(p, q); } + + /*! @abstract The unit quaternion obtained by normalizing `q`. */ + static SIMD_CPPFUNC quatd normalize(const ::simd_quatd p) { return ::simd_normalize(p); } + + /*! @abstract logarithm of the quaternion `q`. */ + static SIMD_CPPFUNC quatd log(const ::simd_quatd q) { return ::__tg_log(q); } + + /*! @abstract exponential map of quaterion `q`. */ + static SIMD_CPPFUNC quatd exp(const ::simd_quatd q) { return ::__tg_exp(q); } + + /*! @abstract Spherical linear interpolation along the shortest arc between + * quaternions `q0` and `q1`. */ + static SIMD_CPPFUNC quatd slerp(const ::simd_quatd p0, const ::simd_quatd p1, double t) { return ::simd_slerp(p0, p1, t); } + + /*! @abstract Spherical linear interpolation along the longest arc between + * quaternions `q0` and `q1`. */ + static SIMD_CPPFUNC quatd slerp_longest(const ::simd_quatd p0, const ::simd_quatd p1, double t) { return ::simd_slerp_longest(p0, p1, t); } + + /*! @abstract Interpolate between quaternions along a spherical cubic spline. + * + * @discussion The function interpolates between q1 and q2. q0 is the left + * endpoint of the previous interval, and q3 is the right endpoint of the next + * interval. Use this function to smoothly interpolate between a sequence of + * rotations. */ + static SIMD_CPPFUNC quatd spline(const ::simd_quatd p0, const ::simd_quatd p1, const ::simd_quatd p2, const ::simd_quatd p3, double t) { return ::simd_spline(p0, p1, p2, p3, t); } + + /*! @abstract Spherical cubic Bezier interpolation between quaternions. + * + * @discussion The function treats q0 ... q3 as control points and uses slerp + * in place of lerp in the De Castlejeau algorithm. The endpoints of + * interpolation are thus q0 and q3, and the curve will not generally pass + * through q1 or q2. Note that the convex hull property of "standard" Bezier + * curve does not hold on the sphere. */ + static SIMD_CPPFUNC quatd bezier(const ::simd_quatd p0, const ::simd_quatd p1, const ::simd_quatd p2, const ::simd_quatd p3, double t) { return ::simd_bezier(p0, p1, p2, p3, t); } +} + +extern "C" { +#endif /* __cplusplus */ + +/* MARK: - double implementations */ + +#include +#include + +/* tg_promote is implementation gobbledygook that enables the compile-time + * dispatching in tgmath.h to work its magic. */ +static simd_quatd __attribute__((__overloadable__)) __tg_promote(simd_quatd); + +/*! @abstract Constructs a quaternion from imaginary and real parts. + * @discussion This function is hidden behind an underscore to avoid confusion + * with the angle-axis constructor. */ +static inline SIMD_CFUNC simd_quatd _simd_quaternion(simd_double3 imag, double real) { + return simd_quaternion(simd_make_double4(imag, real)); +} + +static inline SIMD_CFUNC simd_quatd simd_quaternion(double angle, simd_double3 axis) { + return _simd_quaternion(sin(angle/2) * axis, cos(angle/2)); +} + +static inline SIMD_CFUNC double simd_angle(simd_quatd q) { + return 2*atan2(simd_length(q.vector.xyz), q.vector.w); +} + +static inline SIMD_CFUNC simd_double3 simd_axis(simd_quatd q) { + return simd_normalize(q.vector.xyz); +} + +static inline SIMD_CFUNC simd_quatd simd_add(simd_quatd p, simd_quatd q) { + return simd_quaternion(p.vector + q.vector); +} + +static inline SIMD_CFUNC simd_quatd simd_sub(simd_quatd p, simd_quatd q) { + return simd_quaternion(p.vector - q.vector); +} + +static inline SIMD_CFUNC simd_quatd simd_mul(simd_quatd p, simd_quatd q) { + #pragma STDC FP_CONTRACT ON + return simd_quaternion((p.vector.x * __builtin_shufflevector(q.vector, -q.vector, 3,6,1,4) + + p.vector.y * __builtin_shufflevector(q.vector, -q.vector, 2,3,4,5)) + + (p.vector.z * __builtin_shufflevector(q.vector, -q.vector, 5,0,3,6) + + p.vector.w * q.vector)); +} + +static inline SIMD_CFUNC simd_quatd simd_mul(simd_quatd q, double a) { + return simd_quaternion(a * q.vector); +} + +static inline SIMD_CFUNC simd_quatd simd_mul(double a, simd_quatd q) { + return simd_mul(q,a); +} + +static inline SIMD_CFUNC simd_quatd simd_conjugate(simd_quatd q) { + return simd_quaternion(q.vector * (simd_double4){-1,-1,-1, 1}); +} + +static inline SIMD_CFUNC simd_quatd simd_inverse(simd_quatd q) { + return simd_quaternion(simd_conjugate(q).vector * simd_recip(simd_length_squared(q.vector))); +} + +static inline SIMD_CFUNC simd_quatd simd_negate(simd_quatd q) { + return simd_quaternion(-q.vector); +} + +static inline SIMD_CFUNC double simd_dot(simd_quatd p, simd_quatd q) { + return simd_dot(p.vector, q.vector); +} + +static inline SIMD_CFUNC double simd_length(simd_quatd q) { + return simd_length(q.vector); +} + +static inline SIMD_CFUNC simd_quatd simd_normalize(simd_quatd q) { + double length_squared = simd_length_squared(q.vector); + if (length_squared == 0) { + return simd_quaternion((simd_double4){0,0,0,1}); + } + return simd_quaternion(q.vector * simd_rsqrt(length_squared)); +} + +#if defined __arm__ || defined __arm64__ +/*! @abstract Multiplies the vector `v` by the quaternion `q`. + * + * @discussion This IS NOT the action of `q` on `v` (i.e. this is not rotation + * by `q`. That operation is provided by `simd_act(q, v)`. This function is an + * implementation detail and you should not call it directly. It may be + * removed or modified in future versions of the simd module. */ +static inline SIMD_CFUNC simd_quatd _simd_mul_vq(simd_double3 v, simd_quatd q) { + #pragma STDC FP_CONTRACT ON + return simd_quaternion(v.x * __builtin_shufflevector(q.vector, -q.vector, 3,6,1,4) + + v.y * __builtin_shufflevector(q.vector, -q.vector, 2,3,4,5) + + v.z * __builtin_shufflevector(q.vector, -q.vector, 5,0,3,6)); +} +#endif + +static inline SIMD_CFUNC simd_double3 simd_act(simd_quatd q, simd_double3 v) { +#if defined __arm__ || defined __arm64__ + return simd_mul(q, _simd_mul_vq(v, simd_conjugate(q))).vector.xyz; +#else + #pragma STDC FP_CONTRACT ON + simd_double3 t = 2*simd_cross(simd_imag(q),v); + return v + simd_real(q)*t + simd_cross(simd_imag(q), t); +#endif +} + +static SIMD_NOINLINE simd_quatd __tg_log(simd_quatd q) { + double real = __tg_log(simd_length_squared(q.vector))/2; + if (simd_equal(simd_imag(q), 0)) return _simd_quaternion(0, real); + simd_double3 imag = __tg_acos(simd_real(q)/simd_length(q)) * simd_normalize(simd_imag(q)); + return _simd_quaternion(imag, real); +} + +static SIMD_NOINLINE simd_quatd __tg_exp(simd_quatd q) { + // angle is actually *twice* the angle of the rotation corresponding to + // the resulting quaternion, which is why we don't simply use the (angle, + // axis) constructor to generate `unit`. + double angle = simd_length(simd_imag(q)); + if (angle == 0) return _simd_quaternion(0, exp(simd_real(q))); + simd_double3 axis = simd_normalize(simd_imag(q)); + simd_quatd unit = _simd_quaternion(sin(angle)*axis, cosf(angle)); + return simd_mul(exp(simd_real(q)), unit); +} + +/*! @abstract Implementation detail of the `simd_quaternion(from, to)` + * initializer. + * + * @discussion Computes the quaternion rotation `from` to `to` if they are + * separated by less than 90 degrees. Not numerically stable for larger + * angles. This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static inline SIMD_CFUNC simd_quatd _simd_quaternion_reduced(simd_double3 from, simd_double3 to) { + simd_double3 half = simd_normalize(from + to); + return _simd_quaternion(simd_cross(from, half), simd_dot(from, half)); +} + +static SIMD_NOINLINE simd_quatd simd_quaternion(simd_double3 from, simd_double3 to) { + + // If the angle between from and to is not too big, we can compute the + // rotation accurately using a simple implementation. + if (simd_dot(from, to) >= 0) { + return _simd_quaternion_reduced(from, to); + } + + // Because from and to are more than 90 degrees apart, we compute the + // rotation in two stages (from -> half), (half -> to) to preserve numerical + // accuracy. + simd_double3 half = from + to; + + if (simd_length_squared(half) == 0) { + // half is nearly zero, so from and to point in nearly opposite directions + // and the rotation is numerically underspecified. Pick an axis orthogonal + // to the vectors, and use an angle of pi radians. + simd_double3 abs_from = simd_abs(from); + if (abs_from.x <= abs_from.y && abs_from.x <= abs_from.z) + return _simd_quaternion(simd_normalize(simd_cross(from, (simd_double3){1,0,0})), 0.f); + else if (abs_from.y <= abs_from.z) + return _simd_quaternion(simd_normalize(simd_cross(from, (simd_double3){0,1,0})), 0.f); + else + return _simd_quaternion(simd_normalize(simd_cross(from, (simd_double3){0,0,1})), 0.f); + } + + // Compute the two-step rotation. */ + half = simd_normalize(half); + return simd_mul(_simd_quaternion_reduced(from, half), + _simd_quaternion_reduced(half, to)); +} + +static SIMD_NOINLINE simd_quatd simd_quaternion(simd_double3x3 matrix) { + const simd_double3 *mat = matrix.columns; + double trace = mat[0][0] + mat[1][1] + mat[2][2]; + if (trace >= 0.0) { + double r = 2*sqrt(1 + trace); + double rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[1][2] - mat[2][1]), + rinv*(mat[2][0] - mat[0][2]), + rinv*(mat[0][1] - mat[1][0]), + r/4); + } else if (mat[0][0] >= mat[1][1] && mat[0][0] >= mat[2][2]) { + double r = 2*sqrt(1 - mat[1][1] - mat[2][2] + mat[0][0]); + double rinv = simd_recip(r); + return simd_quaternion(r/4, + rinv*(mat[0][1] + mat[1][0]), + rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] - mat[2][1])); + } else if (mat[1][1] >= mat[2][2]) { + double r = 2*sqrt(1 - mat[0][0] - mat[2][2] + mat[1][1]); + double rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][1] + mat[1][0]), + r/4, + rinv*(mat[1][2] + mat[2][1]), + rinv*(mat[2][0] - mat[0][2])); + } else { + double r = 2*sqrt(1 - mat[0][0] - mat[1][1] + mat[2][2]); + double rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] + mat[2][1]), + r/4, + rinv*(mat[0][1] - mat[1][0])); + } +} + +static SIMD_NOINLINE simd_quatd simd_quaternion(simd_double4x4 matrix) { + const simd_double4 *mat = matrix.columns; + double trace = mat[0][0] + mat[1][1] + mat[2][2]; + if (trace >= 0.0) { + double r = 2*sqrt(1 + trace); + double rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[1][2] - mat[2][1]), + rinv*(mat[2][0] - mat[0][2]), + rinv*(mat[0][1] - mat[1][0]), + r/4); + } else if (mat[0][0] >= mat[1][1] && mat[0][0] >= mat[2][2]) { + double r = 2*sqrt(1 - mat[1][1] - mat[2][2] + mat[0][0]); + double rinv = simd_recip(r); + return simd_quaternion(r/4, + rinv*(mat[0][1] + mat[1][0]), + rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] - mat[2][1])); + } else if (mat[1][1] >= mat[2][2]) { + double r = 2*sqrt(1 - mat[0][0] - mat[2][2] + mat[1][1]); + double rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][1] + mat[1][0]), + r/4, + rinv*(mat[1][2] + mat[2][1]), + rinv*(mat[2][0] - mat[0][2])); + } else { + double r = 2*sqrt(1 - mat[0][0] - mat[1][1] + mat[2][2]); + double rinv = simd_recip(r); + return simd_quaternion(rinv*(mat[0][2] + mat[2][0]), + rinv*(mat[1][2] + mat[2][1]), + r/4, + rinv*(mat[0][1] - mat[1][0])); + } +} + +/*! @abstract The angle between p and q interpreted as 4-dimensional vectors. + * + * @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_NOINLINE double _simd_angle(simd_quatd p, simd_quatd q) { + return 2*atan2(simd_length(p.vector - q.vector), simd_length(p.vector + q.vector)); +} + +/*! @abstract sin(x)/x. + * + * @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_CFUNC double _simd_sinc(double x) { + if (x == 0) return 1; + return sin(x)/x; +} + +/*! @abstract Spherical lerp between q0 and q1. + * + * @discussion This function may interpolate along either the longer or + * shorter path between q0 and q1; it is used as an implementation detail + * in `simd_slerp` and `simd_slerp_longest`; you should use those functions + * instead of calling this directly. */ +static SIMD_NOINLINE simd_quatd _simd_slerp_internal(simd_quatd q0, simd_quatd q1, double t) { + double s = 1 - t; + double a = _simd_angle(q0, q1); + double r = simd_recip(_simd_sinc(a)); + return simd_normalize(simd_quaternion(_simd_sinc(s*a)*r*s*q0.vector + _simd_sinc(t*a)*r*t*q1.vector)); +} + +static SIMD_NOINLINE simd_quatd simd_slerp(simd_quatd q0, simd_quatd q1, double t) { + if (simd_dot(q0, q1) >= 0) + return _simd_slerp_internal(q0, q1, t); + return _simd_slerp_internal(q0, simd_negate(q1), t); +} + +static SIMD_NOINLINE simd_quatd simd_slerp_longest(simd_quatd q0, simd_quatd q1, double t) { + if (simd_dot(q0, q1) >= 0) + return _simd_slerp_internal(q0, simd_negate(q1), t); + return _simd_slerp_internal(q0, q1, t); +} + +/*! @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_NOINLINE simd_quatd _simd_intermediate(simd_quatd q0, simd_quatd q1, simd_quatd q2) { + simd_quatd p0 = __tg_log(simd_mul(q0, simd_inverse(q1))); + simd_quatd p2 = __tg_log(simd_mul(q2, simd_inverse(q1))); + return simd_normalize(simd_mul(q1, __tg_exp(simd_mul(-0.25, simd_add(p0,p2))))); +} + +/*! @discussion This function is an implementation detail and you should not + * call it directly. It may be removed or modified in future versions of the + * simd module. */ +static SIMD_NOINLINE simd_quatd _simd_squad(simd_quatd q0, simd_quatd qa, simd_quatd qb, simd_quatd q1, double t) { + simd_quatd r0 = _simd_slerp_internal(q0, q1, t); + simd_quatd r1 = _simd_slerp_internal(qa, qb, t); + return _simd_slerp_internal(r0, r1, 2*t*(1 - t)); +} + +static SIMD_NOINLINE simd_quatd simd_spline(simd_quatd q0, simd_quatd q1, simd_quatd q2, simd_quatd q3, double t) { + simd_quatd qa = _simd_intermediate(q0, q1, q2); + simd_quatd qb = _simd_intermediate(q1, q2, q3); + return _simd_squad(q1, qa, qb, q2, t); +} + +static SIMD_NOINLINE simd_quatd simd_bezier(simd_quatd q0, simd_quatd q1, simd_quatd q2, simd_quatd q3, double t) { + simd_quatd q01 = _simd_slerp_internal(q0, q1, t); + simd_quatd q12 = _simd_slerp_internal(q1, q2, t); + simd_quatd q23 = _simd_slerp_internal(q2, q3, t); + simd_quatd q012 = _simd_slerp_internal(q01, q12, t); + simd_quatd q123 = _simd_slerp_internal(q12, q23, t); + return _simd_slerp_internal(q012, q123, t); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ +#endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* SIMD_QUATERNIONS */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/simd/vector_make.h b/lib/libc/include/any-macos.11-any/simd/vector_make.h new file mode 100644 index 0000000000..b8e2323944 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/simd/vector_make.h @@ -0,0 +1,6768 @@ +/*! @header + * This header defines functions for constructing, extending, and truncating + * simd vector types. + * + * For each vector type `simd_typeN` supported by , the following + * constructors are provided: + * + * ~~~ + * simd_typeN simd_make_typeN(type other); + * simd_typeN simd_make_typeN(simd_typeM other); + * ~~~ + * For the scalar-input version, or if M < N, these functions zero-extend + * `other` to produce a wider vector. If M == N, `other` is passed through + * unmodified. If `M > N`, `other` is truncated to form the result. + * + * ~~~ + * simd_typeN simd_make_typeN_undef(type other); + * simd_typeN simd_make_typeN_undef(simd_typeM other); + * ~~~ + * These functions are only available for M < N and for scalar inputs. They + * extend `other` to produce a wider vector where the contents of the newly- + * formed lanes are undefined. + * + * In addition, if N is 2, 3, or 4, the following constructors are available: + * ~~~ + * simd_make_typeN(parts ...) + * ~~~ + * where parts is a list of scalars and smaller vectors such that the sum of + * the number of lanes in the arguments is equal to N. For example, a + * `simd_float3` can be constructed from three `floats`, or a `float` and a + * `simd_float2` in any order: + * ~~~ + * simd_float2 ab = { 1, 2 }; + * simd_float3 vector = simd_make_float3(ab, 3); + * ~~~ + * + * @copyright 2014-2016 Apple, Inc. All rights reserved. + * @unsorted */ + +#ifndef SIMD_VECTOR_CONSTRUCTORS +#define SIMD_VECTOR_CONSTRUCTORS + +#include +#if SIMD_COMPILER_HAS_REQUIRED_FEATURES + +#ifdef __cplusplus +extern "C" { +#endif + +/*! @abstract Concatenates `x` and `y` to form a vector of two 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(char x, char y) { + simd_char2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(char other) { + simd_char2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2_undef(char other) { + simd_char2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char16 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char32 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char2 simd_make_char2(simd_char64 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(char x, char y, char z) { + simd_char3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(char x, simd_char2 yz) { + simd_char3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char2 xy, char z) { + simd_char3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(char other) { + simd_char3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3_undef(char other) { + simd_char3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char2 other) { + simd_char3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3_undef(simd_char2 other) { + simd_char3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char16 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char32 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char3 simd_make_char3(simd_char64 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 8-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(char x, char y, char z, char w) { + simd_char4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(char x, char y, simd_char2 zw) { + simd_char4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(char x, simd_char2 yz, char w) { + simd_char4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char2 xy, char z, char w) { + simd_char4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(char x, simd_char3 yzw) { + simd_char4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char2 xy, simd_char2 zw) { + simd_char4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char3 xyz, char w) { + simd_char4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(char other) { + simd_char4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4_undef(char other) { + simd_char4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char2 other) { + simd_char4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4_undef(simd_char2 other) { + simd_char4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char3 other) { + simd_char4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4_undef(simd_char3 other) { + simd_char4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char16 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char32 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_char4 simd_make_char4(simd_char64 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char4 lo, simd_char4 hi) { + simd_char8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(char other) { + simd_char8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8_undef(char other) { + simd_char8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char2 other) { + simd_char8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8_undef(simd_char2 other) { + simd_char8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char3 other) { + simd_char8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8_undef(simd_char3 other) { + simd_char8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char4 other) { + simd_char8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8_undef(simd_char4 other) { + simd_char8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char16 other) { + return simd_make_char8(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char32 other) { + return simd_make_char8(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of eight 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char8 simd_make_char8(simd_char64 other) { + return simd_make_char8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char8 lo, simd_char8 hi) { + simd_char16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(char other) { + simd_char16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16_undef(char other) { + simd_char16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char2 other) { + simd_char16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16_undef(simd_char2 other) { + simd_char16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char3 other) { + simd_char16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16_undef(simd_char3 other) { + simd_char16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char4 other) { + simd_char16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16_undef(simd_char4 other) { + simd_char16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char8 other) { + simd_char16 result = 0; + result.lo = simd_make_char8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16_undef(simd_char8 other) { + simd_char16 result; + result.lo = simd_make_char8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char16 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char32 other) { + return simd_make_char16(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char16 simd_make_char16(simd_char64 other) { + return simd_make_char16(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 8-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char16 lo, simd_char16 hi) { + simd_char32 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(char other) { + simd_char32 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32_undef(char other) { + simd_char32 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char2 other) { + simd_char32 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32_undef(simd_char2 other) { + simd_char32 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char3 other) { + simd_char32 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32_undef(simd_char3 other) { + simd_char32 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char4 other) { + simd_char32 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32_undef(simd_char4 other) { + simd_char32 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char8 other) { + simd_char32 result = 0; + result.lo = simd_make_char16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32_undef(simd_char8 other) { + simd_char32 result; + result.lo = simd_make_char16(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char16 other) { + simd_char32 result = 0; + result.lo = simd_make_char16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32_undef(simd_char16 other) { + simd_char32 result; + result.lo = simd_make_char16(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char32 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char32 simd_make_char32(simd_char64 other) { + return simd_make_char32(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixty-four + * 8-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char32 lo, simd_char32 hi) { + simd_char64 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(char other) { + simd_char64 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(char other) { + simd_char64 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char2 other) { + simd_char64 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(simd_char2 other) { + simd_char64 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char3 other) { + simd_char64 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(simd_char3 other) { + simd_char64 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char4 other) { + simd_char64 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(simd_char4 other) { + simd_char64 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char8 other) { + simd_char64 result = 0; + result.lo = simd_make_char32(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(simd_char8 other) { + simd_char64 result; + result.lo = simd_make_char32(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char16 other) { + simd_char64 result = 0; + result.lo = simd_make_char32(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(simd_char16 other) { + simd_char64 result; + result.lo = simd_make_char32(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char32 other) { + simd_char64 result = 0; + result.lo = simd_make_char32(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64_undef(simd_char32 other) { + simd_char64 result; + result.lo = simd_make_char32(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_char64 simd_make_char64(simd_char64 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(unsigned char x, unsigned char y) { + simd_uchar2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(unsigned char other) { + simd_uchar2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2_undef(unsigned char other) { + simd_uchar2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar16 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar32 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar2 simd_make_uchar2(simd_uchar64 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(unsigned char x, unsigned char y, unsigned char z) { + simd_uchar3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(unsigned char x, simd_uchar2 yz) { + simd_uchar3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar2 xy, unsigned char z) { + simd_uchar3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(unsigned char other) { + simd_uchar3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3_undef(unsigned char other) { + simd_uchar3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar2 other) { + simd_uchar3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3_undef(simd_uchar2 other) { + simd_uchar3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar16 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar32 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar3 simd_make_uchar3(simd_uchar64 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 8-bit unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(unsigned char x, unsigned char y, unsigned char z, unsigned char w) { + simd_uchar4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(unsigned char x, unsigned char y, simd_uchar2 zw) { + simd_uchar4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(unsigned char x, simd_uchar2 yz, unsigned char w) { + simd_uchar4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar2 xy, unsigned char z, unsigned char w) { + simd_uchar4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(unsigned char x, simd_uchar3 yzw) { + simd_uchar4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar2 xy, simd_uchar2 zw) { + simd_uchar4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar3 xyz, unsigned char w) { + simd_uchar4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(unsigned char other) { + simd_uchar4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4_undef(unsigned char other) { + simd_uchar4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar2 other) { + simd_uchar4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4_undef(simd_uchar2 other) { + simd_uchar4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar3 other) { + simd_uchar4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4_undef(simd_uchar3 other) { + simd_uchar4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar16 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar32 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar4 simd_make_uchar4(simd_uchar64 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar4 lo, simd_uchar4 hi) { + simd_uchar8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(unsigned char other) { + simd_uchar8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8_undef(unsigned char other) { + simd_uchar8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar2 other) { + simd_uchar8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8_undef(simd_uchar2 other) { + simd_uchar8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar3 other) { + simd_uchar8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8_undef(simd_uchar3 other) { + simd_uchar8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar4 other) { + simd_uchar8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8_undef(simd_uchar4 other) { + simd_uchar8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar16 other) { + return simd_make_uchar8(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar32 other) { + return simd_make_uchar8(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of eight 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar8 simd_make_uchar8(simd_uchar64 other) { + return simd_make_uchar8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar8 lo, simd_uchar8 hi) { + simd_uchar16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(unsigned char other) { + simd_uchar16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16_undef(unsigned char other) { + simd_uchar16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar2 other) { + simd_uchar16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16_undef(simd_uchar2 other) { + simd_uchar16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar3 other) { + simd_uchar16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16_undef(simd_uchar3 other) { + simd_uchar16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar4 other) { + simd_uchar16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16_undef(simd_uchar4 other) { + simd_uchar16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar8 other) { + simd_uchar16 result = 0; + result.lo = simd_make_uchar8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16_undef(simd_uchar8 other) { + simd_uchar16 result; + result.lo = simd_make_uchar8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar16 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of sixteen 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar32 other) { + return simd_make_uchar16(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of sixteen 8-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uchar16 simd_make_uchar16(simd_uchar64 other) { + return simd_make_uchar16(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 8-bit unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar16 lo, simd_uchar16 hi) { + simd_uchar32 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(unsigned char other) { + simd_uchar32 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32_undef(unsigned char other) { + simd_uchar32 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar2 other) { + simd_uchar32 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32_undef(simd_uchar2 other) { + simd_uchar32 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar3 other) { + simd_uchar32 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32_undef(simd_uchar3 other) { + simd_uchar32 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar4 other) { + simd_uchar32 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32_undef(simd_uchar4 other) { + simd_uchar32 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar8 other) { + simd_uchar32 result = 0; + result.lo = simd_make_uchar16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32_undef(simd_uchar8 other) { + simd_uchar32 result; + result.lo = simd_make_uchar16(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar16 other) { + simd_uchar32 result = 0; + result.lo = simd_make_uchar16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32_undef(simd_uchar16 other) { + simd_uchar32 result; + result.lo = simd_make_uchar16(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar32 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of thirty-two 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar32 simd_make_uchar32(simd_uchar64 other) { + return simd_make_uchar32(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixty-four + * 8-bit unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar32 lo, simd_uchar32 hi) { + simd_uchar64 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(unsigned char other) { + simd_uchar64 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(unsigned char other) { + simd_uchar64 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar2 other) { + simd_uchar64 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(simd_uchar2 other) { + simd_uchar64 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar3 other) { + simd_uchar64 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(simd_uchar3 other) { + simd_uchar64 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar4 other) { + simd_uchar64 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(simd_uchar4 other) { + simd_uchar64 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar8 other) { + simd_uchar64 result = 0; + result.lo = simd_make_uchar32(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(simd_uchar8 other) { + simd_uchar64 result; + result.lo = simd_make_uchar32(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar16 other) { + simd_uchar64 result = 0; + result.lo = simd_make_uchar32(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(simd_uchar16 other) { + simd_uchar64 result; + result.lo = simd_make_uchar32(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixty-four 8-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar32 other) { + simd_uchar64 result = 0; + result.lo = simd_make_uchar32(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64_undef(simd_uchar32 other) { + simd_uchar64 result; + result.lo = simd_make_uchar32(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uchar64 simd_make_uchar64(simd_uchar64 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(short x, short y) { + simd_short2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(short other) { + simd_short2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2_undef(short other) { + simd_short2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(simd_short2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(simd_short3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(simd_short4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(simd_short8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(simd_short16 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_short2 simd_make_short2(simd_short32 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(short x, short y, short z) { + simd_short3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(short x, simd_short2 yz) { + simd_short3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short2 xy, short z) { + simd_short3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(short other) { + simd_short3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3_undef(short other) { + simd_short3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short2 other) { + simd_short3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3_undef(simd_short2 other) { + simd_short3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short16 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short3 simd_make_short3(simd_short32 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 16-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(short x, short y, short z, short w) { + simd_short4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(short x, short y, simd_short2 zw) { + simd_short4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(short x, simd_short2 yz, short w) { + simd_short4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short2 xy, short z, short w) { + simd_short4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(short x, simd_short3 yzw) { + simd_short4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short2 xy, simd_short2 zw) { + simd_short4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short3 xyz, short w) { + simd_short4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(short other) { + simd_short4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4_undef(short other) { + simd_short4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short2 other) { + simd_short4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4_undef(simd_short2 other) { + simd_short4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short3 other) { + simd_short4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4_undef(simd_short3 other) { + simd_short4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short16 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short4 simd_make_short4(simd_short32 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short4 lo, simd_short4 hi) { + simd_short8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(short other) { + simd_short8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8_undef(short other) { + simd_short8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short2 other) { + simd_short8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8_undef(simd_short2 other) { + simd_short8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short3 other) { + simd_short8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8_undef(simd_short3 other) { + simd_short8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short4 other) { + simd_short8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8_undef(simd_short4 other) { + simd_short8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short16 other) { + return simd_make_short8(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of eight 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short8 simd_make_short8(simd_short32 other) { + return simd_make_short8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short8 lo, simd_short8 hi) { + simd_short16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(short other) { + simd_short16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16_undef(short other) { + simd_short16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short2 other) { + simd_short16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16_undef(simd_short2 other) { + simd_short16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short3 other) { + simd_short16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16_undef(simd_short3 other) { + simd_short16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short4 other) { + simd_short16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16_undef(simd_short4 other) { + simd_short16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short8 other) { + simd_short16 result = 0; + result.lo = simd_make_short8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16_undef(simd_short8 other) { + simd_short16 result; + result.lo = simd_make_short8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short16 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short16 simd_make_short16(simd_short32 other) { + return simd_make_short16(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 16-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short16 lo, simd_short16 hi) { + simd_short32 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(short other) { + simd_short32 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32_undef(short other) { + simd_short32 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short2 other) { + simd_short32 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32_undef(simd_short2 other) { + simd_short32 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short3 other) { + simd_short32 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32_undef(simd_short3 other) { + simd_short32 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short4 other) { + simd_short32 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32_undef(simd_short4 other) { + simd_short32 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short8 other) { + simd_short32 result = 0; + result.lo = simd_make_short16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32_undef(simd_short8 other) { + simd_short32 result; + result.lo = simd_make_short16(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short16 other) { + simd_short32 result = 0; + result.lo = simd_make_short16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32_undef(simd_short16 other) { + simd_short32 result; + result.lo = simd_make_short16(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_short32 simd_make_short32(simd_short32 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(unsigned short x, unsigned short y) { + simd_ushort2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(unsigned short other) { + simd_ushort2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2_undef(unsigned short other) { + simd_ushort2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(simd_ushort2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(simd_ushort3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(simd_ushort4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(simd_ushort8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(simd_ushort16 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort2 simd_make_ushort2(simd_ushort32 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(unsigned short x, unsigned short y, unsigned short z) { + simd_ushort3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(unsigned short x, simd_ushort2 yz) { + simd_ushort3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort2 xy, unsigned short z) { + simd_ushort3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(unsigned short other) { + simd_ushort3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3_undef(unsigned short other) { + simd_ushort3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort2 other) { + simd_ushort3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3_undef(simd_ushort2 other) { + simd_ushort3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort16 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort3 simd_make_ushort3(simd_ushort32 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 16-bit unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w) { + simd_ushort4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(unsigned short x, unsigned short y, simd_ushort2 zw) { + simd_ushort4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(unsigned short x, simd_ushort2 yz, unsigned short w) { + simd_ushort4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort2 xy, unsigned short z, unsigned short w) { + simd_ushort4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(unsigned short x, simd_ushort3 yzw) { + simd_ushort4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort2 xy, simd_ushort2 zw) { + simd_ushort4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort3 xyz, unsigned short w) { + simd_ushort4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(unsigned short other) { + simd_ushort4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4_undef(unsigned short other) { + simd_ushort4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort2 other) { + simd_ushort4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4_undef(simd_ushort2 other) { + simd_ushort4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort3 other) { + simd_ushort4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4_undef(simd_ushort3 other) { + simd_ushort4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort16 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort4 simd_make_ushort4(simd_ushort32 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort4 lo, simd_ushort4 hi) { + simd_ushort8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(unsigned short other) { + simd_ushort8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8_undef(unsigned short other) { + simd_ushort8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort2 other) { + simd_ushort8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8_undef(simd_ushort2 other) { + simd_ushort8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort3 other) { + simd_ushort8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8_undef(simd_ushort3 other) { + simd_ushort8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort4 other) { + simd_ushort8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8_undef(simd_ushort4 other) { + simd_ushort8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort16 other) { + return simd_make_ushort8(other.lo); +} + +/*! @abstract Truncates `other` to form a vector of eight 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort8 simd_make_ushort8(simd_ushort32 other) { + return simd_make_ushort8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort8 lo, simd_ushort8 hi) { + simd_ushort16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(unsigned short other) { + simd_ushort16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16_undef(unsigned short other) { + simd_ushort16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort2 other) { + simd_ushort16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16_undef(simd_ushort2 other) { + simd_ushort16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort3 other) { + simd_ushort16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16_undef(simd_ushort3 other) { + simd_ushort16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort4 other) { + simd_ushort16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16_undef(simd_ushort4 other) { + simd_ushort16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort8 other) { + simd_ushort16 result = 0; + result.lo = simd_make_ushort8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16_undef(simd_ushort8 other) { + simd_ushort16 result; + result.lo = simd_make_ushort8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort16 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of sixteen 16-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ushort16 simd_make_ushort16(simd_ushort32 other) { + return simd_make_ushort16(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 16-bit unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort16 lo, simd_ushort16 hi) { + simd_ushort32 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(unsigned short other) { + simd_ushort32 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32_undef(unsigned short other) { + simd_ushort32 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort2 other) { + simd_ushort32 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32_undef(simd_ushort2 other) { + simd_ushort32 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort3 other) { + simd_ushort32 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32_undef(simd_ushort3 other) { + simd_ushort32 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort4 other) { + simd_ushort32 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32_undef(simd_ushort4 other) { + simd_ushort32 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort8 other) { + simd_ushort32 result = 0; + result.lo = simd_make_ushort16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32_undef(simd_ushort8 other) { + simd_ushort32 result; + result.lo = simd_make_ushort16(other); + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of thirty-two 16-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort16 other) { + simd_ushort32 result = 0; + result.lo = simd_make_ushort16(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32_undef(simd_ushort16 other) { + simd_ushort32 result; + result.lo = simd_make_ushort16(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ushort32 simd_make_ushort32(simd_ushort32 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(int x, int y) { + simd_int2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(int other) { + simd_int2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2_undef(int other) { + simd_int2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(simd_int2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(simd_int3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(simd_int4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(simd_int8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_int2 simd_make_int2(simd_int16 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(int x, int y, int z) { + simd_int3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(int x, simd_int2 yz) { + simd_int3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(simd_int2 xy, int z) { + simd_int3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(int other) { + simd_int3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3_undef(int other) { + simd_int3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(simd_int2 other) { + simd_int3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3_undef(simd_int2 other) { + simd_int3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(simd_int3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(simd_int4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(simd_int8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int3 simd_make_int3(simd_int16 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 32-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(int x, int y, int z, int w) { + simd_int4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(int x, int y, simd_int2 zw) { + simd_int4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(int x, simd_int2 yz, int w) { + simd_int4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int2 xy, int z, int w) { + simd_int4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(int x, simd_int3 yzw) { + simd_int4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int2 xy, simd_int2 zw) { + simd_int4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int3 xyz, int w) { + simd_int4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(int other) { + simd_int4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4_undef(int other) { + simd_int4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int2 other) { + simd_int4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4_undef(simd_int2 other) { + simd_int4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int3 other) { + simd_int4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4_undef(simd_int3 other) { + simd_int4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int4 simd_make_int4(simd_int16 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(simd_int4 lo, simd_int4 hi) { + simd_int8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(int other) { + simd_int8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8_undef(int other) { + simd_int8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(simd_int2 other) { + simd_int8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8_undef(simd_int2 other) { + simd_int8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(simd_int3 other) { + simd_int8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8_undef(simd_int3 other) { + simd_int8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(simd_int4 other) { + simd_int8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8_undef(simd_int4 other) { + simd_int8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(simd_int8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int8 simd_make_int8(simd_int16 other) { + return simd_make_int8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(simd_int8 lo, simd_int8 hi) { + simd_int16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(int other) { + simd_int16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16_undef(int other) { + simd_int16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(simd_int2 other) { + simd_int16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16_undef(simd_int2 other) { + simd_int16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(simd_int3 other) { + simd_int16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16_undef(simd_int3 other) { + simd_int16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(simd_int4 other) { + simd_int16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16_undef(simd_int4 other) { + simd_int16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(simd_int8 other) { + simd_int16 result = 0; + result.lo = simd_make_int8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16_undef(simd_int8 other) { + simd_int16 result; + result.lo = simd_make_int8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_int16 simd_make_int16(simd_int16 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(unsigned int x, unsigned int y) { + simd_uint2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(unsigned int other) { + simd_uint2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2_undef(unsigned int other) { + simd_uint2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(simd_uint2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(simd_uint3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(simd_uint4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(simd_uint8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint2 simd_make_uint2(simd_uint16 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(unsigned int x, unsigned int y, unsigned int z) { + simd_uint3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(unsigned int x, simd_uint2 yz) { + simd_uint3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(simd_uint2 xy, unsigned int z) { + simd_uint3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(unsigned int other) { + simd_uint3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3_undef(unsigned int other) { + simd_uint3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(simd_uint2 other) { + simd_uint3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3_undef(simd_uint2 other) { + simd_uint3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(simd_uint3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(simd_uint4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(simd_uint8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint3 simd_make_uint3(simd_uint16 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 32-bit unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(unsigned int x, unsigned int y, unsigned int z, unsigned int w) { + simd_uint4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(unsigned int x, unsigned int y, simd_uint2 zw) { + simd_uint4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(unsigned int x, simd_uint2 yz, unsigned int w) { + simd_uint4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint2 xy, unsigned int z, unsigned int w) { + simd_uint4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(unsigned int x, simd_uint3 yzw) { + simd_uint4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint2 xy, simd_uint2 zw) { + simd_uint4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint3 xyz, unsigned int w) { + simd_uint4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(unsigned int other) { + simd_uint4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4_undef(unsigned int other) { + simd_uint4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint2 other) { + simd_uint4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4_undef(simd_uint2 other) { + simd_uint4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint3 other) { + simd_uint4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4_undef(simd_uint3 other) { + simd_uint4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint4 simd_make_uint4(simd_uint16 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(simd_uint4 lo, simd_uint4 hi) { + simd_uint8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(unsigned int other) { + simd_uint8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8_undef(unsigned int other) { + simd_uint8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(simd_uint2 other) { + simd_uint8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8_undef(simd_uint2 other) { + simd_uint8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(simd_uint3 other) { + simd_uint8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8_undef(simd_uint3 other) { + simd_uint8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(simd_uint4 other) { + simd_uint8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8_undef(simd_uint4 other) { + simd_uint8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(simd_uint8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 32-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_uint8 simd_make_uint8(simd_uint16 other) { + return simd_make_uint8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(simd_uint8 lo, simd_uint8 hi) { + simd_uint16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(unsigned int other) { + simd_uint16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16_undef(unsigned int other) { + simd_uint16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(simd_uint2 other) { + simd_uint16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16_undef(simd_uint2 other) { + simd_uint16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(simd_uint3 other) { + simd_uint16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16_undef(simd_uint3 other) { + simd_uint16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(simd_uint4 other) { + simd_uint16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16_undef(simd_uint4 other) { + simd_uint16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(simd_uint8 other) { + simd_uint16 result = 0; + result.lo = simd_make_uint8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16_undef(simd_uint8 other) { + simd_uint16 result; + result.lo = simd_make_uint8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_uint16 simd_make_uint16(simd_uint16 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(float x, float y) { + simd_float2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(float other) { + simd_float2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 32-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2_undef(float other) { + simd_float2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(simd_float2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(simd_float3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(simd_float4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(simd_float8 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float2 simd_make_float2(simd_float16 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(float x, float y, float z) { + simd_float3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(float x, simd_float2 yz) { + simd_float3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(simd_float2 xy, float z) { + simd_float3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(float other) { + simd_float3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3_undef(float other) { + simd_float3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(simd_float2 other) { + simd_float3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3_undef(simd_float2 other) { + simd_float3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(simd_float3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(simd_float4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(simd_float8 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float3 simd_make_float3(simd_float16 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 32-bit floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(float x, float y, float z, float w) { + simd_float4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(float x, float y, simd_float2 zw) { + simd_float4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(float x, simd_float2 yz, float w) { + simd_float4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float2 xy, float z, float w) { + simd_float4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(float x, simd_float3 yzw) { + simd_float4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float2 xy, simd_float2 zw) { + simd_float4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float3 xyz, float w) { + simd_float4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(float other) { + simd_float4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4_undef(float other) { + simd_float4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float2 other) { + simd_float4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4_undef(simd_float2 other) { + simd_float4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float3 other) { + simd_float4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 32-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4_undef(simd_float3 other) { + simd_float4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float8 other) { + return other.xyzw; +} + +/*! @abstract Truncates `other` to form a vector of four 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float4 simd_make_float4(simd_float16 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(simd_float4 lo, simd_float4 hi) { + simd_float8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(float other) { + simd_float8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8_undef(float other) { + simd_float8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(simd_float2 other) { + simd_float8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8_undef(simd_float2 other) { + simd_float8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(simd_float3 other) { + simd_float8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8_undef(simd_float3 other) { + simd_float8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(simd_float4 other) { + simd_float8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8_undef(simd_float4 other) { + simd_float8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(simd_float8 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of eight 32-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_float8 simd_make_float8(simd_float16 other) { + return simd_make_float8(other.lo); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(simd_float8 lo, simd_float8 hi) { + simd_float16 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(float other) { + simd_float16 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16_undef(float other) { + simd_float16 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(simd_float2 other) { + simd_float16 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16_undef(simd_float2 other) { + simd_float16 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(simd_float3 other) { + simd_float16 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16_undef(simd_float3 other) { + simd_float16 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(simd_float4 other) { + simd_float16 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16_undef(simd_float4 other) { + simd_float16 result; + result.xyzw = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(simd_float8 other) { + simd_float16 result = 0; + result.lo = simd_make_float8(other); + return result; +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16_undef(simd_float8 other) { + simd_float16 result; + result.lo = simd_make_float8(other); + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_float16 simd_make_float16(simd_float16 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2(simd_long1 x, simd_long1 y) { + simd_long2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2(simd_long1 other) { + simd_long2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2_undef(simd_long1 other) { + simd_long2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2(simd_long2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2(simd_long3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2(simd_long4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit signed (twos- + * complement) integers. */ +static inline SIMD_CFUNC simd_long2 simd_make_long2(simd_long8 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long1 x, simd_long1 y, simd_long1 z) { + simd_long3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long1 x, simd_long2 yz) { + simd_long3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long2 xy, simd_long1 z) { + simd_long3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long1 other) { + simd_long3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3_undef(simd_long1 other) { + simd_long3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long2 other) { + simd_long3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3_undef(simd_long2 other) { + simd_long3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long3 simd_make_long3(simd_long8 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 64-bit signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long1 x, simd_long1 y, simd_long1 z, simd_long1 w) { + simd_long4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long1 x, simd_long1 y, simd_long2 zw) { + simd_long4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long1 x, simd_long2 yz, simd_long1 w) { + simd_long4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long2 xy, simd_long1 z, simd_long1 w) { + simd_long4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long1 x, simd_long3 yzw) { + simd_long4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long2 xy, simd_long2 zw) { + simd_long4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long3 xyz, simd_long1 w) { + simd_long4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long1 other) { + simd_long4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4_undef(simd_long1 other) { + simd_long4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long2 other) { + simd_long4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4_undef(simd_long2 other) { + simd_long4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long3 other) { + simd_long4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4_undef(simd_long3 other) { + simd_long4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long4 simd_make_long4(simd_long8 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8(simd_long4 lo, simd_long4 hi) { + simd_long8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8(simd_long1 other) { + simd_long8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8_undef(simd_long1 other) { + simd_long8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8(simd_long2 other) { + simd_long8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8_undef(simd_long2 other) { + simd_long8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8(simd_long3 other) { + simd_long8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8_undef(simd_long3 other) { + simd_long8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8(simd_long4 other) { + simd_long8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8_undef(simd_long4 other) { + simd_long8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_long8 simd_make_long8(simd_long8 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2(simd_ulong1 x, simd_ulong1 y) { + simd_ulong2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2(simd_ulong1 other) { + simd_ulong2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2_undef(simd_ulong1 other) { + simd_ulong2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2(simd_ulong2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2(simd_ulong3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2(simd_ulong4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong2 simd_make_ulong2(simd_ulong8 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong1 x, simd_ulong1 y, simd_ulong1 z) { + simd_ulong3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong1 x, simd_ulong2 yz) { + simd_ulong3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong2 xy, simd_ulong1 z) { + simd_ulong3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong1 other) { + simd_ulong3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3_undef(simd_ulong1 other) { + simd_ulong3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong2 other) { + simd_ulong3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3_undef(simd_ulong2 other) { + simd_ulong3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong3 simd_make_ulong3(simd_ulong8 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 64-bit unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong1 x, simd_ulong1 y, simd_ulong1 z, simd_ulong1 w) { + simd_ulong4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong1 x, simd_ulong1 y, simd_ulong2 zw) { + simd_ulong4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong1 x, simd_ulong2 yz, simd_ulong1 w) { + simd_ulong4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong2 xy, simd_ulong1 z, simd_ulong1 w) { + simd_ulong4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong1 x, simd_ulong3 yzw) { + simd_ulong4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong2 xy, simd_ulong2 zw) { + simd_ulong4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong3 xyz, simd_ulong1 w) { + simd_ulong4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong1 other) { + simd_ulong4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4_undef(simd_ulong1 other) { + simd_ulong4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong2 other) { + simd_ulong4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4_undef(simd_ulong2 other) { + simd_ulong4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong3 other) { + simd_ulong4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4_undef(simd_ulong3 other) { + simd_ulong4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong4 simd_make_ulong4(simd_ulong8 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 64-bit + * unsigned integers. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8(simd_ulong4 lo, simd_ulong4 hi) { + simd_ulong8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8(simd_ulong1 other) { + simd_ulong8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8_undef(simd_ulong1 other) { + simd_ulong8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8(simd_ulong2 other) { + simd_ulong8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8_undef(simd_ulong2 other) { + simd_ulong8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8(simd_ulong3 other) { + simd_ulong8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8_undef(simd_ulong3 other) { + simd_ulong8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit unsigned + * integers. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8(simd_ulong4 other) { + simd_ulong8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8_undef(simd_ulong4 other) { + simd_ulong8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_ulong8 simd_make_ulong8(simd_ulong8 other) { + return other; +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2(double x, double y) { + simd_double2 result; + result.x = x; + result.y = y; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of two 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2(double other) { + simd_double2 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of two 64-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2_undef(double other) { + simd_double2 result; + result.x = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2(simd_double2 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2(simd_double3 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2(simd_double4 other) { + return other.xy; +} + +/*! @abstract Truncates `other` to form a vector of two 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double2 simd_make_double2(simd_double8 other) { + return other.xy; +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(double x, double y, double z) { + simd_double3 result; + result.x = x; + result.y = y; + result.z = z; + return result; +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(double x, simd_double2 yz) { + simd_double3 result; + result.x = x; + result.yz = yz; + return result; +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(simd_double2 xy, double z) { + simd_double3 result; + result.xy = xy; + result.z = z; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(double other) { + simd_double3 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3_undef(double other) { + simd_double3 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(simd_double2 other) { + simd_double3 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of three 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3_undef(simd_double2 other) { + simd_double3 result; + result.xy = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(simd_double3 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of three 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(simd_double4 other) { + return other.xyz; +} + +/*! @abstract Truncates `other` to form a vector of three 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double3 simd_make_double3(simd_double8 other) { + return other.xyz; +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 64-bit floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(double x, double y, double z, double w) { + simd_double4 result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(double x, double y, simd_double2 zw) { + simd_double4 result; + result.x = x; + result.y = y; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(double x, simd_double2 yz, double w) { + simd_double4 result; + result.x = x; + result.yz = yz; + result.w = w; + return result; +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double2 xy, double z, double w) { + simd_double4 result; + result.xy = xy; + result.z = z; + result.w = w; + return result; +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(double x, simd_double3 yzw) { + simd_double4 result; + result.x = x; + result.yzw = yzw; + return result; +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double2 xy, simd_double2 zw) { + simd_double4 result; + result.xy = xy; + result.zw = zw; + return result; +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double3 xyz, double w) { + simd_double4 result; + result.xyz = xyz; + result.w = w; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(double other) { + simd_double4 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4_undef(double other) { + simd_double4 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double2 other) { + simd_double4 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4_undef(simd_double2 other) { + simd_double4 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of four 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double3 other) { + simd_double4 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of four 64-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4_undef(simd_double3 other) { + simd_double4 result; + result.xyz = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double4 other) { + return other; +} + +/*! @abstract Truncates `other` to form a vector of four 64-bit floating- + * point numbers. */ +static inline SIMD_CFUNC simd_double4 simd_make_double4(simd_double8 other) { + return other.xyzw; +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8(simd_double4 lo, simd_double4 hi) { + simd_double8 result; + result.lo = lo; + result.hi = hi; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8(double other) { + simd_double8 result = 0; + result.x = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8_undef(double other) { + simd_double8 result; + result.x = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8(simd_double2 other) { + simd_double8 result = 0; + result.xy = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8_undef(simd_double2 other) { + simd_double8 result; + result.xy = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8(simd_double3 other) { + simd_double8 result = 0; + result.xyz = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8_undef(simd_double3 other) { + simd_double8 result; + result.xyz = other; + return result; +} + +/*! @abstract Zero-extends `other` to form a vector of eight 64-bit + * floating-point numbers. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8(simd_double4 other) { + simd_double8 result = 0; + result.xyzw = other; + return result; +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8_undef(simd_double4 other) { + simd_double8 result; + result.xyzw = other; + return result; +} + +/*! @abstract Returns `other` unmodified. This function is a convenience for + * templated and autogenerated code. */ +static inline SIMD_CFUNC simd_double8 simd_make_double8(simd_double8 other) { + return other; +} + +#ifdef __cplusplus +} /* extern "C" */ + +namespace simd { +/*! @abstract Concatenates `x` and `y` to form a vector of two 8-bit signed + * (twos-complement) integers. */ +static inline SIMD_CPPFUNC char2 make_char2(char x, char y) { + return ::simd_make_char2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char2 make_char2(typeN other) { + return ::simd_make_char2(other); +} + +/*! @abstract Extends `other` to form a vector of two 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC char2 make_char2_undef(typeN other) { + return ::simd_make_char2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char3 make_char3(char x, char y, char z) { + return ::simd_make_char3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char3 make_char3(char x, char2 yz) { + return ::simd_make_char3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char3 make_char3(char2 xy, char z) { + return ::simd_make_char3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char3 make_char3(typeN other) { + return ::simd_make_char3(other); +} + +/*! @abstract Extends `other` to form a vector of three 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC char3 make_char3_undef(typeN other) { + return ::simd_make_char3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 8-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char x, char y, char z, char w) { + return ::simd_make_char4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char x, char y, char2 zw) { + return ::simd_make_char4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char x, char2 yz, char w) { + return ::simd_make_char4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char2 xy, char z, char w) { + return ::simd_make_char4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char x, char3 yzw) { + return ::simd_make_char4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char2 xy, char2 zw) { + return ::simd_make_char4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char4 make_char4(char3 xyz, char w) { + return ::simd_make_char4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char4 make_char4(typeN other) { + return ::simd_make_char4(other); +} + +/*! @abstract Extends `other` to form a vector of four 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC char4 make_char4_undef(typeN other) { + return ::simd_make_char4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char8 make_char8(char4 lo, char4 hi) { + return ::simd_make_char8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char8 make_char8(typeN other) { + return ::simd_make_char8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC char8 make_char8_undef(typeN other) { + return ::simd_make_char8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 8-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char16 make_char16(char8 lo, char8 hi) { + return ::simd_make_char16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char16 make_char16(typeN other) { + return ::simd_make_char16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +template static SIMD_CPPFUNC char16 make_char16_undef(typeN other) { + return ::simd_make_char16_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 8-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char32 make_char32(char16 lo, char16 hi) { + return ::simd_make_char32(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of thirty- + * two 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char32 make_char32(typeN other) { + return ::simd_make_char32(other); +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +template static SIMD_CPPFUNC char32 make_char32_undef(typeN other) { + return ::simd_make_char32_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixty-four + * 8-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC char64 make_char64(char32 lo, char32 hi) { + return ::simd_make_char64(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixty- + * four 8-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC char64 make_char64(typeN other) { + return ::simd_make_char64(other); +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +template static SIMD_CPPFUNC char64 make_char64_undef(typeN other) { + return ::simd_make_char64_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar2 make_uchar2(unsigned char x, unsigned char y) { + return ::simd_make_uchar2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar2 make_uchar2(typeN other) { + return ::simd_make_uchar2(other); +} + +/*! @abstract Extends `other` to form a vector of two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar2 make_uchar2_undef(typeN other) { + return ::simd_make_uchar2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar3 make_uchar3(unsigned char x, unsigned char y, unsigned char z) { + return ::simd_make_uchar3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar3 make_uchar3(unsigned char x, uchar2 yz) { + return ::simd_make_uchar3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar3 make_uchar3(uchar2 xy, unsigned char z) { + return ::simd_make_uchar3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar3 make_uchar3(typeN other) { + return ::simd_make_uchar3(other); +} + +/*! @abstract Extends `other` to form a vector of three 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar3 make_uchar3_undef(typeN other) { + return ::simd_make_uchar3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 8-bit unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(unsigned char x, unsigned char y, unsigned char z, unsigned char w) { + return ::simd_make_uchar4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(unsigned char x, unsigned char y, uchar2 zw) { + return ::simd_make_uchar4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(unsigned char x, uchar2 yz, unsigned char w) { + return ::simd_make_uchar4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(uchar2 xy, unsigned char z, unsigned char w) { + return ::simd_make_uchar4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(unsigned char x, uchar3 yzw) { + return ::simd_make_uchar4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(uchar2 xy, uchar2 zw) { + return ::simd_make_uchar4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar4 make_uchar4(uchar3 xyz, unsigned char w) { + return ::simd_make_uchar4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar4 make_uchar4(typeN other) { + return ::simd_make_uchar4(other); +} + +/*! @abstract Extends `other` to form a vector of four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar4 make_uchar4_undef(typeN other) { + return ::simd_make_uchar4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar8 make_uchar8(uchar4 lo, uchar4 hi) { + return ::simd_make_uchar8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar8 make_uchar8(typeN other) { + return ::simd_make_uchar8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar8 make_uchar8_undef(typeN other) { + return ::simd_make_uchar8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 8-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uchar16 make_uchar16(uchar8 lo, uchar8 hi) { + return ::simd_make_uchar16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar16 make_uchar16(typeN other) { + return ::simd_make_uchar16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar16 make_uchar16_undef(typeN other) { + return ::simd_make_uchar16_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 8-bit unsigned integers. */ +static inline SIMD_CPPFUNC uchar32 make_uchar32(uchar16 lo, uchar16 hi) { + return ::simd_make_uchar32(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of thirty- + * two 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar32 make_uchar32(typeN other) { + return ::simd_make_uchar32(other); +} + +/*! @abstract Extends `other` to form a vector of thirty-two 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar32 make_uchar32_undef(typeN other) { + return ::simd_make_uchar32_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixty-four + * 8-bit unsigned integers. */ +static inline SIMD_CPPFUNC uchar64 make_uchar64(uchar32 lo, uchar32 hi) { + return ::simd_make_uchar64(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixty- + * four 8-bit unsigned integers. */ +template static SIMD_CPPFUNC uchar64 make_uchar64(typeN other) { + return ::simd_make_uchar64(other); +} + +/*! @abstract Extends `other` to form a vector of sixty-four 8-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uchar64 make_uchar64_undef(typeN other) { + return ::simd_make_uchar64_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 16-bit signed + * (twos-complement) integers. */ +static inline SIMD_CPPFUNC short2 make_short2(short x, short y) { + return ::simd_make_short2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 16-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC short2 make_short2(typeN other) { + return ::simd_make_short2(other); +} + +/*! @abstract Extends `other` to form a vector of two 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC short2 make_short2_undef(typeN other) { + return ::simd_make_short2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short3 make_short3(short x, short y, short z) { + return ::simd_make_short3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short3 make_short3(short x, short2 yz) { + return ::simd_make_short3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short3 make_short3(short2 xy, short z) { + return ::simd_make_short3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 16-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC short3 make_short3(typeN other) { + return ::simd_make_short3(other); +} + +/*! @abstract Extends `other` to form a vector of three 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC short3 make_short3_undef(typeN other) { + return ::simd_make_short3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 16-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short x, short y, short z, short w) { + return ::simd_make_short4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short x, short y, short2 zw) { + return ::simd_make_short4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short x, short2 yz, short w) { + return ::simd_make_short4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short2 xy, short z, short w) { + return ::simd_make_short4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short x, short3 yzw) { + return ::simd_make_short4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short2 xy, short2 zw) { + return ::simd_make_short4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short4 make_short4(short3 xyz, short w) { + return ::simd_make_short4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 16-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC short4 make_short4(typeN other) { + return ::simd_make_short4(other); +} + +/*! @abstract Extends `other` to form a vector of four 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC short4 make_short4_undef(typeN other) { + return ::simd_make_short4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short8 make_short8(short4 lo, short4 hi) { + return ::simd_make_short8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 16-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC short8 make_short8(typeN other) { + return ::simd_make_short8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC short8 make_short8_undef(typeN other) { + return ::simd_make_short8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 16-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short16 make_short16(short8 lo, short8 hi) { + return ::simd_make_short16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 16-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC short16 make_short16(typeN other) { + return ::simd_make_short16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +template static SIMD_CPPFUNC short16 make_short16_undef(typeN other) { + return ::simd_make_short16_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 16-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC short32 make_short32(short16 lo, short16 hi) { + return ::simd_make_short32(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of thirty- + * two 16-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC short32 make_short32(typeN other) { + return ::simd_make_short32(other); +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +template static SIMD_CPPFUNC short32 make_short32_undef(typeN other) { + return ::simd_make_short32_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort2 make_ushort2(unsigned short x, unsigned short y) { + return ::simd_make_ushort2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 16-bit unsigned integers. */ +template static SIMD_CPPFUNC ushort2 make_ushort2(typeN other) { + return ::simd_make_ushort2(other); +} + +/*! @abstract Extends `other` to form a vector of two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ushort2 make_ushort2_undef(typeN other) { + return ::simd_make_ushort2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort3 make_ushort3(unsigned short x, unsigned short y, unsigned short z) { + return ::simd_make_ushort3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort3 make_ushort3(unsigned short x, ushort2 yz) { + return ::simd_make_ushort3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort3 make_ushort3(ushort2 xy, unsigned short z) { + return ::simd_make_ushort3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 16-bit unsigned integers. */ +template static SIMD_CPPFUNC ushort3 make_ushort3(typeN other) { + return ::simd_make_ushort3(other); +} + +/*! @abstract Extends `other` to form a vector of three 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ushort3 make_ushort3_undef(typeN other) { + return ::simd_make_ushort3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 16-bit unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(unsigned short x, unsigned short y, unsigned short z, unsigned short w) { + return ::simd_make_ushort4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(unsigned short x, unsigned short y, ushort2 zw) { + return ::simd_make_ushort4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(unsigned short x, ushort2 yz, unsigned short w) { + return ::simd_make_ushort4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(ushort2 xy, unsigned short z, unsigned short w) { + return ::simd_make_ushort4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(unsigned short x, ushort3 yzw) { + return ::simd_make_ushort4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(ushort2 xy, ushort2 zw) { + return ::simd_make_ushort4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort4 make_ushort4(ushort3 xyz, unsigned short w) { + return ::simd_make_ushort4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 16-bit unsigned integers. */ +template static SIMD_CPPFUNC ushort4 make_ushort4(typeN other) { + return ::simd_make_ushort4(other); +} + +/*! @abstract Extends `other` to form a vector of four 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ushort4 make_ushort4_undef(typeN other) { + return ::simd_make_ushort4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort8 make_ushort8(ushort4 lo, ushort4 hi) { + return ::simd_make_ushort8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 16-bit unsigned integers. */ +template static SIMD_CPPFUNC ushort8 make_ushort8(typeN other) { + return ::simd_make_ushort8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ushort8 make_ushort8_undef(typeN other) { + return ::simd_make_ushort8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 16-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ushort16 make_ushort16(ushort8 lo, ushort8 hi) { + return ::simd_make_ushort16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 16-bit unsigned integers. */ +template static SIMD_CPPFUNC ushort16 make_ushort16(typeN other) { + return ::simd_make_ushort16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ushort16 make_ushort16_undef(typeN other) { + return ::simd_make_ushort16_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of thirty-two + * 16-bit unsigned integers. */ +static inline SIMD_CPPFUNC ushort32 make_ushort32(ushort16 lo, ushort16 hi) { + return ::simd_make_ushort32(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of thirty- + * two 16-bit unsigned integers. */ +template static SIMD_CPPFUNC ushort32 make_ushort32(typeN other) { + return ::simd_make_ushort32(other); +} + +/*! @abstract Extends `other` to form a vector of thirty-two 16-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ushort32 make_ushort32_undef(typeN other) { + return ::simd_make_ushort32_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 32-bit signed + * (twos-complement) integers. */ +static inline SIMD_CPPFUNC int2 make_int2(int x, int y) { + return ::simd_make_int2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 32-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC int2 make_int2(typeN other) { + return ::simd_make_int2(other); +} + +/*! @abstract Extends `other` to form a vector of two 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC int2 make_int2_undef(typeN other) { + return ::simd_make_int2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int3 make_int3(int x, int y, int z) { + return ::simd_make_int3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int3 make_int3(int x, int2 yz) { + return ::simd_make_int3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int3 make_int3(int2 xy, int z) { + return ::simd_make_int3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 32-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC int3 make_int3(typeN other) { + return ::simd_make_int3(other); +} + +/*! @abstract Extends `other` to form a vector of three 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC int3 make_int3_undef(typeN other) { + return ::simd_make_int3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 32-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int x, int y, int z, int w) { + return ::simd_make_int4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int x, int y, int2 zw) { + return ::simd_make_int4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int x, int2 yz, int w) { + return ::simd_make_int4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int2 xy, int z, int w) { + return ::simd_make_int4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int x, int3 yzw) { + return ::simd_make_int4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int2 xy, int2 zw) { + return ::simd_make_int4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int4 make_int4(int3 xyz, int w) { + return ::simd_make_int4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 32-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC int4 make_int4(typeN other) { + return ::simd_make_int4(other); +} + +/*! @abstract Extends `other` to form a vector of four 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC int4 make_int4_undef(typeN other) { + return ::simd_make_int4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int8 make_int8(int4 lo, int4 hi) { + return ::simd_make_int8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 32-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC int8 make_int8(typeN other) { + return ::simd_make_int8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC int8 make_int8_undef(typeN other) { + return ::simd_make_int8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 32-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC int16 make_int16(int8 lo, int8 hi) { + return ::simd_make_int16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 32-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC int16 make_int16(typeN other) { + return ::simd_make_int16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit signed + * (twos-complement) integers. The contents of the newly-created vector + * lanes are unspecified. */ +template static SIMD_CPPFUNC int16 make_int16_undef(typeN other) { + return ::simd_make_int16_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint2 make_uint2(unsigned int x, unsigned int y) { + return ::simd_make_uint2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 32-bit unsigned integers. */ +template static SIMD_CPPFUNC uint2 make_uint2(typeN other) { + return ::simd_make_uint2(other); +} + +/*! @abstract Extends `other` to form a vector of two 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uint2 make_uint2_undef(typeN other) { + return ::simd_make_uint2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint3 make_uint3(unsigned int x, unsigned int y, unsigned int z) { + return ::simd_make_uint3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint3 make_uint3(unsigned int x, uint2 yz) { + return ::simd_make_uint3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint3 make_uint3(uint2 xy, unsigned int z) { + return ::simd_make_uint3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 32-bit unsigned integers. */ +template static SIMD_CPPFUNC uint3 make_uint3(typeN other) { + return ::simd_make_uint3(other); +} + +/*! @abstract Extends `other` to form a vector of three 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uint3 make_uint3_undef(typeN other) { + return ::simd_make_uint3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 32-bit unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(unsigned int x, unsigned int y, unsigned int z, unsigned int w) { + return ::simd_make_uint4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(unsigned int x, unsigned int y, uint2 zw) { + return ::simd_make_uint4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(unsigned int x, uint2 yz, unsigned int w) { + return ::simd_make_uint4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(uint2 xy, unsigned int z, unsigned int w) { + return ::simd_make_uint4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(unsigned int x, uint3 yzw) { + return ::simd_make_uint4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(uint2 xy, uint2 zw) { + return ::simd_make_uint4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint4 make_uint4(uint3 xyz, unsigned int w) { + return ::simd_make_uint4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 32-bit unsigned integers. */ +template static SIMD_CPPFUNC uint4 make_uint4(typeN other) { + return ::simd_make_uint4(other); +} + +/*! @abstract Extends `other` to form a vector of four 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uint4 make_uint4_undef(typeN other) { + return ::simd_make_uint4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint8 make_uint8(uint4 lo, uint4 hi) { + return ::simd_make_uint8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 32-bit unsigned integers. */ +template static SIMD_CPPFUNC uint8 make_uint8(typeN other) { + return ::simd_make_uint8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uint8 make_uint8_undef(typeN other) { + return ::simd_make_uint8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 32-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC uint16 make_uint16(uint8 lo, uint8 hi) { + return ::simd_make_uint16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 32-bit unsigned integers. */ +template static SIMD_CPPFUNC uint16 make_uint16(typeN other) { + return ::simd_make_uint16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC uint16 make_uint16_undef(typeN other) { + return ::simd_make_uint16_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float2 make_float2(float x, float y) { + return ::simd_make_float2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 32-bit floating-point numbers. */ +template static SIMD_CPPFUNC float2 make_float2(typeN other) { + return ::simd_make_float2(other); +} + +/*! @abstract Extends `other` to form a vector of two 32-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +template static SIMD_CPPFUNC float2 make_float2_undef(typeN other) { + return ::simd_make_float2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float3 make_float3(float x, float y, float z) { + return ::simd_make_float3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float3 make_float3(float x, float2 yz) { + return ::simd_make_float3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float3 make_float3(float2 xy, float z) { + return ::simd_make_float3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 32-bit floating-point numbers. */ +template static SIMD_CPPFUNC float3 make_float3(typeN other) { + return ::simd_make_float3(other); +} + +/*! @abstract Extends `other` to form a vector of three 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC float3 make_float3_undef(typeN other) { + return ::simd_make_float3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 32-bit floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float x, float y, float z, float w) { + return ::simd_make_float4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float x, float y, float2 zw) { + return ::simd_make_float4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float x, float2 yz, float w) { + return ::simd_make_float4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float2 xy, float z, float w) { + return ::simd_make_float4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float x, float3 yzw) { + return ::simd_make_float4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float2 xy, float2 zw) { + return ::simd_make_float4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float4 make_float4(float3 xyz, float w) { + return ::simd_make_float4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 32-bit floating-point numbers. */ +template static SIMD_CPPFUNC float4 make_float4(typeN other) { + return ::simd_make_float4(other); +} + +/*! @abstract Extends `other` to form a vector of four 32-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +template static SIMD_CPPFUNC float4 make_float4_undef(typeN other) { + return ::simd_make_float4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float8 make_float8(float4 lo, float4 hi) { + return ::simd_make_float8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 32-bit floating-point numbers. */ +template static SIMD_CPPFUNC float8 make_float8(typeN other) { + return ::simd_make_float8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC float8 make_float8_undef(typeN other) { + return ::simd_make_float8_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of sixteen 32-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC float16 make_float16(float8 lo, float8 hi) { + return ::simd_make_float16(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of sixteen + * 32-bit floating-point numbers. */ +template static SIMD_CPPFUNC float16 make_float16(typeN other) { + return ::simd_make_float16(other); +} + +/*! @abstract Extends `other` to form a vector of sixteen 32-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC float16 make_float16_undef(typeN other) { + return ::simd_make_float16_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 64-bit signed + * (twos-complement) integers. */ +static inline SIMD_CPPFUNC long2 make_long2(long1 x, long1 y) { + return ::simd_make_long2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 64-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC long2 make_long2(typeN other) { + return ::simd_make_long2(other); +} + +/*! @abstract Extends `other` to form a vector of two 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC long2 make_long2_undef(typeN other) { + return ::simd_make_long2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long3 make_long3(long1 x, long1 y, long1 z) { + return ::simd_make_long3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long3 make_long3(long1 x, long2 yz) { + return ::simd_make_long3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long3 make_long3(long2 xy, long1 z) { + return ::simd_make_long3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 64-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC long3 make_long3(typeN other) { + return ::simd_make_long3(other); +} + +/*! @abstract Extends `other` to form a vector of three 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC long3 make_long3_undef(typeN other) { + return ::simd_make_long3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 64-bit signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long1 x, long1 y, long1 z, long1 w) { + return ::simd_make_long4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long1 x, long1 y, long2 zw) { + return ::simd_make_long4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long1 x, long2 yz, long1 w) { + return ::simd_make_long4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long2 xy, long1 z, long1 w) { + return ::simd_make_long4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long1 x, long3 yzw) { + return ::simd_make_long4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long2 xy, long2 zw) { + return ::simd_make_long4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long4 make_long4(long3 xyz, long1 w) { + return ::simd_make_long4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 64-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC long4 make_long4(typeN other) { + return ::simd_make_long4(other); +} + +/*! @abstract Extends `other` to form a vector of four 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC long4 make_long4_undef(typeN other) { + return ::simd_make_long4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 64-bit + * signed (twos-complement) integers. */ +static inline SIMD_CPPFUNC long8 make_long8(long4 lo, long4 hi) { + return ::simd_make_long8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 64-bit signed (twos-complement) integers. */ +template static SIMD_CPPFUNC long8 make_long8(typeN other) { + return ::simd_make_long8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit signed (twos- + * complement) integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC long8 make_long8_undef(typeN other) { + return ::simd_make_long8_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong2 make_ulong2(ulong1 x, ulong1 y) { + return ::simd_make_ulong2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 64-bit unsigned integers. */ +template static SIMD_CPPFUNC ulong2 make_ulong2(typeN other) { + return ::simd_make_ulong2(other); +} + +/*! @abstract Extends `other` to form a vector of two 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ulong2 make_ulong2_undef(typeN other) { + return ::simd_make_ulong2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong3 make_ulong3(ulong1 x, ulong1 y, ulong1 z) { + return ::simd_make_ulong3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong3 make_ulong3(ulong1 x, ulong2 yz) { + return ::simd_make_ulong3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong3 make_ulong3(ulong2 xy, ulong1 z) { + return ::simd_make_ulong3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 64-bit unsigned integers. */ +template static SIMD_CPPFUNC ulong3 make_ulong3(typeN other) { + return ::simd_make_ulong3(other); +} + +/*! @abstract Extends `other` to form a vector of three 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ulong3 make_ulong3_undef(typeN other) { + return ::simd_make_ulong3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 64-bit unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong1 x, ulong1 y, ulong1 z, ulong1 w) { + return ::simd_make_ulong4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong1 x, ulong1 y, ulong2 zw) { + return ::simd_make_ulong4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong1 x, ulong2 yz, ulong1 w) { + return ::simd_make_ulong4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong2 xy, ulong1 z, ulong1 w) { + return ::simd_make_ulong4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong1 x, ulong3 yzw) { + return ::simd_make_ulong4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong2 xy, ulong2 zw) { + return ::simd_make_ulong4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong4 make_ulong4(ulong3 xyz, ulong1 w) { + return ::simd_make_ulong4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 64-bit unsigned integers. */ +template static SIMD_CPPFUNC ulong4 make_ulong4(typeN other) { + return ::simd_make_ulong4(other); +} + +/*! @abstract Extends `other` to form a vector of four 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ulong4 make_ulong4_undef(typeN other) { + return ::simd_make_ulong4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 64-bit + * unsigned integers. */ +static inline SIMD_CPPFUNC ulong8 make_ulong8(ulong4 lo, ulong4 hi) { + return ::simd_make_ulong8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 64-bit unsigned integers. */ +template static SIMD_CPPFUNC ulong8 make_ulong8(typeN other) { + return ::simd_make_ulong8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit unsigned + * integers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC ulong8 make_ulong8_undef(typeN other) { + return ::simd_make_ulong8_undef(other); +} + +/*! @abstract Concatenates `x` and `y` to form a vector of two 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double2 make_double2(double x, double y) { + return ::simd_make_double2(x, y); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of two + * 64-bit floating-point numbers. */ +template static SIMD_CPPFUNC double2 make_double2(typeN other) { + return ::simd_make_double2(other); +} + +/*! @abstract Extends `other` to form a vector of two 64-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +template static SIMD_CPPFUNC double2 make_double2_undef(typeN other) { + return ::simd_make_double2_undef(other); +} + +/*! @abstract Concatenates `x`, `y` and `z` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double3 make_double3(double x, double y, double z) { + return ::simd_make_double3(x, y, z); +} + +/*! @abstract Concatenates `x` and `yz` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double3 make_double3(double x, double2 yz) { + return ::simd_make_double3(x, yz); +} + +/*! @abstract Concatenates `xy` and `z` to form a vector of three 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double3 make_double3(double2 xy, double z) { + return ::simd_make_double3(xy, z); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of three + * 64-bit floating-point numbers. */ +template static SIMD_CPPFUNC double3 make_double3(typeN other) { + return ::simd_make_double3(other); +} + +/*! @abstract Extends `other` to form a vector of three 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC double3 make_double3_undef(typeN other) { + return ::simd_make_double3_undef(other); +} + +/*! @abstract Concatenates `x`, `y`, `z` and `w` to form a vector of four + * 64-bit floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double x, double y, double z, double w) { + return ::simd_make_double4(x, y, z, w); +} + +/*! @abstract Concatenates `x`, `y` and `zw` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double x, double y, double2 zw) { + return ::simd_make_double4(x, y, zw); +} + +/*! @abstract Concatenates `x`, `yz` and `w` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double x, double2 yz, double w) { + return ::simd_make_double4(x, yz, w); +} + +/*! @abstract Concatenates `xy`, `z` and `w` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double2 xy, double z, double w) { + return ::simd_make_double4(xy, z, w); +} + +/*! @abstract Concatenates `x` and `yzw` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double x, double3 yzw) { + return ::simd_make_double4(x, yzw); +} + +/*! @abstract Concatenates `xy` and `zw` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double2 xy, double2 zw) { + return ::simd_make_double4(xy, zw); +} + +/*! @abstract Concatenates `xyz` and `w` to form a vector of four 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double4 make_double4(double3 xyz, double w) { + return ::simd_make_double4(xyz, w); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of four + * 64-bit floating-point numbers. */ +template static SIMD_CPPFUNC double4 make_double4(typeN other) { + return ::simd_make_double4(other); +} + +/*! @abstract Extends `other` to form a vector of four 64-bit floating-point + * numbers. The contents of the newly-created vector lanes are unspecified. */ +template static SIMD_CPPFUNC double4 make_double4_undef(typeN other) { + return ::simd_make_double4_undef(other); +} + +/*! @abstract Concatenates `lo` and `hi` to form a vector of eight 64-bit + * floating-point numbers. */ +static inline SIMD_CPPFUNC double8 make_double8(double4 lo, double4 hi) { + return ::simd_make_double8(lo, hi); +} + +/*! @abstract Truncates or zero-extends `other` to form a vector of eight + * 64-bit floating-point numbers. */ +template static SIMD_CPPFUNC double8 make_double8(typeN other) { + return ::simd_make_double8(other); +} + +/*! @abstract Extends `other` to form a vector of eight 64-bit floating- + * point numbers. The contents of the newly-created vector lanes are + * unspecified. */ +template static SIMD_CPPFUNC double8 make_double8_undef(typeN other) { + return ::simd_make_double8_undef(other); +} + +} /* namespace simd */ +#endif /* __cplusplus */ +#endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ +#endif /* SIMD_VECTOR_CONSTRUCTORS */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/stdio.h b/lib/libc/include/any-macos.11-any/stdio.h new file mode 100644 index 0000000000..f28020b797 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/stdio.h @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2000, 2005, 2007, 2009, 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)stdio.h 8.5 (Berkeley) 4/29/95 + */ + +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#include <_stdio.h> + +__BEGIN_DECLS +extern FILE *__stdinp; +extern FILE *__stdoutp; +extern FILE *__stderrp; +__END_DECLS + +#define __SLBF 0x0001 /* line buffered */ +#define __SNBF 0x0002 /* unbuffered */ +#define __SRD 0x0004 /* OK to read */ +#define __SWR 0x0008 /* OK to write */ + /* RD and WR are never simultaneously asserted */ +#define __SRW 0x0010 /* open for reading & writing */ +#define __SEOF 0x0020 /* found EOF */ +#define __SERR 0x0040 /* found error */ +#define __SMBF 0x0080 /* _buf is from malloc */ +#define __SAPP 0x0100 /* fdopen()ed in append mode */ +#define __SSTR 0x0200 /* this is an sprintf/snprintf string */ +#define __SOPT 0x0400 /* do fseek() optimisation */ +#define __SNPT 0x0800 /* do not do fseek() optimisation */ +#define __SOFF 0x1000 /* set iff _offset is in fact correct */ +#define __SMOD 0x2000 /* true => fgetln modified _p text */ +#define __SALC 0x4000 /* allocate string space dynamically */ +#define __SIGN 0x8000 /* ignore this file in _fwalk */ + +/* + * The following three definitions are for ANSI C, which took them + * from System V, which brilliantly took internal interface macros and + * made them official arguments to setvbuf(), without renaming them. + * Hence, these ugly _IOxxx names are *supposed* to appear in user code. + * + * Although numbered as their counterparts above, the implementation + * does not rely on this. + */ +#define _IOFBF 0 /* setvbuf should set fully buffered */ +#define _IOLBF 1 /* setvbuf should set line buffered */ +#define _IONBF 2 /* setvbuf should set unbuffered */ + +#define BUFSIZ 1024 /* size of buffer used by setbuf */ +#define EOF (-1) + + /* must be == _POSIX_STREAM_MAX */ +#define FOPEN_MAX 20 /* must be <= OPEN_MAX */ +#define FILENAME_MAX 1024 /* must be <= PATH_MAX */ + +/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ +#ifndef _ANSI_SOURCE +#define P_tmpdir "/var/tmp/" +#endif +#define L_tmpnam 1024 /* XXX must be == PATH_MAX */ +#define TMP_MAX 308915776 + +#ifndef SEEK_SET +#define SEEK_SET 0 /* set file offset to offset */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* set file offset to current plus offset */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* set file offset to EOF plus offset */ +#endif + +#define stdin __stdinp +#define stdout __stdoutp +#define stderr __stderrp + +#ifdef _DARWIN_UNLIMITED_STREAMS +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 +#error "_DARWIN_UNLIMITED_STREAMS specified, but -miphoneos-version-min version does not support it." +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 +#error "_DARWIN_UNLIMITED_STREAMS specified, but -mmacosx-version-min version does not support it." +#endif +#endif + +/* ANSI-C */ + +__BEGIN_DECLS +void clearerr(FILE *); +int fclose(FILE *); +int feof(FILE *); +int ferror(FILE *); +int fflush(FILE *); +int fgetc(FILE *); +int fgetpos(FILE * __restrict, fpos_t *); +char *fgets(char * __restrict, int, FILE *); +#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) +FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fopen)); +#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ +FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen)); +#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ +int fprintf(FILE * __restrict, const char * __restrict, ...) __printflike(2, 3); +int fputc(int, FILE *); +int fputs(const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(fputs); +size_t fread(void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream); +FILE *freopen(const char * __restrict, const char * __restrict, + FILE * __restrict) __DARWIN_ALIAS(freopen); +int fscanf(FILE * __restrict, const char * __restrict, ...) __scanflike(2, 3); +int fseek(FILE *, long, int); +int fsetpos(FILE *, const fpos_t *); +long ftell(FILE *); +size_t fwrite(const void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream) __DARWIN_ALIAS(fwrite); +int getc(FILE *); +int getchar(void); +char *gets(char *); +void perror(const char *) __cold; +int printf(const char * __restrict, ...) __printflike(1, 2); +int putc(int, FILE *); +int putchar(int); +int puts(const char *); +int remove(const char *); +int rename (const char *__old, const char *__new); +void rewind(FILE *); +int scanf(const char * __restrict, ...) __scanflike(1, 2); +void setbuf(FILE * __restrict, char * __restrict); +int setvbuf(FILE * __restrict, char * __restrict, int, size_t); +int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3) __swift_unavailable("Use snprintf instead."); +int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3); +FILE *tmpfile(void); + +__swift_unavailable("Use mkstemp(3) instead.") +#if !defined(_POSIX_C_SOURCE) +__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.") +#endif +char *tmpnam(char *); +int ungetc(int, FILE *); +int vfprintf(FILE * __restrict, const char * __restrict, va_list) __printflike(2, 0); +int vprintf(const char * __restrict, va_list) __printflike(1, 0); +int vsprintf(char * __restrict, const char * __restrict, va_list) __printflike(2, 0) __swift_unavailable("Use vsnprintf instead."); +__END_DECLS + + + +/* Additional functionality provided by: + * POSIX.1-1988 + */ + +#if __DARWIN_C_LEVEL >= 198808L +#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */ + +__BEGIN_DECLS +#include <_ctermid.h> + +#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) +FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fdopen)); +#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ +FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fdopen)); +#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ +int fileno(FILE *); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 198808L */ + + +/* Additional functionality provided by: + * POSIX.2-1992 C Language Binding Option + */ +#if TARGET_OS_IPHONE +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg) +#else +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg) +#endif + +#if __DARWIN_C_LEVEL >= 199209L +__BEGIN_DECLS +int pclose(FILE *) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); +#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) +FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); +#else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ +FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); +#endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199209L */ + +#undef __swift_unavailable_on + +/* Additional functionality provided by: + * POSIX.1c-1995, + * POSIX.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + */ + +#if __DARWIN_C_LEVEL >= 199506L + +/* Functions internal to the implementation. */ +__BEGIN_DECLS +int __srget(FILE *); +int __svfscanf(FILE *, const char *, va_list) __scanflike(2, 0); +int __swbuf(int, FILE *); +__END_DECLS + +/* + * The __sfoo macros are here so that we can + * define function versions in the C library. + */ +#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) +#if defined(__GNUC__) && defined(__STDC__) +__header_always_inline int __sputc(int _c, FILE *_p) { + if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) + return (*_p->_p++ = _c); + else + return (__swbuf(_c, _p)); +} +#else +/* + * This has been tuned to generate reasonable code on the vax using pcc. + */ +#define __sputc(c, p) \ + (--(p)->_w < 0 ? \ + (p)->_w >= (p)->_lbfsize ? \ + (*(p)->_p = (c)), *(p)->_p != '\n' ? \ + (int)*(p)->_p++ : \ + __swbuf('\n', p) : \ + __swbuf((int)(c), p) : \ + (*(p)->_p = (c), (int)*(p)->_p++)) +#endif + +#define __sfeof(p) (((p)->_flags & __SEOF) != 0) +#define __sferror(p) (((p)->_flags & __SERR) != 0) +#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) +#define __sfileno(p) ((p)->_file) + +__BEGIN_DECLS +void flockfile(FILE *); +int ftrylockfile(FILE *); +void funlockfile(FILE *); +int getc_unlocked(FILE *); +int getchar_unlocked(void); +int putc_unlocked(int, FILE *); +int putchar_unlocked(int); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +int getw(FILE *); +int putw(int, FILE *); +#endif + +__swift_unavailable("Use mkstemp(3) instead.") +#if !defined(_POSIX_C_SOURCE) +__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.") +#endif +char *tempnam(const char *__dir, const char *__prefix) __DARWIN_ALIAS(tempnam); +__END_DECLS + +#ifndef lint +#define getc_unlocked(fp) __sgetc(fp) +#define putc_unlocked(x, fp) __sputc(x, fp) +#endif /* lint */ + +#define getchar_unlocked() getc_unlocked(stdin) +#define putchar_unlocked(x) putc_unlocked(x, stdout) +#endif /* __DARWIN_C_LEVEL >= 199506L */ + + + +/* Additional functionality provided by: + * POSIX.1-2001 + * ISO C99 + */ + +#if __DARWIN_C_LEVEL >= 200112L +#include + +__BEGIN_DECLS +int fseeko(FILE * __stream, off_t __offset, int __whence); +off_t ftello(FILE * __stream); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) +__BEGIN_DECLS +int snprintf(char * __restrict __str, size_t __size, const char * __restrict __format, ...) __printflike(3, 4); +int vfscanf(FILE * __restrict __stream, const char * __restrict __format, va_list) __scanflike(2, 0); +int vscanf(const char * __restrict __format, va_list) __scanflike(1, 0); +int vsnprintf(char * __restrict __str, size_t __size, const char * __restrict __format, va_list) __printflike(3, 0); +int vsscanf(const char * __restrict __str, const char * __restrict __format, va_list) __scanflike(2, 0); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) */ + + + +/* Additional functionality provided by: + * POSIX.1-2008 + */ + +#if __DARWIN_C_LEVEL >= 200809L +#include + +__BEGIN_DECLS +int dprintf(int, const char * __restrict, ...) __printflike(2, 3) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +int vdprintf(int, const char * __restrict, va_list) __printflike(2, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +ssize_t getdelim(char ** __restrict __linep, size_t * __restrict __linecapp, int __delimiter, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +FILE *fmemopen(void * __restrict __buf, size_t __size, const char * __restrict __mode) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); +FILE *open_memstream(char **__bufp, size_t *__sizep) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200809L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +__BEGIN_DECLS +extern __const int sys_nerr; /* perror(3) external variables */ +extern __const char *__const sys_errlist[]; + +int asprintf(char ** __restrict, const char * __restrict, ...) __printflike(2, 3); +char *ctermid_r(char *); +char *fgetln(FILE *, size_t *); +__const char *fmtcheck(const char *, const char *); +int fpurge(FILE *); +void setbuffer(FILE *, char *, int); +int setlinebuf(FILE *); +int vasprintf(char ** __restrict, const char * __restrict, va_list) __printflike(2, 0); +FILE *zopen(const char *, const char *, int); + + +/* + * Stdio function-access interface. + */ +FILE *funopen(const void *, + int (* _Nullable)(void *, char *, int), + int (* _Nullable)(void *, const char *, int), + fpos_t (* _Nullable)(void *, fpos_t, int), + int (* _Nullable)(void *)); +__END_DECLS +#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) +#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) + +#define feof_unlocked(p) __sfeof(p) +#define ferror_unlocked(p) __sferror(p) +#define clearerr_unlocked(p) __sclearerr(p) +#define fileno_unlocked(p) __sfileno(p) + +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + +#ifdef _USE_EXTENDED_LOCALES_ +#include +#endif /* _USE_EXTENDED_LOCALES_ */ + +#if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus) +/* Security checking functions. */ +#include +#endif + +#endif /* _STDIO_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/stdlib.h b/lib/libc/include/any-macos.11-any/stdlib.h new file mode 100644 index 0000000000..699d3e85c2 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/stdlib.h @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2000, 2002 - 2008 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)stdlib.h 8.5 (Berkeley) 5/19/95 + */ + +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +#include +#include + +#include <_types.h> +#if !defined(_ANSI_SOURCE) +#include +#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +#include +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#endif /* !_ANSI_SOURCE */ + +/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: + * _GCC_SIZE_T */ +#include + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +#include +#include +#endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +#include + +typedef struct { + int quot; /* quotient */ + int rem; /* remainder */ +} div_t; + +typedef struct { + long quot; /* quotient */ + long rem; /* remainder */ +} ldiv_t; + +#if !__DARWIN_NO_LONG_LONG +typedef struct { + long long quot; + long long rem; +} lldiv_t; +#endif /* !__DARWIN_NO_LONG_LONG */ + +#include + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +#define RAND_MAX 0x7fffffff + +#ifdef _USE_EXTENDED_LOCALES_ +#include <_xlocale.h> +#endif /* _USE_EXTENDED_LOCALES_ */ + +#ifndef MB_CUR_MAX +#ifdef _USE_EXTENDED_LOCALES_ +#define MB_CUR_MAX (___mb_cur_max()) +#ifndef MB_CUR_MAX_L +#define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) +#endif /* !MB_CUR_MAX_L */ +#else /* !_USE_EXTENDED_LOCALES_ */ +extern int __mb_cur_max; +#define MB_CUR_MAX __mb_cur_max +#endif /* _USE_EXTENDED_LOCALES_ */ +#endif /* MB_CUR_MAX */ + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) \ + && defined(_USE_EXTENDED_LOCALES_) && !defined(MB_CUR_MAX_L) +#define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) +#endif + +#include + +__BEGIN_DECLS +void abort(void) __cold __dead2; +int abs(int) __pure2; +int atexit(void (* _Nonnull)(void)); +double atof(const char *); +int atoi(const char *); +long atol(const char *); +#if !__DARWIN_NO_LONG_LONG +long long + atoll(const char *); +#endif /* !__DARWIN_NO_LONG_LONG */ +void *bsearch(const void *__key, const void *__base, size_t __nel, + size_t __width, int (* _Nonnull __compar)(const void *, const void *)); +/* calloc is now declared in _malloc.h */ +div_t div(int, int) __pure2; +void exit(int) __dead2; +/* free is now declared in _malloc.h */ +char *getenv(const char *); +long labs(long) __pure2; +ldiv_t ldiv(long, long) __pure2; +#if !__DARWIN_NO_LONG_LONG +long long + llabs(long long); +lldiv_t lldiv(long long, long long); +#endif /* !__DARWIN_NO_LONG_LONG */ +/* malloc is now declared in _malloc.h */ +int mblen(const char *__s, size_t __n); +size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); +int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); +/* posix_memalign is now declared in _malloc.h */ +void qsort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)); +int rand(void) __swift_unavailable("Use arc4random instead."); +/* realloc is now declared in _malloc.h */ +void srand(unsigned) __swift_unavailable("Use arc4random instead."); +double strtod(const char *, char **) __DARWIN_ALIAS(strtod); +float strtof(const char *, char **) __DARWIN_ALIAS(strtof); +long strtol(const char *__str, char **__endptr, int __base); +long double + strtold(const char *, char **); +#if !__DARWIN_NO_LONG_LONG +long long + strtoll(const char *__str, char **__endptr, int __base); +#endif /* !__DARWIN_NO_LONG_LONG */ +unsigned long + strtoul(const char *__str, char **__endptr, int __base); +#if !__DARWIN_NO_LONG_LONG +unsigned long long + strtoull(const char *__str, char **__endptr, int __base); +#endif /* !__DARWIN_NO_LONG_LONG */ + +#if TARGET_OS_IPHONE +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg) +#else +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg) +#endif + +__swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable") +__API_AVAILABLE(macos(10.0)) __IOS_PROHIBITED +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +int system(const char *) __DARWIN_ALIAS_C(system); + +#undef __swift_unavailable_on + +size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); +int wctomb(char *, wchar_t); + +#ifndef _ANSI_SOURCE +void _Exit(int) __dead2; +long a64l(const char *); +double drand48(void); +char *ecvt(double, int, int *__restrict, int *__restrict); /* LEGACY */ +double erand48(unsigned short[3]); +char *fcvt(double, int, int *__restrict, int *__restrict); /* LEGACY */ +char *gcvt(double, int, char *); /* LEGACY */ +int getsubopt(char **, char * const *, char **); +int grantpt(int); +#if __DARWIN_UNIX03 +char *initstate(unsigned, char *, size_t); /* no __DARWIN_ALIAS needed */ +#else /* !__DARWIN_UNIX03 */ +char *initstate(unsigned long, char *, long); +#endif /* __DARWIN_UNIX03 */ +long jrand48(unsigned short[3]) __swift_unavailable("Use arc4random instead."); +char *l64a(long); +void lcong48(unsigned short[7]); +long lrand48(void) __swift_unavailable("Use arc4random instead."); +char *mktemp(char *); +int mkstemp(char *); +long mrand48(void) __swift_unavailable("Use arc4random instead."); +long nrand48(unsigned short[3]) __swift_unavailable("Use arc4random instead."); +int posix_openpt(int); +char *ptsname(int); + +#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +int ptsname_r(int fildes, char *buffer, size_t buflen) __API_AVAILABLE(macos(10.13.4), ios(11.3), tvos(11.3), watchos(4.3)); +#endif + +int putenv(char *) __DARWIN_ALIAS(putenv); +long random(void) __swift_unavailable("Use arc4random instead."); +int rand_r(unsigned *) __swift_unavailable("Use arc4random instead."); +#if (__DARWIN_UNIX03 && !defined(_POSIX_C_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(_DARWIN_BETTER_REALPATH) +char *realpath(const char * __restrict, char * __restrict) __DARWIN_EXTSN(realpath); +#else /* (!__DARWIN_UNIX03 || _POSIX_C_SOURCE) && !_DARWIN_C_SOURCE && !_DARWIN_BETTER_REALPATH */ +char *realpath(const char * __restrict, char * __restrict) __DARWIN_ALIAS(realpath); +#endif /* (__DARWIN_UNIX03 && _POSIX_C_SOURCE) || _DARWIN_C_SOURCE || _DARWIN_BETTER_REALPATH */ +unsigned short + *seed48(unsigned short[3]); +int setenv(const char * __name, const char * __value, int __overwrite) __DARWIN_ALIAS(setenv); +#if __DARWIN_UNIX03 +void setkey(const char *) __DARWIN_ALIAS(setkey); +#else /* !__DARWIN_UNIX03 */ +int setkey(const char *); +#endif /* __DARWIN_UNIX03 */ +char *setstate(const char *); +void srand48(long); +#if __DARWIN_UNIX03 +void srandom(unsigned); +#else /* !__DARWIN_UNIX03 */ +void srandom(unsigned long); +#endif /* __DARWIN_UNIX03 */ +int unlockpt(int); +#if __DARWIN_UNIX03 +int unsetenv(const char *) __DARWIN_ALIAS(unsetenv); +#else /* !__DARWIN_UNIX03 */ +void unsetenv(const char *); +#endif /* __DARWIN_UNIX03 */ +#endif /* !_ANSI_SOURCE */ + +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +#include +#include +#include +#include <_types/_uint32_t.h> + +uint32_t arc4random(void); +void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/) + __OSX_DEPRECATED(10.0, 10.12, "use arc4random_stir") + __IOS_DEPRECATED(2.0, 10.0, "use arc4random_stir") + __TVOS_DEPRECATED(2.0, 10.0, "use arc4random_stir") + __WATCHOS_DEPRECATED(1.0, 3.0, "use arc4random_stir"); +void arc4random_buf(void * __buf, size_t __nbytes) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +void arc4random_stir(void); +uint32_t + arc4random_uniform(uint32_t __upper_bound) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +#ifdef __BLOCKS__ +int atexit_b(void (^ _Nonnull)(void)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void *bsearch_b(const void *__key, const void *__base, size_t __nel, + size_t __width, int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ + + /* getcap(3) functions */ +char *cgetcap(char *, const char *, int); +int cgetclose(void); +int cgetent(char **, char **, const char *); +int cgetfirst(char **, char **); +int cgetmatch(const char *, const char *); +int cgetnext(char **, char **); +int cgetnum(char *, const char *, long *); +int cgetset(const char *); +int cgetstr(char *, const char *, char **); +int cgetustr(char *, const char *, char **); + +int daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0, "Use posix_spawn APIs instead.") __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +char *devname(dev_t, mode_t); +char *devname_r(dev_t, mode_t, char *buf, int len); +char *getbsize(int *, long *); +int getloadavg(double [], int); +const char + *getprogname(void); +void setprogname(const char *); + +#ifdef __BLOCKS__ +#if __has_attribute(noescape) +#define __sort_noescape __attribute__((__noescape__)) +#else +#define __sort_noescape +#endif +#endif /* __BLOCKS__ */ + +int heapsort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)); +#ifdef __BLOCKS__ +int heapsort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) + __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ +int mergesort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)); +#ifdef __BLOCKS__ +int mergesort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) + __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ +void psort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)) + __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#ifdef __BLOCKS__ +void psort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) + __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ +void psort_r(void *__base, size_t __nel, size_t __width, void *, + int (* _Nonnull __compar)(void *, const void *, const void *)) + __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#ifdef __BLOCKS__ +void qsort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape) + __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +#endif /* __BLOCKS__ */ +void qsort_r(void *__base, size_t __nel, size_t __width, void *, + int (* _Nonnull __compar)(void *, const void *, const void *)); +int radixsort(const unsigned char **__base, int __nel, const unsigned char *__table, + unsigned __endbyte); +int rpmatch(const char *) + __API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0)); +int sradixsort(const unsigned char **__base, int __nel, const unsigned char *__table, + unsigned __endbyte); +void sranddev(void); +void srandomdev(void); +void *reallocf(void *__ptr, size_t __size) __alloc_size(2); +long long + strtonum(const char *__numstr, long long __minval, long long __maxval, const char **__errstrp) + __API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)); +#if !__DARWIN_NO_LONG_LONG +long long + strtoq(const char *__str, char **__endptr, int __base); +unsigned long long + strtouq(const char *__str, char **__endptr, int __base); +#endif /* !__DARWIN_NO_LONG_LONG */ +extern char *suboptarg; /* getsubopt(3) external variable */ +/* valloc is now declared in _malloc.h */ +#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ + +/* Poison the following routines if -fshort-wchar is set */ +#if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU +#pragma GCC poison mbstowcs mbtowc wcstombs wctomb +#endif +__END_DECLS + +#ifdef _USE_EXTENDED_LOCALES_ +#include +#endif /* _USE_EXTENDED_LOCALES_ */ + +#endif /* _STDLIB_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/_symbol_aliasing.h b/lib/libc/include/any-macos.11-any/sys/_symbol_aliasing.h index 05722c3576..7cb1a8c002 100644 --- a/lib/libc/include/any-macos.11-any/sys/_symbol_aliasing.h +++ b/lib/libc/include/any-macos.11-any/sys/_symbol_aliasing.h @@ -341,24 +341,6 @@ #define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_14_5(x) #endif -#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 150000 -#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_15_0(x) x -#else -#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_15_0(x) -#endif - -#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 150100 -#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_15_1(x) x -#else -#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_15_1(x) -#endif - -#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 150200 -#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_15_2(x) x -#else -#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_15_2(x) -#endif - #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1000 #define __DARWIN_ALIAS_STARTING_MAC___MAC_10_0(x) x #else @@ -573,16 +555,4 @@ #define __DARWIN_ALIAS_STARTING_MAC___MAC_11_3(x) x #else #define __DARWIN_ALIAS_STARTING_MAC___MAC_11_3(x) -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 120000 -#define __DARWIN_ALIAS_STARTING_MAC___MAC_12_0(x) x -#else -#define __DARWIN_ALIAS_STARTING_MAC___MAC_12_0(x) -#endif - -#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 120100 -#define __DARWIN_ALIAS_STARTING_MAC___MAC_12_1(x) x -#else -#define __DARWIN_ALIAS_STARTING_MAC___MAC_12_1(x) #endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/_types/_uintptr_t.h b/lib/libc/include/any-macos.11-any/sys/_types/_uintptr_t.h new file mode 100644 index 0000000000..7971dbc86a --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/_types/_uintptr_t.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2003-2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef _UINTPTR_T +#define _UINTPTR_T +typedef unsigned long uintptr_t; +#endif /* _UINTPTR_T */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/attr.h b/lib/libc/include/any-macos.11-any/sys/attr.h index 4e317dd547..9eca5efb34 100644 --- a/lib/libc/include/any-macos.11-any/sys/attr.h +++ b/lib/libc/include/any-macos.11-any/sys/attr.h @@ -83,7 +83,6 @@ struct attrlist { attrgroup_t fileattr; /* file attribute group */ attrgroup_t forkattr; /* fork attribute group */ }; - #define ATTR_BIT_MAP_COUNT 5 typedef struct attribute_set { @@ -94,9 +93,6 @@ typedef struct attribute_set { attrgroup_t forkattr; /* fork attribute group */ } attribute_set_t; -#define ATTRIBUTE_SET_INIT(a) do {(a)->commonattr = (a)->volattr = (a)->dirattr = (a)->fileattr = (a)->forkattr = 0; } while(0) - - typedef struct attrreference { int32_t attr_dataoffset; u_int32_t attr_length; @@ -467,13 +463,12 @@ typedef struct vol_attributes_attr { #define ATTR_VOL_ENCODINGSUSED 0x00010000 #define ATTR_VOL_CAPABILITIES 0x00020000 #define ATTR_VOL_UUID 0x00040000 -#define ATTR_VOL_SPACEUSED 0x00800000 #define ATTR_VOL_QUOTA_SIZE 0x10000000 #define ATTR_VOL_RESERVED_SIZE 0x20000000 #define ATTR_VOL_ATTRIBUTES 0x40000000 #define ATTR_VOL_INFO 0x80000000 -#define ATTR_VOL_VALIDMASK 0xF087FFFF +#define ATTR_VOL_VALIDMASK 0xF007FFFF /* * The list of settable ATTR_VOL_* attributes include the following: diff --git a/lib/libc/include/any-macos.11-any/sys/cdefs.h b/lib/libc/include/any-macos.11-any/sys/cdefs.h index 7108b92160..e8145978d4 100644 --- a/lib/libc/include/any-macos.11-any/sys/cdefs.h +++ b/lib/libc/include/any-macos.11-any/sys/cdefs.h @@ -152,16 +152,8 @@ #endif /* !NO_ANSI_KEYWORDS */ #endif /* !(__STDC__ || __cplusplus) */ -/* - * __pure2 can be used for functions that are only a function of their scalar - * arguments (meaning they can't dereference pointers). - * - * __stateful_pure can be used for functions that have no side effects, - * but depend on the state of the memory. - */ #define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) -#define __stateful_pure __attribute__((__pure__)) /* __unused denotes variables and functions that may not be used, preventing * the compiler from warning about it if not used. @@ -187,9 +179,9 @@ * __exported_push/_exported_pop are pragmas used to delimit a range of * symbols that should be exported even when symbols are hidden by default. */ -#define __exported __attribute__((__visibility__("default"))) -#define __exported_push _Pragma("GCC visibility push(default)") -#define __exported_pop _Pragma("GCC visibility pop") +#define __exported __attribute__((__visibility__("default"))) +#define __exported_push _Pragma("GCC visibility push(default)") +#define __exported_pop _Pragma("GCC visibility pop") /* __deprecated causes the compiler to produce a warning when encountering * code using the deprecated functionality. @@ -825,7 +817,6 @@ #define __XNU_PRIVATE_EXTERN __attribute__((visibility("hidden"))) #endif - /* * Architecture validation for current SDK */ @@ -882,11 +873,4 @@ typedef _type _name; enum __VA_ARGS__ __enum_closed __enum_options #endif - - -#define __kernel_ptr_semantics -#define __kernel_data_semantics -#define __kernel_dual_semantics - - #endif /* !_CDEFS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/event.h b/lib/libc/include/any-macos.11-any/sys/event.h index 2731bd520f..b03d37f867 100644 --- a/lib/libc/include/any-macos.11-any/sys/event.h +++ b/lib/libc/include/any-macos.11-any/sys/event.h @@ -58,9 +58,7 @@ #include #include -#include #include -#include /* * Filter types @@ -368,10 +366,13 @@ enum { /* Temporay solution for BootX to use inode.h till kqueue moves to vfs layer */ +#include struct knote; SLIST_HEAD(klist, knote); +#include + struct timespec; __BEGIN_DECLS diff --git a/lib/libc/include/any-macos.11-any/sys/fcntl.h b/lib/libc/include/any-macos.11-any/sys/fcntl.h index 7a6addbfd2..8f13a01f90 100644 --- a/lib/libc/include/any-macos.11-any/sys/fcntl.h +++ b/lib/libc/include/any-macos.11-any/sys/fcntl.h @@ -134,11 +134,8 @@ #define O_NOCTTY 0x00020000 /* don't assign controlling terminal */ -#if __DARWIN_C_LEVEL >= 200809L -#define O_DIRECTORY 0x00100000 -#endif - #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define O_DIRECTORY 0x00100000 #define O_SYMLINK 0x00200000 /* allow open of a symlink */ #endif @@ -259,13 +256,7 @@ #define F_LOG2PHYS_EXT 65 /* file offset to device offset, extended */ -#define F_GETLKPID 66 /* See man fcntl(2) F_GETLK - * Similar to F_GETLK but in addition l_pid is treated as an input parameter - * which is used as a matching value when searching locks on the file - * so that only locks owned by the process with pid l_pid are returned. - * However, any flock(2) type lock will also be found with the returned value - * of l_pid set to -1 (as with F_GETLK). - */ +#define F_GETLKPID 66 /* get record locking information, per-process */ /* See F_DUPFD_CLOEXEC below for 67 */ diff --git a/lib/libc/include/any-macos.11-any/sys/ioctl.h b/lib/libc/include/any-macos.11-any/sys/ioctl.h new file mode 100644 index 0000000000..bb84842dd2 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/ioctl.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ioctl.h 8.6 (Berkeley) 3/28/94 + */ + +#ifndef _SYS_IOCTL_H_ +#define _SYS_IOCTL_H_ + +#include + +/* + * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ + * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented + * nonwithstanding). + */ +struct ttysize { + unsigned short ts_lines; + unsigned short ts_cols; + unsigned short ts_xxx; + unsigned short ts_yyy; +}; +#define TIOCGSIZE TIOCGWINSZ +#define TIOCSSIZE TIOCSWINSZ + +#include + +#include +#include + + +#include + +__BEGIN_DECLS +int ioctl(int, unsigned long, ...); +__END_DECLS +#endif /* !_SYS_IOCTL_H_ */ + +/* + * Keep outside _SYS_IOCTL_H_ + * Compatability with old terminal driver + * + * Source level -> #define USE_OLD_TTY + * Kernel level -> always on + */ +#if defined(USE_OLD_TTY) || defined(BSD_KERNEL_PRIVATE) +#include +#endif /* !_SYS_IOCTL_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/mount.h b/lib/libc/include/any-macos.11-any/sys/mount.h index 4dfdb397e5..85a8347ddf 100644 --- a/lib/libc/include/any-macos.11-any/sys/mount.h +++ b/lib/libc/include/any-macos.11-any/sys/mount.h @@ -388,6 +388,7 @@ struct netfs_status { + /* * Generic file handle */ @@ -402,7 +403,6 @@ struct fhandle { typedef struct fhandle fhandle_t; - __BEGIN_DECLS int fhopen(const struct fhandle *, int); int fstatfs(int, struct statfs *) __DARWIN_INODE64(fstatfs); diff --git a/lib/libc/include/any-macos.11-any/sys/proc_info.h b/lib/libc/include/any-macos.11-any/sys/proc_info.h index 8ad05f361e..8c6b668afb 100644 --- a/lib/libc/include/any-macos.11-any/sys/proc_info.h +++ b/lib/libc/include/any-macos.11-any/sys/proc_info.h @@ -620,11 +620,12 @@ struct kqueue_dyninfo { }; /* keep in sync with KQ_* in sys/eventvar.h */ -#define PROC_KQUEUE_SELECT 0x0001 -#define PROC_KQUEUE_SLEEP 0x0002 -#define PROC_KQUEUE_32 0x0008 -#define PROC_KQUEUE_64 0x0010 -#define PROC_KQUEUE_QOS 0x0020 +#define PROC_KQUEUE_SELECT 0x01 +#define PROC_KQUEUE_SLEEP 0x02 +#define PROC_KQUEUE_32 0x08 +#define PROC_KQUEUE_64 0x10 +#define PROC_KQUEUE_QOS 0x20 + struct kqueue_fdinfo { struct proc_fileinfo pfi; diff --git a/lib/libc/include/any-macos.11-any/sys/random.h b/lib/libc/include/any-macos.11-any/sys/random.h new file mode 100644 index 0000000000..4599da090b --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/random.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1999, 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef __SYS_RANDOM_H__ +#define __SYS_RANDOM_H__ + +#include +#include + +__BEGIN_DECLS + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +int getentropy(void* buffer, size_t size); +__END_DECLS + +#endif /* __SYS_RANDOM_H__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/resource.h b/lib/libc/include/any-macos.11-any/sys/resource.h new file mode 100644 index 0000000000..ddb4d6ac31 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/resource.h @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2000-2018 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)resource.h 8.2 (Berkeley) 1/4/94 + */ + +#ifndef _SYS_RESOURCE_H_ +#define _SYS_RESOURCE_H_ + +#include +#include +#include + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#include +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#include + +/* [XSI] The timeval structure shall be defined as described in + * + */ +#include + +/* The id_t type shall be defined as described in */ +#include + + +/* + * Resource limit type (low 63 bits, excluding the sign bit) + */ +typedef __uint64_t rlim_t; + + +/***** + * PRIORITY + */ + +/* + * Possible values of the first parameter to getpriority()/setpriority(), + * used to indicate the type of the second parameter. + */ +#define PRIO_PROCESS 0 /* Second argument is a PID */ +#define PRIO_PGRP 1 /* Second argument is a GID */ +#define PRIO_USER 2 /* Second argument is a UID */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define PRIO_DARWIN_THREAD 3 /* Second argument is always 0 (current thread) */ +#define PRIO_DARWIN_PROCESS 4 /* Second argument is a PID */ + + +/* + * Range limitations for the value of the third parameter to setpriority(). + */ +#define PRIO_MIN -20 +#define PRIO_MAX 20 + +/* + * use PRIO_DARWIN_BG to set the current thread into "background" state + * which lowers CPU, disk IO, and networking priorites until thread terminates + * or "background" state is revoked + */ +#define PRIO_DARWIN_BG 0x1000 + +/* + * use PRIO_DARWIN_NONUI to restrict a process's ability to make calls to + * the GPU. (deprecated) + */ +#define PRIO_DARWIN_NONUI 0x1001 + +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + + +/***** + * RESOURCE USAGE + */ + +/* + * Possible values of the first parameter to getrusage(), used to indicate + * the scope of the information to be returned. + */ +#define RUSAGE_SELF 0 /* Current process information */ +#define RUSAGE_CHILDREN -1 /* Current process' children */ + +/* + * A structure representing an accounting of resource utilization. The + * address of an instance of this structure is the second parameter to + * getrusage(). + * + * Note: All values other than ru_utime and ru_stime are implementaiton + * defined and subject to change in a future release. Their use + * is discouraged for standards compliant programs. + */ +struct rusage { + struct timeval ru_utime; /* user time used (PL) */ + struct timeval ru_stime; /* system time used (PL) */ +#if __DARWIN_C_LEVEL < __DARWIN_C_FULL + long ru_opaque[14]; /* implementation defined */ +#else + /* + * Informational aliases for source compatibility with programs + * that need more information than that provided by standards, + * and which do not mind being OS-dependent. + */ + long ru_maxrss; /* max resident set size (PL) */ +#define ru_first ru_ixrss /* internal: ruadd() range start */ + long ru_ixrss; /* integral shared memory size (NU) */ + long ru_idrss; /* integral unshared data (NU) */ + long ru_isrss; /* integral unshared stack (NU) */ + long ru_minflt; /* page reclaims (NU) */ + long ru_majflt; /* page faults (NU) */ + long ru_nswap; /* swaps (NU) */ + long ru_inblock; /* block input operations (atomic) */ + long ru_oublock; /* block output operations (atomic) */ + long ru_msgsnd; /* messages sent (atomic) */ + long ru_msgrcv; /* messages received (atomic) */ + long ru_nsignals; /* signals received (atomic) */ + long ru_nvcsw; /* voluntary context switches (atomic) */ + long ru_nivcsw; /* involuntary " */ +#define ru_last ru_nivcsw /* internal: ruadd() range end */ +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ +}; + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* + * Flavors for proc_pid_rusage(). + */ +#define RUSAGE_INFO_V0 0 +#define RUSAGE_INFO_V1 1 +#define RUSAGE_INFO_V2 2 +#define RUSAGE_INFO_V3 3 +#define RUSAGE_INFO_V4 4 +#define RUSAGE_INFO_V5 5 +#define RUSAGE_INFO_CURRENT RUSAGE_INFO_V5 + +/* + * Flags for RUSAGE_INFO_V5 + */ +#define RU_PROC_RUNS_RESLIDE 0x00000001 /* proc has reslid shared cache */ + +typedef void *rusage_info_t; + +struct rusage_info_v0 { + uint8_t ri_uuid[16]; + uint64_t ri_user_time; + uint64_t ri_system_time; + uint64_t ri_pkg_idle_wkups; + uint64_t ri_interrupt_wkups; + uint64_t ri_pageins; + uint64_t ri_wired_size; + uint64_t ri_resident_size; + uint64_t ri_phys_footprint; + uint64_t ri_proc_start_abstime; + uint64_t ri_proc_exit_abstime; +}; + +struct rusage_info_v1 { + uint8_t ri_uuid[16]; + uint64_t ri_user_time; + uint64_t ri_system_time; + uint64_t ri_pkg_idle_wkups; + uint64_t ri_interrupt_wkups; + uint64_t ri_pageins; + uint64_t ri_wired_size; + uint64_t ri_resident_size; + uint64_t ri_phys_footprint; + uint64_t ri_proc_start_abstime; + uint64_t ri_proc_exit_abstime; + uint64_t ri_child_user_time; + uint64_t ri_child_system_time; + uint64_t ri_child_pkg_idle_wkups; + uint64_t ri_child_interrupt_wkups; + uint64_t ri_child_pageins; + uint64_t ri_child_elapsed_abstime; +}; + +struct rusage_info_v2 { + uint8_t ri_uuid[16]; + uint64_t ri_user_time; + uint64_t ri_system_time; + uint64_t ri_pkg_idle_wkups; + uint64_t ri_interrupt_wkups; + uint64_t ri_pageins; + uint64_t ri_wired_size; + uint64_t ri_resident_size; + uint64_t ri_phys_footprint; + uint64_t ri_proc_start_abstime; + uint64_t ri_proc_exit_abstime; + uint64_t ri_child_user_time; + uint64_t ri_child_system_time; + uint64_t ri_child_pkg_idle_wkups; + uint64_t ri_child_interrupt_wkups; + uint64_t ri_child_pageins; + uint64_t ri_child_elapsed_abstime; + uint64_t ri_diskio_bytesread; + uint64_t ri_diskio_byteswritten; +}; + +struct rusage_info_v3 { + uint8_t ri_uuid[16]; + uint64_t ri_user_time; + uint64_t ri_system_time; + uint64_t ri_pkg_idle_wkups; + uint64_t ri_interrupt_wkups; + uint64_t ri_pageins; + uint64_t ri_wired_size; + uint64_t ri_resident_size; + uint64_t ri_phys_footprint; + uint64_t ri_proc_start_abstime; + uint64_t ri_proc_exit_abstime; + uint64_t ri_child_user_time; + uint64_t ri_child_system_time; + uint64_t ri_child_pkg_idle_wkups; + uint64_t ri_child_interrupt_wkups; + uint64_t ri_child_pageins; + uint64_t ri_child_elapsed_abstime; + uint64_t ri_diskio_bytesread; + uint64_t ri_diskio_byteswritten; + uint64_t ri_cpu_time_qos_default; + uint64_t ri_cpu_time_qos_maintenance; + uint64_t ri_cpu_time_qos_background; + uint64_t ri_cpu_time_qos_utility; + uint64_t ri_cpu_time_qos_legacy; + uint64_t ri_cpu_time_qos_user_initiated; + uint64_t ri_cpu_time_qos_user_interactive; + uint64_t ri_billed_system_time; + uint64_t ri_serviced_system_time; +}; + +struct rusage_info_v4 { + uint8_t ri_uuid[16]; + uint64_t ri_user_time; + uint64_t ri_system_time; + uint64_t ri_pkg_idle_wkups; + uint64_t ri_interrupt_wkups; + uint64_t ri_pageins; + uint64_t ri_wired_size; + uint64_t ri_resident_size; + uint64_t ri_phys_footprint; + uint64_t ri_proc_start_abstime; + uint64_t ri_proc_exit_abstime; + uint64_t ri_child_user_time; + uint64_t ri_child_system_time; + uint64_t ri_child_pkg_idle_wkups; + uint64_t ri_child_interrupt_wkups; + uint64_t ri_child_pageins; + uint64_t ri_child_elapsed_abstime; + uint64_t ri_diskio_bytesread; + uint64_t ri_diskio_byteswritten; + uint64_t ri_cpu_time_qos_default; + uint64_t ri_cpu_time_qos_maintenance; + uint64_t ri_cpu_time_qos_background; + uint64_t ri_cpu_time_qos_utility; + uint64_t ri_cpu_time_qos_legacy; + uint64_t ri_cpu_time_qos_user_initiated; + uint64_t ri_cpu_time_qos_user_interactive; + uint64_t ri_billed_system_time; + uint64_t ri_serviced_system_time; + uint64_t ri_logical_writes; + uint64_t ri_lifetime_max_phys_footprint; + uint64_t ri_instructions; + uint64_t ri_cycles; + uint64_t ri_billed_energy; + uint64_t ri_serviced_energy; + uint64_t ri_interval_max_phys_footprint; + uint64_t ri_runnable_time; +}; + +struct rusage_info_v5 { + uint8_t ri_uuid[16]; + uint64_t ri_user_time; + uint64_t ri_system_time; + uint64_t ri_pkg_idle_wkups; + uint64_t ri_interrupt_wkups; + uint64_t ri_pageins; + uint64_t ri_wired_size; + uint64_t ri_resident_size; + uint64_t ri_phys_footprint; + uint64_t ri_proc_start_abstime; + uint64_t ri_proc_exit_abstime; + uint64_t ri_child_user_time; + uint64_t ri_child_system_time; + uint64_t ri_child_pkg_idle_wkups; + uint64_t ri_child_interrupt_wkups; + uint64_t ri_child_pageins; + uint64_t ri_child_elapsed_abstime; + uint64_t ri_diskio_bytesread; + uint64_t ri_diskio_byteswritten; + uint64_t ri_cpu_time_qos_default; + uint64_t ri_cpu_time_qos_maintenance; + uint64_t ri_cpu_time_qos_background; + uint64_t ri_cpu_time_qos_utility; + uint64_t ri_cpu_time_qos_legacy; + uint64_t ri_cpu_time_qos_user_initiated; + uint64_t ri_cpu_time_qos_user_interactive; + uint64_t ri_billed_system_time; + uint64_t ri_serviced_system_time; + uint64_t ri_logical_writes; + uint64_t ri_lifetime_max_phys_footprint; + uint64_t ri_instructions; + uint64_t ri_cycles; + uint64_t ri_billed_energy; + uint64_t ri_serviced_energy; + uint64_t ri_interval_max_phys_footprint; + uint64_t ri_runnable_time; + uint64_t ri_flags; +}; + +typedef struct rusage_info_v5 rusage_info_current; + +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + + +/***** + * RESOURCE LIMITS + */ + +/* + * Symbolic constants for resource limits; since all limits are representable + * as a type rlim_t, we are permitted to define RLIM_SAVED_* in terms of + * RLIM_INFINITY. + */ +#define RLIM_INFINITY (((__uint64_t)1 << 63) - 1) /* no limit */ +#define RLIM_SAVED_MAX RLIM_INFINITY /* Unrepresentable hard limit */ +#define RLIM_SAVED_CUR RLIM_INFINITY /* Unrepresentable soft limit */ + +/* + * Possible values of the first parameter to getrlimit()/setrlimit(), to + * indicate for which resource the operation is being performed. + */ +#define RLIMIT_CPU 0 /* cpu time per process */ +#define RLIMIT_FSIZE 1 /* file size */ +#define RLIMIT_DATA 2 /* data segment size */ +#define RLIMIT_STACK 3 /* stack size */ +#define RLIMIT_CORE 4 /* core file size */ +#define RLIMIT_AS 5 /* address space (resident set size) */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define RLIMIT_RSS RLIMIT_AS /* source compatibility alias */ +#define RLIMIT_MEMLOCK 6 /* locked-in-memory address space */ +#define RLIMIT_NPROC 7 /* number of processes */ +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ +#define RLIMIT_NOFILE 8 /* number of open files */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define RLIM_NLIMITS 9 /* total number of resource limits */ +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ +#define _RLIMIT_POSIX_FLAG 0x1000 /* Set bit for strict POSIX */ + +/* + * A structure representing a resource limit. The address of an instance + * of this structure is the second parameter to getrlimit()/setrlimit(). + */ +struct rlimit { + rlim_t rlim_cur; /* current (soft) limit */ + rlim_t rlim_max; /* maximum value for rlim_cur */ +}; + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* + * proc_rlimit_control() + * + * Resource limit flavors + */ +#define RLIMIT_WAKEUPS_MONITOR 0x1 /* Configure the wakeups monitor. */ +#define RLIMIT_CPU_USAGE_MONITOR 0x2 /* Configure the CPU usage monitor. */ +#define RLIMIT_THREAD_CPULIMITS 0x3 /* Configure a blocking, per-thread, CPU limits. */ +#define RLIMIT_FOOTPRINT_INTERVAL 0x4 /* Configure memory footprint interval tracking */ + +/* + * Flags for wakeups monitor control. + */ +#define WAKEMON_ENABLE 0x01 +#define WAKEMON_DISABLE 0x02 +#define WAKEMON_GET_PARAMS 0x04 +#define WAKEMON_SET_DEFAULTS 0x08 +#define WAKEMON_MAKE_FATAL 0x10 /* Configure the task so that violations are fatal. */ + +/* + * Flags for CPU usage monitor control. + */ +#define CPUMON_MAKE_FATAL 0x1000 + +/* + * Flags for memory footprint interval tracking. + */ +#define FOOTPRINT_INTERVAL_RESET 0x1 /* Reset the footprint interval counter to zero */ + +struct proc_rlimit_control_wakeupmon { + uint32_t wm_flags; + int32_t wm_rate; +}; + + + +/* I/O type */ +#define IOPOL_TYPE_DISK 0 +#define IOPOL_TYPE_VFS_ATIME_UPDATES 2 +#define IOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES 3 +#define IOPOL_TYPE_VFS_STATFS_NO_DATA_VOLUME 4 +#define IOPOL_TYPE_VFS_TRIGGER_RESOLVE 5 +#define IOPOL_TYPE_VFS_IGNORE_CONTENT_PROTECTION 6 +#define IOPOL_TYPE_VFS_IGNORE_PERMISSIONS 7 +#define IOPOL_TYPE_VFS_SKIP_MTIME_UPDATE 8 + +/* scope */ +#define IOPOL_SCOPE_PROCESS 0 +#define IOPOL_SCOPE_THREAD 1 +#define IOPOL_SCOPE_DARWIN_BG 2 + +/* I/O Priority */ +#define IOPOL_DEFAULT 0 +#define IOPOL_IMPORTANT 1 +#define IOPOL_PASSIVE 2 +#define IOPOL_THROTTLE 3 +#define IOPOL_UTILITY 4 +#define IOPOL_STANDARD 5 + +/* compatibility with older names */ +#define IOPOL_APPLICATION IOPOL_STANDARD +#define IOPOL_NORMAL IOPOL_IMPORTANT + + +#define IOPOL_ATIME_UPDATES_DEFAULT 0 +#define IOPOL_ATIME_UPDATES_OFF 1 + +#define IOPOL_MATERIALIZE_DATALESS_FILES_DEFAULT 0 +#define IOPOL_MATERIALIZE_DATALESS_FILES_OFF 1 +#define IOPOL_MATERIALIZE_DATALESS_FILES_ON 2 + +#define IOPOL_VFS_STATFS_NO_DATA_VOLUME_DEFAULT 0 +#define IOPOL_VFS_STATFS_FORCE_NO_DATA_VOLUME 1 + +#define IOPOL_VFS_TRIGGER_RESOLVE_DEFAULT 0 +#define IOPOL_VFS_TRIGGER_RESOLVE_OFF 1 + +#define IOPOL_VFS_CONTENT_PROTECTION_DEFAULT 0 +#define IOPOL_VFS_CONTENT_PROTECTION_IGNORE 1 + +#define IOPOL_VFS_IGNORE_PERMISSIONS_OFF 0 +#define IOPOL_VFS_IGNORE_PERMISSIONS_ON 1 + +#define IOPOL_VFS_SKIP_MTIME_UPDATE_OFF 0 +#define IOPOL_VFS_SKIP_MTIME_UPDATE_ON 1 + +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + +__BEGIN_DECLS +int getpriority(int, id_t); +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +int getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ +int getrlimit(int, struct rlimit *) __DARWIN_ALIAS(getrlimit); +int getrusage(int, struct rusage *); +int setpriority(int, id_t, int); +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +int setiopolicy_np(int, int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ +int setrlimit(int, const struct rlimit *) __DARWIN_ALIAS(setrlimit); +__END_DECLS + +#endif /* !_SYS_RESOURCE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/socket.h b/lib/libc/include/any-macos.11-any/sys/socket.h new file mode 100644 index 0000000000..0c6b09babe --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/socket.h @@ -0,0 +1,741 @@ +/* + * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */ +/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ +/* + * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)socket.h 8.4 (Berkeley) 2/21/94 + * $FreeBSD: src/sys/sys/socket.h,v 1.39.2.7 2001/07/03 11:02:01 ume Exp $ + */ +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ + +#ifndef _SYS_SOCKET_H_ +#define _SYS_SOCKET_H_ + +#include +#include +#include +#include + + +#include + +/* + * Definitions related to sockets: types, address families, options. + */ + +/* + * Data types. + */ + +#include +#include +#include +#include +#include + +/* XXX Not explicitly defined by POSIX, but function return types are */ +#include + +/* XXX Not explicitly defined by POSIX, but function return types are */ +#include + +/* + * [XSI] The iovec structure shall be defined as described in . + */ +#include + +/* + * Types + */ +#define SOCK_STREAM 1 /* stream socket */ +#define SOCK_DGRAM 2 /* datagram socket */ +#define SOCK_RAW 3 /* raw-protocol interface */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SOCK_RDM 4 /* reliably-delivered message */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#define SOCK_SEQPACKET 5 /* sequenced packet stream */ + +/* + * Option flags per-socket. + */ +#define SO_DEBUG 0x0001 /* turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present (in ticks) */ +#else +#define SO_LINGER 0x1080 /* linger on close if data present (in seconds) */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */ +#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */ +#define SO_TIMESTAMP_MONOTONIC 0x0800 /* Monotonically increasing timestamp on rcvd dgram */ +#ifndef __APPLE__ +#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ +#else +#define SO_DONTTRUNC 0x2000 /* APPLE: Retain unread data */ + /* (ATOMIC proto) */ +#define SO_WANTMORE 0x4000 /* APPLE: Give hint when more data ready */ +#define SO_WANTOOBFLAG 0x8000 /* APPLE: Want OOB in MSG_FLAG on receive */ + + +#endif /* (!__APPLE__) */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SO_LABEL 0x1010 /* deprecated */ +#define SO_PEERLABEL 0x1011 /* deprecated */ +#ifdef __APPLE__ +#define SO_NREAD 0x1020 /* APPLE: get 1st-packet byte count */ +#define SO_NKE 0x1021 /* APPLE: Install socket-level NKE */ +#define SO_NOSIGPIPE 0x1022 /* APPLE: No SIGPIPE on EPIPE */ +#define SO_NOADDRERR 0x1023 /* APPLE: Returns EADDRNOTAVAIL when src is not available anymore */ +#define SO_NWRITE 0x1024 /* APPLE: Get number of bytes currently in send socket buffer */ +#define SO_REUSESHAREUID 0x1025 /* APPLE: Allow reuse of port/socket by different userids */ +#ifdef __APPLE_API_PRIVATE +#define SO_NOTIFYCONFLICT 0x1026 /* APPLE: send notification if there is a bind on a port which is already in use */ +#define SO_UPCALLCLOSEWAIT 0x1027 /* APPLE: block on close until an upcall returns */ +#endif +#define SO_LINGER_SEC 0x1080 /* linger on close if data present (in seconds) */ +#define SO_RANDOMPORT 0x1082 /* APPLE: request local port randomization */ +#define SO_NP_EXTENSIONS 0x1083 /* To turn off some POSIX behavior */ +#endif + +#define SO_NUMRCVPKT 0x1112 /* number of datagrams in receive socket buffer */ +#define SO_NET_SERVICE_TYPE 0x1116 /* Network service type */ + + +#define SO_NETSVC_MARKING_LEVEL 0x1119 /* Get QoS marking in effect for socket */ + +/* + * Network Service Type for option SO_NET_SERVICE_TYPE + * + * The vast majority of sockets should use Best Effort that is the default + * Network Service Type. Other Network Service Types have to be used only if + * the traffic actually matches the description of the Network Service Type. + * + * Network Service Types do not represent priorities but rather describe + * different categories of delay, jitter and loss parameters. + * Those parameters may influence protocols from layer 4 protocols like TCP + * to layer 2 protocols like Wi-Fi. The Network Service Type can determine + * how the traffic is queued and scheduled by the host networking stack and + * by other entities on the network like switches and routers. For example + * for Wi-Fi, the Network Service Type can select the marking of the + * layer 2 packet with the appropriate WMM Access Category. + * + * There is no point in attempting to game the system and use + * a Network Service Type that does not correspond to the actual + * traffic characteristic but one that seems to have a higher precedence. + * The reason is that for service classes that have lower tolerance + * for delay and jitter, the queues size is lower than for service + * classes that are more tolerant to delay and jitter. + * + * For example using a voice service type for bulk data transfer will lead + * to disastrous results as soon as congestion happens because the voice + * queue overflows and packets get dropped. This is not only bad for the bulk + * data transfer but it is also bad for VoIP apps that legitimately are using + * the voice service type. + * + * The characteristics of the Network Service Types are based on the service + * classes defined in RFC 4594 "Configuration Guidelines for DiffServ Service + * Classes" + * + * When system detects the outgoing interface belongs to a DiffServ domain + * that follows the recommendation of the IETF draft "Guidelines for DiffServ to + * IEEE 802.11 Mapping", the packet will marked at layer 3 with a DSCP value + * that corresponds to Network Service Type. + * + * NET_SERVICE_TYPE_BE + * "Best Effort", unclassified/standard. This is the default service + * class and cover the majority of the traffic. + * + * NET_SERVICE_TYPE_BK + * "Background", high delay tolerant, loss tolerant. elastic flow, + * variable size & long-lived. E.g: non-interactive network bulk transfer + * like synching or backup. + * + * NET_SERVICE_TYPE_RD + * "Responsive Data", a notch higher than "Best Effort", medium delay + * tolerant, elastic & inelastic flow, bursty, long-lived. E.g. email, + * instant messaging, for which there is a sense of interactivity and + * urgency (user waiting for output). + * + * NET_SERVICE_TYPE_OAM + * "Operations, Administration, and Management", medium delay tolerant, + * low-medium loss tolerant, elastic & inelastic flows, variable size. + * E.g. VPN tunnels. + * + * NET_SERVICE_TYPE_AV + * "Multimedia Audio/Video Streaming", medium delay tolerant, low-medium + * loss tolerant, elastic flow, constant packet interval, variable rate + * and size. E.g. video and audio playback with buffering. + * + * NET_SERVICE_TYPE_RV + * "Responsive Multimedia Audio/Video", low delay tolerant, low-medium + * loss tolerant, elastic flow, variable packet interval, rate and size. + * E.g. screen sharing. + * + * NET_SERVICE_TYPE_VI + * "Interactive Video", low delay tolerant, low-medium loss tolerant, + * elastic flow, constant packet interval, variable rate & size. E.g. + * video telephony. + * + * NET_SERVICE_TYPE_SIG + * "Signaling", low delay tolerant, low loss tolerant, inelastic flow, + * jitter tolerant, rate is bursty but short, variable size. E.g. SIP. + * + * NET_SERVICE_TYPE_VO + * "Interactive Voice", very low delay tolerant, very low loss tolerant, + * inelastic flow, constant packet rate, somewhat fixed size. + * E.g. VoIP. + */ + +#define NET_SERVICE_TYPE_BE 0 /* Best effort */ +#define NET_SERVICE_TYPE_BK 1 /* Background system initiated */ +#define NET_SERVICE_TYPE_SIG 2 /* Signaling */ +#define NET_SERVICE_TYPE_VI 3 /* Interactive Video */ +#define NET_SERVICE_TYPE_VO 4 /* Interactive Voice */ +#define NET_SERVICE_TYPE_RV 5 /* Responsive Multimedia Audio/Video */ +#define NET_SERVICE_TYPE_AV 6 /* Multimedia Audio/Video Streaming */ +#define NET_SERVICE_TYPE_OAM 7 /* Operations, Administration, and Management */ +#define NET_SERVICE_TYPE_RD 8 /* Responsive Data */ + + +/* These are supported values for SO_NETSVC_MARKING_LEVEL */ +#define NETSVC_MRKNG_UNKNOWN 0 /* The outgoing network interface is not known */ +#define NETSVC_MRKNG_LVL_L2 1 /* Default marking at layer 2 (for example Wi-Fi WMM) */ +#define NETSVC_MRKNG_LVL_L3L2_ALL 2 /* Layer 3 DSCP marking and layer 2 marking for all Network Service Types */ +#define NETSVC_MRKNG_LVL_L3L2_BK 3 /* The system policy limits layer 3 DSCP marking and layer 2 marking + * to background Network Service Types */ + + +typedef __uint32_t sae_associd_t; +#define SAE_ASSOCID_ANY 0 +#define SAE_ASSOCID_ALL ((sae_associd_t)(-1ULL)) + +typedef __uint32_t sae_connid_t; +#define SAE_CONNID_ANY 0 +#define SAE_CONNID_ALL ((sae_connid_t)(-1ULL)) + +/* connectx() flag parameters */ +#define CONNECT_RESUME_ON_READ_WRITE 0x1 /* resume connect() on read/write */ +#define CONNECT_DATA_IDEMPOTENT 0x2 /* data is idempotent */ +#define CONNECT_DATA_AUTHENTICATED 0x4 /* data includes security that replaces the TFO-cookie */ + +/* sockaddr endpoints */ +typedef struct sa_endpoints { + unsigned int sae_srcif; /* optional source interface */ + const struct sockaddr *sae_srcaddr; /* optional source address */ + socklen_t sae_srcaddrlen; /* size of source address */ + const struct sockaddr *sae_dstaddr; /* destination address */ + socklen_t sae_dstaddrlen; /* size of destination address */ +} sa_endpoints_t; +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +#ifndef __APPLE__ +struct accept_filter_arg { + char af_name[16]; + char af_arg[256 - 16]; +}; +#endif + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#ifdef __APPLE__ + +/* + * Structure to control non-portable Sockets extension to POSIX + */ +struct so_np_extensions { + u_int32_t npx_flags; + u_int32_t npx_mask; +}; + +#define SONPX_SETOPTSHUT 0x000000001 /* flag for allowing setsockopt after shutdown */ + + + +#endif +#endif + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xffff /* options for socket level */ + + +/* + * Address families. + */ +#define AF_UNSPEC 0 /* unspecified */ +#define AF_UNIX 1 /* local to host (pipes) */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define AF_LOCAL AF_UNIX /* backward compatibility */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#define AF_INET 2 /* internetwork: UDP, TCP, etc. */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define AF_IMPLINK 3 /* arpanet imp addresses */ +#define AF_PUP 4 /* pup protocols: e.g. BSP */ +#define AF_CHAOS 5 /* mit CHAOS protocols */ +#define AF_NS 6 /* XEROX NS protocols */ +#define AF_ISO 7 /* ISO protocols */ +#define AF_OSI AF_ISO +#define AF_ECMA 8 /* European computer manufacturers */ +#define AF_DATAKIT 9 /* datakit protocols */ +#define AF_CCITT 10 /* CCITT protocols, X.25 etc */ +#define AF_SNA 11 /* IBM SNA */ +#define AF_DECnet 12 /* DECnet */ +#define AF_DLI 13 /* DEC Direct data link interface */ +#define AF_LAT 14 /* LAT */ +#define AF_HYLINK 15 /* NSC Hyperchannel */ +#define AF_APPLETALK 16 /* Apple Talk */ +#define AF_ROUTE 17 /* Internal Routing Protocol */ +#define AF_LINK 18 /* Link layer interface */ +#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */ +#define AF_COIP 20 /* connection-oriented IP, aka ST II */ +#define AF_CNT 21 /* Computer Network Technology */ +#define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */ +#define AF_IPX 23 /* Novell Internet Protocol */ +#define AF_SIP 24 /* Simple Internet Protocol */ +#define pseudo_AF_PIP 25 /* Help Identify PIP packets */ +#define AF_NDRV 27 /* Network Driver 'raw' access */ +#define AF_ISDN 28 /* Integrated Services Digital Network */ +#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */ +#define pseudo_AF_KEY 29 /* Internal key-management function */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#define AF_INET6 30 /* IPv6 */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define AF_NATM 31 /* native ATM access */ +#define AF_SYSTEM 32 /* Kernel event messages */ +#define AF_NETBIOS 33 /* NetBIOS */ +#define AF_PPP 34 /* PPP communication protocol */ +#define pseudo_AF_HDRCMPLT 35 /* Used by BPF to not rewrite headers + * in interface output routine */ +#define AF_RESERVED_36 36 /* Reserved for internal usage */ +#define AF_IEEE80211 37 /* IEEE 802.11 protocol */ +#define AF_UTUN 38 +#define AF_VSOCK 40 /* VM Sockets */ +#define AF_MAX 41 +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * [XSI] Structure used by kernel to store most addresses. + */ +struct sockaddr { + __uint8_t sa_len; /* total length */ + sa_family_t sa_family; /* [XSI] address family */ + char sa_data[14]; /* [XSI] addr value (actually larger) */ +}; + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SOCK_MAXADDRLEN 255 /* longest possible addresses */ + +/* + * Structure used by kernel to pass protocol + * information in raw sockets. + */ +struct sockproto { + __uint16_t sp_family; /* address family */ + __uint16_t sp_protocol; /* protocol */ +}; +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128 +#define _SS_ALIGNSIZE (sizeof(__int64_t)) +#define _SS_PAD1SIZE \ + (_SS_ALIGNSIZE - sizeof(__uint8_t) - sizeof(sa_family_t)) +#define _SS_PAD2SIZE \ + (_SS_MAXSIZE - sizeof(__uint8_t) - sizeof(sa_family_t) - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +/* + * [XSI] sockaddr_storage + */ +struct sockaddr_storage { + __uint8_t ss_len; /* address length */ + sa_family_t ss_family; /* [XSI] address family */ + char __ss_pad1[_SS_PAD1SIZE]; + __int64_t __ss_align; /* force structure storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; +}; + +/* + * Protocol families, same as address families for now. + */ +#define PF_UNSPEC AF_UNSPEC +#define PF_LOCAL AF_LOCAL +#define PF_UNIX PF_LOCAL /* backward compatibility */ +#define PF_INET AF_INET +#define PF_IMPLINK AF_IMPLINK +#define PF_PUP AF_PUP +#define PF_CHAOS AF_CHAOS +#define PF_NS AF_NS +#define PF_ISO AF_ISO +#define PF_OSI AF_ISO +#define PF_ECMA AF_ECMA +#define PF_DATAKIT AF_DATAKIT +#define PF_CCITT AF_CCITT +#define PF_SNA AF_SNA +#define PF_DECnet AF_DECnet +#define PF_DLI AF_DLI +#define PF_LAT AF_LAT +#define PF_HYLINK AF_HYLINK +#define PF_APPLETALK AF_APPLETALK +#define PF_ROUTE AF_ROUTE +#define PF_LINK AF_LINK +#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */ +#define PF_COIP AF_COIP +#define PF_CNT AF_CNT +#define PF_SIP AF_SIP +#define PF_IPX AF_IPX /* same format as AF_NS */ +#define PF_RTIP pseudo_AF_RTIP /* same format as AF_INET */ +#define PF_PIP pseudo_AF_PIP +#define PF_NDRV AF_NDRV +#define PF_ISDN AF_ISDN +#define PF_KEY pseudo_AF_KEY +#define PF_INET6 AF_INET6 +#define PF_NATM AF_NATM +#define PF_SYSTEM AF_SYSTEM +#define PF_NETBIOS AF_NETBIOS +#define PF_PPP AF_PPP +#define PF_RESERVED_36 AF_RESERVED_36 +#define PF_UTUN AF_UTUN +#define PF_VSOCK AF_VSOCK +#define PF_MAX AF_MAX + +/* + * These do not have socket-layer support: + */ +#define PF_VLAN ((uint32_t)0x766c616e) /* 'vlan' */ +#define PF_BOND ((uint32_t)0x626f6e64) /* 'bond' */ + +/* + * Definitions for network related sysctl, CTL_NET. + * + * Second level is protocol family. + * Third level is protocol number. + * + * Further levels are defined by the individual families below. + */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define NET_MAXID AF_MAX +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +/* + * PF_ROUTE - Routing table + * + * Three additional levels are defined: + * Fourth: address family, 0 is wildcard + * Fifth: type of info, defined below + * Sixth: flag(s) to mask with for NET_RT_FLAGS + */ +#define NET_RT_DUMP 1 /* dump; may limit to a.f. */ +#define NET_RT_FLAGS 2 /* by flags, e.g. RESOLVING */ +#define NET_RT_IFLIST 3 /* survey interface list */ +#define NET_RT_STAT 4 /* routing statistics */ +#define NET_RT_TRASH 5 /* routes not in table but not freed */ +#define NET_RT_IFLIST2 6 /* interface list with addresses */ +#define NET_RT_DUMP2 7 /* dump; may limit to a.f. */ +/* + * Allows read access non-local host's MAC address + * if the process has neighbor cache entitlement. + */ +#define NET_RT_FLAGS_PRIV 10 +#define NET_RT_MAXID 11 +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + + + + +/* + * Maximum queue length specifiable by listen. + */ +#define SOMAXCONN 128 + +/* + * [XSI] Message header for recvmsg and sendmsg calls. + * Used value-result for recvmsg, value only for sendmsg. + */ +struct msghdr { + void *msg_name; /* [XSI] optional address */ + socklen_t msg_namelen; /* [XSI] size of address */ + struct iovec *msg_iov; /* [XSI] scatter/gather array */ + int msg_iovlen; /* [XSI] # elements in msg_iov */ + void *msg_control; /* [XSI] ancillary data, see below */ + socklen_t msg_controllen; /* [XSI] ancillary data buffer len */ + int msg_flags; /* [XSI] flags on received message */ +}; + + + +#define MSG_OOB 0x1 /* process out-of-band data */ +#define MSG_PEEK 0x2 /* peek at incoming message */ +#define MSG_DONTROUTE 0x4 /* send without using routing tables */ +#define MSG_EOR 0x8 /* data completes record */ +#define MSG_TRUNC 0x10 /* data discarded before delivery */ +#define MSG_CTRUNC 0x20 /* control data lost before delivery */ +#define MSG_WAITALL 0x40 /* wait for full request or error */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */ +#define MSG_EOF 0x100 /* data completes connection */ +#ifdef __APPLE__ +#ifdef __APPLE_API_OBSOLETE +#define MSG_WAITSTREAM 0x200 /* wait up to full request.. may return partial */ +#endif +#define MSG_FLUSH 0x400 /* Start of 'hold' seq; dump so_temp, deprecated */ +#define MSG_HOLD 0x800 /* Hold frag in so_temp, deprecated */ +#define MSG_SEND 0x1000 /* Send the packet in so_temp, deprecated */ +#define MSG_HAVEMORE 0x2000 /* Data ready to be read */ +#define MSG_RCVMORE 0x4000 /* Data remains in current pkt */ +#endif +#define MSG_NEEDSA 0x10000 /* Fail receive if socket address cannot be allocated */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +#if __DARWIN_C_LEVEL >= 200809L +#define MSG_NOSIGNAL 0x80000 /* do not generate SIGPIPE on EOF */ +#endif /* __DARWIN_C_LEVEL */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * Header for ancillary data objects in msg_control buffer. + * Used for additional information with/about a datagram + * not expressible by flags. The format is a sequence + * of message elements headed by cmsghdr structures. + */ +struct cmsghdr { + socklen_t cmsg_len; /* [XSI] data byte count, including hdr */ + int cmsg_level; /* [XSI] originating protocol */ + int cmsg_type; /* [XSI] protocol-specific type */ +/* followed by unsigned char cmsg_data[]; */ +}; + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#ifndef __APPLE__ +/* + * While we may have more groups than this, the cmsgcred struct must + * be able to fit in an mbuf, and NGROUPS_MAX is too large to allow + * this. + */ +#define CMGROUP_MAX 16 + +/* + * Credentials structure, used to verify the identity of a peer + * process that has sent us a message. This is allocated by the + * peer process but filled in by the kernel. This prevents the + * peer from lying about its identity. (Note that cmcred_groups[0] + * is the effective GID.) + */ +struct cmsgcred { + pid_t cmcred_pid; /* PID of sending process */ + uid_t cmcred_uid; /* real UID of sending process */ + uid_t cmcred_euid; /* effective UID of sending process */ + gid_t cmcred_gid; /* real GID of sending process */ + short cmcred_ngroups; /* number or groups */ + gid_t cmcred_groups[CMGROUP_MAX]; /* groups */ +}; +#endif +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* given pointer to struct cmsghdr, return pointer to data */ +#define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ + __DARWIN_ALIGN32(sizeof(struct cmsghdr))) + +/* + * RFC 2292 requires to check msg_controllen, in case that the kernel returns + * an empty list for some reasons. + */ +#define CMSG_FIRSTHDR(mhdr) \ + ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ + (struct cmsghdr *)(mhdr)->msg_control : \ + (struct cmsghdr *)0L) + + +/* + * Given pointer to struct cmsghdr, return pointer to next cmsghdr + * RFC 2292 says that CMSG_NXTHDR(mhdr, NULL) is equivalent to CMSG_FIRSTHDR(mhdr) + */ +#define CMSG_NXTHDR(mhdr, cmsg) \ + ((char *)(cmsg) == (char *)0L ? CMSG_FIRSTHDR(mhdr) : \ + ((((unsigned char *)(cmsg) + \ + __DARWIN_ALIGN32((__uint32_t)(cmsg)->cmsg_len) + \ + __DARWIN_ALIGN32(sizeof(struct cmsghdr))) > \ + ((unsigned char *)(mhdr)->msg_control + \ + (mhdr)->msg_controllen)) ? \ + (struct cmsghdr *)0L /* NULL */ : \ + (struct cmsghdr *)(void *)((unsigned char *)(cmsg) + \ + __DARWIN_ALIGN32((__uint32_t)(cmsg)->cmsg_len)))) + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +/* RFC 2292 additions */ +#define CMSG_SPACE(l) (__DARWIN_ALIGN32(sizeof(struct cmsghdr)) + __DARWIN_ALIGN32(l)) +#define CMSG_LEN(l) (__DARWIN_ALIGN32(sizeof(struct cmsghdr)) + (l)) + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* "Socket"-level control message types: */ +#define SCM_RIGHTS 0x01 /* access rights (array of int) */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */ +#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */ +#define SCM_TIMESTAMP_MONOTONIC 0x04 /* timestamp (uint64_t) */ + + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * howto arguments for shutdown(2), specified by Posix.1g. + */ +#define SHUT_RD 0 /* shut down the reading side */ +#define SHUT_WR 1 /* shut down the writing side */ +#define SHUT_RDWR 2 /* shut down both sides */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +/* + * sendfile(2) header/trailer struct + */ +struct sf_hdtr { + struct iovec *headers; /* pointer to an array of header struct iovec's */ + int hdr_cnt; /* number of header iovec's */ + struct iovec *trailers; /* pointer to an array of trailer struct iovec's */ + int trl_cnt; /* number of trailer iovec's */ +}; + + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + + +__BEGIN_DECLS + +int accept(int, struct sockaddr * __restrict, socklen_t * __restrict) +__DARWIN_ALIAS_C(accept); +int bind(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS(bind); +int connect(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(connect); +int getpeername(int, struct sockaddr * __restrict, socklen_t * __restrict) +__DARWIN_ALIAS(getpeername); +int getsockname(int, struct sockaddr * __restrict, socklen_t * __restrict) +__DARWIN_ALIAS(getsockname); +int getsockopt(int, int, int, void * __restrict, socklen_t * __restrict); +int listen(int, int) __DARWIN_ALIAS(listen); +ssize_t recv(int, void *, size_t, int) __DARWIN_ALIAS_C(recv); +ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, + socklen_t * __restrict) __DARWIN_ALIAS_C(recvfrom); +ssize_t recvmsg(int, struct msghdr *, int) __DARWIN_ALIAS_C(recvmsg); +ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send); +ssize_t sendmsg(int, const struct msghdr *, int) __DARWIN_ALIAS_C(sendmsg); +ssize_t sendto(int, const void *, size_t, + int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(sendto); +int setsockopt(int, int, int, const void *, socklen_t); +int shutdown(int, int); +int sockatmark(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int socket(int, int, int); +int socketpair(int, int, int, int *) __DARWIN_ALIAS(socketpair); + +#if !defined(_POSIX_C_SOURCE) +int sendfile(int, int, off_t, off_t *, struct sf_hdtr *, int); +#endif /* !_POSIX_C_SOURCE */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +void pfctlinput(int, struct sockaddr *); + +__API_AVAILABLE(macosx(10.11), ios(9.0), tvos(9.0), watchos(2.0)) +int connectx(int, const sa_endpoints_t *, sae_associd_t, unsigned int, + const struct iovec *, unsigned int, size_t *, sae_connid_t *); + +__API_AVAILABLE(macosx(10.11), ios(9.0), tvos(9.0), watchos(2.0)) +int disconnectx(int, sae_associd_t, sae_connid_t); +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +__END_DECLS + + +#endif /* !_SYS_SOCKET_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/sockio.h b/lib/libc/include/any-macos.11-any/sys/sockio.h new file mode 100644 index 0000000000..9dc2ee7489 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/sockio.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sockio.h 8.1 (Berkeley) 3/28/94 + */ + +#ifndef _SYS_SOCKIO_H_ +#define _SYS_SOCKIO_H_ + +#include + +#include + +/* Socket ioctl's. */ +#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */ +#define SIOCSPGRP _IOW('s', 8, int) /* set process group */ +#define SIOCGPGRP _IOR('s', 9, int) /* get process group */ + +/* + * OSIOCGIF* ioctls are deprecated; they are kept for binary compatibility. + */ +#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */ +#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */ +#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */ +#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */ +#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */ +#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */ +#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */ +#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */ +#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ +#define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */ + +#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */ +#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */ +#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */ +#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */ +#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */ +#define SIOCAUTOADDR _IOWR('i', 38, struct ifreq) /* autoconf address */ +#define SIOCAUTONETMASK _IOW('i', 39, struct ifreq) /* autoconf netmask */ +#define SIOCARPIPLL _IOWR('i', 40, struct ifreq) /* arp for IPv4LL address */ + +#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */ +#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */ +#define SIOCGIFMTU _IOWR('i', 51, struct ifreq) /* get IF mtu */ +#define SIOCSIFMTU _IOW('i', 52, struct ifreq) /* set IF mtu */ +#define SIOCGIFPHYS _IOWR('i', 53, struct ifreq) /* get IF wire */ +#define SIOCSIFPHYS _IOW('i', 54, struct ifreq) /* set IF wire */ +#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ + +/* + * The command SIOCGIFMEDIA does not allow a process to access the extended + * media subtype and extended subtype values are returned as IFM_OTHER. + */ +#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get compatible net media */ + +#define SIOCSIFGENERIC _IOW('i', 57, struct ifreq) /* generic IF set op */ +#define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */ +#define SIOCRSLVMULTI _IOWR('i', 59, struct rslvmulti_req) + +#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set link level addr */ +#define SIOCGIFSTATUS _IOWR('i', 61, struct ifstat) /* get IF status */ +#define SIOCSIFPHYADDR _IOW('i', 62, struct ifaliasreq) /* set gif addres */ +#define SIOCGIFPSRCADDR _IOWR('i', 63, struct ifreq) /* get gif psrc addr */ +#define SIOCGIFPDSTADDR _IOWR('i', 64, struct ifreq) /* get gif pdst addr */ +#define SIOCDIFPHYADDR _IOW('i', 65, struct ifreq) /* delete gif addrs */ + +#define SIOCGIFDEVMTU _IOWR('i', 68, struct ifreq) /* get if ifdevmtu */ +#define SIOCSIFALTMTU _IOW('i', 69, struct ifreq) /* set if alternate mtu */ +#define SIOCGIFALTMTU _IOWR('i', 72, struct ifreq) /* get if alternate mtu */ +#define SIOCSIFBOND _IOW('i', 70, struct ifreq) /* set bond if config */ +#define SIOCGIFBOND _IOWR('i', 71, struct ifreq) /* get bond if config */ + +/* + * The command SIOCGIFXMEDIA is meant to be used by processes only to be able + * to access the extended media subtypes with the extended IFM_TMASK. + * + * An ifnet must not implement SIOCGIFXMEDIA as it gets the extended + * media subtypes by simply compiling with + */ +#define SIOCGIFXMEDIA _IOWR('i', 72, struct ifmediareq) /* get net extended media */ + + +#define SIOCSIFCAP _IOW('i', 90, struct ifreq) /* set IF features */ +#define SIOCGIFCAP _IOWR('i', 91, struct ifreq) /* get IF features */ + +#define SIOCIFCREATE _IOWR('i', 120, struct ifreq) /* create clone if */ +#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */ +#define SIOCIFCREATE2 _IOWR('i', 122, struct ifreq) /* create clone if with data */ + +#define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) /* set driver-specific + * parameters */ +#define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) /* get driver-specific + * parameters */ +#define SIOCSIFVLAN _IOW('i', 126, struct ifreq) /* set VLAN config */ +#define SIOCGIFVLAN _IOWR('i', 127, struct ifreq) /* get VLAN config */ +#define SIOCSETVLAN SIOCSIFVLAN +#define SIOCGETVLAN SIOCGIFVLAN + +#define SIOCIFGCLONERS _IOWR('i', 129, struct if_clonereq) /* get cloners */ + +#define SIOCGIFASYNCMAP _IOWR('i', 124, struct ifreq) /* get ppp asyncmap */ +#define SIOCSIFASYNCMAP _IOW('i', 125, struct ifreq) /* set ppp asyncmap */ + + + +#define SIOCGIFMAC _IOWR('i', 130, struct ifreq) /* deprecated */ +#define SIOCSIFMAC _IOW('i', 131, struct ifreq) /* deprecated */ +#define SIOCSIFKPI _IOW('i', 134, struct ifreq) /* set interface kext param - root only */ +#define SIOCGIFKPI _IOWR('i', 135, struct ifreq) /* get interface kext param */ + +#define SIOCGIFWAKEFLAGS _IOWR('i', 136, struct ifreq) /* get interface wake property flags */ + +#define SIOCGIFFUNCTIONALTYPE _IOWR('i', 173, struct ifreq) /* get interface functional type */ + +#define SIOCSIF6LOWPAN _IOW('i', 196, struct ifreq) /* set 6LOWPAN config */ +#define SIOCGIF6LOWPAN _IOWR('i', 197, struct ifreq) /* get 6LOWPAN config */ + + +#endif /* !_SYS_SOCKIO_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/sys/sysctl.h b/lib/libc/include/any-macos.11-any/sys/sysctl.h index 8159506c99..9baf93c2ec 100644 --- a/lib/libc/include/any-macos.11-any/sys/sysctl.h +++ b/lib/libc/include/any-macos.11-any/sys/sysctl.h @@ -338,8 +338,8 @@ struct ctlname { #define KERN_KDSET_TYPEFILTER 22 #define KERN_KDBUFWAIT 23 #define KERN_KDCPUMAP 24 -#define KERN_KDCPUMAP_EXT 25 -/* 25 - 27 unused */ +/* 25 - 26 unused */ +#define KERN_KDWRITEMAP_V3 27 #define KERN_KDWRITETR_V3 28 #define CTL_KERN_NAMES { \ @@ -668,28 +668,6 @@ extern struct loadavg averunnable; * hw.l2cachesize - * hw.l3cachesize - * - * hw.nperflevels - Number of core types in the system. See the parameters below, which can be used to get - * - information associated with a specific perf level. - * - * The following parameters apply to perflevel N, where N is a number between 0 and the number of core types in the system minus one. - * perflevel 0 always refers to the highest performance core type in the system. - * - * hw.perflevelN.physicalcpu - The number of physical processors available in the current power management mode. - * hw.perflevelN.physicalcpumax - The maximum number of physical processors that could be available this boot. - * hw.perflevelN.logicalcpu - The number of logical processors available in the current power management mode. - * hw.perflevelN.logicalcpumax - The maximum number of logical processors that could be available this boot. - * - * hw.perflevelN.l1dcachesize - These values provide the size in bytes of the L1, L2 and L3 caches. If a cache is not present - * hw.perflevelN.l1icachesize - then the selector will return and error. - * hw.perflevelN.l2cachesize - - * hw.perflevelN.l3cachesize - - * - * hw.perflevelN.cpusperl2 - These values provide the number of CPUs of the same type that share L2 and L3 caches. - * hw.perflevelN.cpusperl3 - If a cache is not present then the selector will return and error. - * - * hw.perflevelN.l2perflevels - These values provide a bitmap, where bit number of CPUs of the same type that share L2 and L3 caches. - * hw.perflevelN.l3perflevels - If a cache is not present then the selector will return and error. - * * hw.packages - Gives the number of processor packages. * * These are the selectors for optional processor features for specific processors. Selectors that return errors are not support diff --git a/lib/libc/include/any-macos.11-any/sys/ttycom.h b/lib/libc/include/any-macos.11-any/sys/ttycom.h new file mode 100644 index 0000000000..e3830c8627 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/sys/ttycom.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ttycom.h 8.1 (Berkeley) 3/28/94 + */ + +#ifndef _SYS_TTYCOM_H_ +#define _SYS_TTYCOM_H_ + +#include +/* + * Tty ioctl's except for those supported only for backwards compatibility + * with the old tty driver. + */ + +/* + * Window/terminal size structure. This information is stored by the kernel + * in order to provide a consistent interface, but is not used by the kernel. + */ +struct winsize { + unsigned short ws_row; /* rows, in characters */ + unsigned short ws_col; /* columns, in characters */ + unsigned short ws_xpixel; /* horizontal size, pixels */ + unsigned short ws_ypixel; /* vertical size, pixels */ +}; + +#define TIOCMODG _IOR('t', 3, int) /* get modem control state */ +#define TIOCMODS _IOW('t', 4, int) /* set modem control state */ +#define TIOCM_LE 0001 /* line enable */ +#define TIOCM_DTR 0002 /* data terminal ready */ +#define TIOCM_RTS 0004 /* request to send */ +#define TIOCM_ST 0010 /* secondary transmit */ +#define TIOCM_SR 0020 /* secondary receive */ +#define TIOCM_CTS 0040 /* clear to send */ +#define TIOCM_CAR 0100 /* carrier detect */ +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RNG 0200 /* ring */ +#define TIOCM_RI TIOCM_RNG +#define TIOCM_DSR 0400 /* data set ready */ + /* 8-10 compat */ +#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */ +#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */ + /* 15 unused */ +#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */ + /* 17-18 compat */ +#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */ +#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */ +#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */ +#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */ +#define TIOCGETD _IOR('t', 26, int) /* get line discipline */ +#define TIOCSETD _IOW('t', 27, int) /* set line discipline */ +#define TIOCIXON _IO('t', 129) /* internal input VSTART */ +#define TIOCIXOFF _IO('t', 128) /* internal input VSTOP */ + /* 127-124 compat */ +#define TIOCSBRK _IO('t', 123) /* set break bit */ +#define TIOCCBRK _IO('t', 122) /* clear break bit */ +#define TIOCSDTR _IO('t', 121) /* set data terminal ready */ +#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */ +#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */ +#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */ + /* 117-116 compat */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ +#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */ +#define TIOCNOTTY _IO('t', 113) /* void tty association */ +#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */ +#define TIOCPKT_DATA 0x00 /* data packet */ +#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */ +#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ +#define TIOCPKT_STOP 0x04 /* stop output */ +#define TIOCPKT_START 0x08 /* start output */ +#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ +#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ +#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */ +#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */ +#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */ +#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */ +#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */ +#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ +#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ +#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */ +#define TIOCSTAT _IO('t', 101) /* simulate ^T status message */ +#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */ +#define TIOCSCONS _IO('t', 99) /* 4.2 compatibility */ +#define TIOCCONS _IOW('t', 98, int) /* become virtual console */ +#define TIOCSCTTY _IO('t', 97) /* become controlling tty */ +#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */ +#define TIOCSIG _IO('t', 95) /* pty: generate signal */ +#define TIOCDRAIN _IO('t', 94) /* wait till output drained */ +#define TIOCMSDTRWAIT _IOW('t', 91, int) /* modem: set wait on close */ +#define TIOCMGDTRWAIT _IOR('t', 90, int) /* modem: get wait on close */ +#define TIOCTIMESTAMP _IOR('t', 89, struct timeval) /* enable/get timestamp + * of last input event */ +#define TIOCDCDTIMESTAMP _IOR('t', 88, struct timeval) /* enable/get timestamp + * of last DCd rise */ +#define TIOCSDRAINWAIT _IOW('t', 87, int) /* set ttywait timeout */ +#define TIOCGDRAINWAIT _IOR('t', 86, int) /* get ttywait timeout */ +#define TIOCDSIMICROCODE _IO('t', 85) /* download microcode to + * DSI Softmodem */ +#define TIOCPTYGRANT _IO('t', 84) /* grantpt(3) */ +#define TIOCPTYGNAME _IOC(IOC_OUT, 't', 83, 128) /* ptsname(3) */ +#define TIOCPTYUNLK _IO('t', 82) /* unlockpt(3) */ + +#define TTYDISC 0 /* termios tty line discipline */ +#define TABLDISC 3 /* tablet discipline */ +#define SLIPDISC 4 /* serial IP discipline */ +#define PPPDISC 5 /* PPP discipline */ + +#endif /* !_SYS_TTYCOM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/unistd.h b/lib/libc/include/any-macos.11-any/unistd.h new file mode 100644 index 0000000000..d07a4a61f5 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/unistd.h @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2000, 2002-2006, 2008-2010, 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1998-1999 Apple Computer, Inc. All Rights Reserved + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)unistd.h 8.12 (Berkeley) 4/27/95 + * + * Copyright (c) 1998 Apple Compter, Inc. + * All Rights Reserved + */ + +/* History: + 7/14/99 EKN at Apple fixed getdirentriesattr from getdirentryattr + 3/26/98 CHW at Apple added real interface to searchfs call + 3/5/98 CHW at Apple added hfs semantic system calls headers +*/ + +#ifndef _UNISTD_H_ +#define _UNISTD_H_ + +#include <_types.h> +#include +#include +#include +#include +#include +#include +/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: + * _GCC_SIZE_T */ +#include +#include +#include +#include +#include + +#define STDIN_FILENO 0 /* standard input file descriptor */ +#define STDOUT_FILENO 1 /* standard output file descriptor */ +#define STDERR_FILENO 2 /* standard error file descriptor */ + + +/* Version test macros */ +/* _POSIX_VERSION and _POSIX2_VERSION from sys/unistd.h */ +#define _XOPEN_VERSION 600 /* [XSI] */ +#define _XOPEN_XCU_VERSION 4 /* Older standard */ + + +/* Please keep this list in the same order as the applicable standard */ +#define _POSIX_ADVISORY_INFO (-1) /* [ADV] */ +#define _POSIX_ASYNCHRONOUS_IO (-1) /* [AIO] */ +#define _POSIX_BARRIERS (-1) /* [BAR] */ +#define _POSIX_CHOWN_RESTRICTED 200112L +#define _POSIX_CLOCK_SELECTION (-1) /* [CS] */ +#define _POSIX_CPUTIME (-1) /* [CPT] */ +#define _POSIX_FSYNC 200112L /* [FSC] */ +#define _POSIX_IPV6 200112L +#define _POSIX_JOB_CONTROL 200112L +#define _POSIX_MAPPED_FILES 200112L /* [MF] */ +#define _POSIX_MEMLOCK (-1) /* [ML] */ +#define _POSIX_MEMLOCK_RANGE (-1) /* [MR] */ +#define _POSIX_MEMORY_PROTECTION 200112L /* [MPR] */ +#define _POSIX_MESSAGE_PASSING (-1) /* [MSG] */ +#define _POSIX_MONOTONIC_CLOCK (-1) /* [MON] */ +#define _POSIX_NO_TRUNC 200112L +#define _POSIX_PRIORITIZED_IO (-1) /* [PIO] */ +#define _POSIX_PRIORITY_SCHEDULING (-1) /* [PS] */ +#define _POSIX_RAW_SOCKETS (-1) /* [RS] */ +#define _POSIX_READER_WRITER_LOCKS 200112L /* [THR] */ +#define _POSIX_REALTIME_SIGNALS (-1) /* [RTS] */ +#define _POSIX_REGEXP 200112L +#define _POSIX_SAVED_IDS 200112L /* XXX required */ +#define _POSIX_SEMAPHORES (-1) /* [SEM] */ +#define _POSIX_SHARED_MEMORY_OBJECTS (-1) /* [SHM] */ +#define _POSIX_SHELL 200112L +#define _POSIX_SPAWN (-1) /* [SPN] */ +#define _POSIX_SPIN_LOCKS (-1) /* [SPI] */ +#define _POSIX_SPORADIC_SERVER (-1) /* [SS] */ +#define _POSIX_SYNCHRONIZED_IO (-1) /* [SIO] */ +#define _POSIX_THREAD_ATTR_STACKADDR 200112L /* [TSA] */ +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L /* [TSS] */ +#define _POSIX_THREAD_CPUTIME (-1) /* [TCT] */ +#define _POSIX_THREAD_PRIO_INHERIT (-1) /* [TPI] */ +#define _POSIX_THREAD_PRIO_PROTECT (-1) /* [TPP] */ +#define _POSIX_THREAD_PRIORITY_SCHEDULING (-1) /* [TPS] */ +#define _POSIX_THREAD_PROCESS_SHARED 200112L /* [TSH] */ +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L /* [TSF] */ +#define _POSIX_THREAD_SPORADIC_SERVER (-1) /* [TSP] */ +#define _POSIX_THREADS 200112L /* [THR] */ +#define _POSIX_TIMEOUTS (-1) /* [TMO] */ +#define _POSIX_TIMERS (-1) /* [TMR] */ +#define _POSIX_TRACE (-1) /* [TRC] */ +#define _POSIX_TRACE_EVENT_FILTER (-1) /* [TEF] */ +#define _POSIX_TRACE_INHERIT (-1) /* [TRI] */ +#define _POSIX_TRACE_LOG (-1) /* [TRL] */ +#define _POSIX_TYPED_MEMORY_OBJECTS (-1) /* [TYM] */ +#ifndef _POSIX_VDISABLE +#define _POSIX_VDISABLE 0xff /* same as sys/termios.h */ +#endif /* _POSIX_VDISABLE */ + +#if __DARWIN_C_LEVEL >= 199209L +#define _POSIX2_C_BIND 200112L +#define _POSIX2_C_DEV 200112L /* c99 command */ +#define _POSIX2_CHAR_TERM 200112L +#define _POSIX2_FORT_DEV (-1) /* fort77 command */ +#define _POSIX2_FORT_RUN 200112L +#define _POSIX2_LOCALEDEF 200112L /* localedef command */ +#define _POSIX2_PBS (-1) +#define _POSIX2_PBS_ACCOUNTING (-1) +#define _POSIX2_PBS_CHECKPOINT (-1) +#define _POSIX2_PBS_LOCATE (-1) +#define _POSIX2_PBS_MESSAGE (-1) +#define _POSIX2_PBS_TRACK (-1) +#define _POSIX2_SW_DEV 200112L +#define _POSIX2_UPE 200112L /* XXXX no fc, newgrp, tabs */ +#endif /* __DARWIN_C_LEVEL */ + +#define __ILP32_OFF32 (-1) +#define __ILP32_OFFBIG (-1) + +#define __LP64_OFF64 (1) +#define __LPBIG_OFFBIG (1) + +#if __DARWIN_C_LEVEL >= 200112L +#define _POSIX_V6_ILP32_OFF32 __ILP32_OFF32 +#define _POSIX_V6_ILP32_OFFBIG __ILP32_OFFBIG +#define _POSIX_V6_LP64_OFF64 __LP64_OFF64 +#define _POSIX_V6_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 200809L +#define _POSIX_V7_ILP32_OFF32 __ILP32_OFF32 +#define _POSIX_V7_ILP32_OFFBIG __ILP32_OFFBIG +#define _POSIX_V7_LP64_OFF64 __LP64_OFF64 +#define _POSIX_V7_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= 200809L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _V6_ILP32_OFF32 __ILP32_OFF32 +#define _V6_ILP32_OFFBIG __ILP32_OFFBIG +#define _V6_LP64_OFF64 __LP64_OFF64 +#define _V6_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _XBS5_ILP32_OFF32 __ILP32_OFF32 +#define _XBS5_ILP32_OFFBIG __ILP32_OFFBIG +#define _XBS5_LP64_OFF64 __LP64_OFF64 +#define _XBS5_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL < 200809L */ + +#if __DARWIN_C_LEVEL >= 199506L /* This really should be XSI */ +#define _XOPEN_CRYPT (1) +#define _XOPEN_ENH_I18N (1) /* XXX required */ +#define _XOPEN_LEGACY (-1) /* no ftime gcvt, wcswcs */ +#define _XOPEN_REALTIME (-1) /* no q'ed signals, mq_* */ +#define _XOPEN_REALTIME_THREADS (-1) /* no posix_spawn, et. al. */ +#define _XOPEN_SHM (1) +#define _XOPEN_STREAMS (-1) /* Issue 6 */ +#define _XOPEN_UNIX (1) +#endif /* XSI */ + +/* configurable system variables */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _SC_CLK_TCK 3 +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 +#define _SC_BC_BASE_MAX 9 +#define _SC_BC_DIM_MAX 10 +#define _SC_BC_SCALE_MAX 11 +#define _SC_BC_STRING_MAX 12 +#define _SC_COLL_WEIGHTS_MAX 13 +#define _SC_EXPR_NEST_MAX 14 +#define _SC_LINE_MAX 15 +#define _SC_RE_DUP_MAX 16 +#define _SC_2_VERSION 17 +#define _SC_2_C_BIND 18 +#define _SC_2_C_DEV 19 +#define _SC_2_CHAR_TERM 20 +#define _SC_2_FORT_DEV 21 +#define _SC_2_FORT_RUN 22 +#define _SC_2_LOCALEDEF 23 +#define _SC_2_SW_DEV 24 +#define _SC_2_UPE 25 +#define _SC_STREAM_MAX 26 +#define _SC_TZNAME_MAX 27 + +#if __DARWIN_C_LEVEL >= 199309L +#define _SC_ASYNCHRONOUS_IO 28 +#define _SC_PAGESIZE 29 +#define _SC_MEMLOCK 30 +#define _SC_MEMLOCK_RANGE 31 +#define _SC_MEMORY_PROTECTION 32 +#define _SC_MESSAGE_PASSING 33 +#define _SC_PRIORITIZED_IO 34 +#define _SC_PRIORITY_SCHEDULING 35 +#define _SC_REALTIME_SIGNALS 36 +#define _SC_SEMAPHORES 37 +#define _SC_FSYNC 38 +#define _SC_SHARED_MEMORY_OBJECTS 39 +#define _SC_SYNCHRONIZED_IO 40 +#define _SC_TIMERS 41 +#define _SC_AIO_LISTIO_MAX 42 +#define _SC_AIO_MAX 43 +#define _SC_AIO_PRIO_DELTA_MAX 44 +#define _SC_DELAYTIMER_MAX 45 +#define _SC_MQ_OPEN_MAX 46 +#define _SC_MAPPED_FILES 47 /* swap _SC_PAGESIZE vs. BSD */ +#define _SC_RTSIG_MAX 48 +#define _SC_SEM_NSEMS_MAX 49 +#define _SC_SEM_VALUE_MAX 50 +#define _SC_SIGQUEUE_MAX 51 +#define _SC_TIMER_MAX 52 +#endif /* __DARWIN_C_LEVEL >= 199309L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _SC_NPROCESSORS_CONF 57 +#define _SC_NPROCESSORS_ONLN 58 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if __DARWIN_C_LEVEL >= 200112L +#define _SC_2_PBS 59 +#define _SC_2_PBS_ACCOUNTING 60 +#define _SC_2_PBS_CHECKPOINT 61 +#define _SC_2_PBS_LOCATE 62 +#define _SC_2_PBS_MESSAGE 63 +#define _SC_2_PBS_TRACK 64 +#define _SC_ADVISORY_INFO 65 +#define _SC_BARRIERS 66 +#define _SC_CLOCK_SELECTION 67 +#define _SC_CPUTIME 68 +#define _SC_FILE_LOCKING 69 +#define _SC_GETGR_R_SIZE_MAX 70 +#define _SC_GETPW_R_SIZE_MAX 71 +#define _SC_HOST_NAME_MAX 72 +#define _SC_LOGIN_NAME_MAX 73 +#define _SC_MONOTONIC_CLOCK 74 +#define _SC_MQ_PRIO_MAX 75 +#define _SC_READER_WRITER_LOCKS 76 +#define _SC_REGEXP 77 +#define _SC_SHELL 78 +#define _SC_SPAWN 79 +#define _SC_SPIN_LOCKS 80 +#define _SC_SPORADIC_SERVER 81 +#define _SC_THREAD_ATTR_STACKADDR 82 +#define _SC_THREAD_ATTR_STACKSIZE 83 +#define _SC_THREAD_CPUTIME 84 +#define _SC_THREAD_DESTRUCTOR_ITERATIONS 85 +#define _SC_THREAD_KEYS_MAX 86 +#define _SC_THREAD_PRIO_INHERIT 87 +#define _SC_THREAD_PRIO_PROTECT 88 +#define _SC_THREAD_PRIORITY_SCHEDULING 89 +#define _SC_THREAD_PROCESS_SHARED 90 +#define _SC_THREAD_SAFE_FUNCTIONS 91 +#define _SC_THREAD_SPORADIC_SERVER 92 +#define _SC_THREAD_STACK_MIN 93 +#define _SC_THREAD_THREADS_MAX 94 +#define _SC_TIMEOUTS 95 +#define _SC_THREADS 96 +#define _SC_TRACE 97 +#define _SC_TRACE_EVENT_FILTER 98 +#define _SC_TRACE_INHERIT 99 +#define _SC_TRACE_LOG 100 +#define _SC_TTY_NAME_MAX 101 +#define _SC_TYPED_MEMORY_OBJECTS 102 +#define _SC_V6_ILP32_OFF32 103 +#define _SC_V6_ILP32_OFFBIG 104 +#define _SC_V6_LP64_OFF64 105 +#define _SC_V6_LPBIG_OFFBIG 106 +#define _SC_IPV6 118 +#define _SC_RAW_SOCKETS 119 +#define _SC_SYMLOOP_MAX 120 +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 199506L /* Really XSI */ +#define _SC_ATEXIT_MAX 107 +#define _SC_IOV_MAX 56 +#define _SC_PAGE_SIZE _SC_PAGESIZE +#define _SC_XOPEN_CRYPT 108 +#define _SC_XOPEN_ENH_I18N 109 +#define _SC_XOPEN_LEGACY 110 /* Issue 6 */ +#define _SC_XOPEN_REALTIME 111 /* Issue 6 */ +#define _SC_XOPEN_REALTIME_THREADS 112 /* Issue 6 */ +#define _SC_XOPEN_SHM 113 +#define _SC_XOPEN_STREAMS 114 /* Issue 6 */ +#define _SC_XOPEN_UNIX 115 +#define _SC_XOPEN_VERSION 116 +#define _SC_XOPEN_XCU_VERSION 121 +#endif /* XSI */ + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _SC_XBS5_ILP32_OFF32 122 +#define _SC_XBS5_ILP32_OFFBIG 123 +#define _SC_XBS5_LP64_OFF64 124 +#define _SC_XBS5_LPBIG_OFFBIG 125 +#endif /* __DARWIN_C_LEVEL <= 200809L */ + +#if __DARWIN_C_LEVEL >= 200112L +#define _SC_SS_REPL_MAX 126 +#define _SC_TRACE_EVENT_NAME_MAX 127 +#define _SC_TRACE_NAME_MAX 128 +#define _SC_TRACE_SYS_MAX 129 +#define _SC_TRACE_USER_EVENT_MAX 130 +#endif + +#if __DARWIN_C_LEVEL < 200112L || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 6 */ +#define _SC_PASS_MAX 131 +#endif + +/* 132-199 available for future use */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _SC_PHYS_PAGES 200 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if __DARWIN_C_LEVEL >= 199209L +#ifndef _CS_PATH /* Defined in */ +#define _CS_PATH 1 +#endif +#endif + +#if __DARWIN_C_LEVEL >= 200112 +#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 +#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 +#define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 +#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5 +#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6 +#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7 +#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8 +#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9 +#define _CS_POSIX_V6_LP64_OFF64_LIBS 10 +#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11 +#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12 +#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13 +#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14 +#endif + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _CS_XBS5_ILP32_OFF32_CFLAGS 20 +#define _CS_XBS5_ILP32_OFF32_LDFLAGS 21 +#define _CS_XBS5_ILP32_OFF32_LIBS 22 +#define _CS_XBS5_ILP32_OFF32_LINTFLAGS 23 +#define _CS_XBS5_ILP32_OFFBIG_CFLAGS 24 +#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS 25 +#define _CS_XBS5_ILP32_OFFBIG_LIBS 26 +#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 27 +#define _CS_XBS5_LP64_OFF64_CFLAGS 28 +#define _CS_XBS5_LP64_OFF64_LDFLAGS 29 +#define _CS_XBS5_LP64_OFF64_LIBS 30 +#define _CS_XBS5_LP64_OFF64_LINTFLAGS 31 +#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS 32 +#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 33 +#define _CS_XBS5_LPBIG_OFFBIG_LIBS 34 +#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 35 +#endif + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _CS_DARWIN_USER_DIR 65536 +#define _CS_DARWIN_USER_TEMP_DIR 65537 +#define _CS_DARWIN_USER_CACHE_DIR 65538 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + +#ifdef _DARWIN_UNLIMITED_GETGROUPS +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 +#error "_DARWIN_UNLIMITED_GETGROUPS specified, but -miphoneos-version-min version does not support it." +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 +#error "_DARWIN_UNLIMITED_GETGROUPS specified, but -mmacosx-version-min version does not support it." +#endif +#endif + +/* POSIX.1-1990 */ + +__BEGIN_DECLS +void _exit(int) __dead2; +int access(const char *, int); +unsigned int + alarm(unsigned int); +int chdir(const char *); +int chown(const char *, uid_t, gid_t); + +int close(int) __DARWIN_ALIAS_C(close); + +int dup(int); +int dup2(int, int); +int execl(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execle(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execlp(const char * __file, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execv(const char * __path, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execve(const char * __file, char * const * __argv, char * const * __envp) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execvp(const char * __file, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +pid_t fork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +long fpathconf(int, int); +char *getcwd(char *, size_t); +gid_t getegid(void); +uid_t geteuid(void); +gid_t getgid(void); +#if defined(_DARWIN_UNLIMITED_GETGROUPS) || defined(_DARWIN_C_SOURCE) +int getgroups(int, gid_t []) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(getgroups)); +#else /* !_DARWIN_UNLIMITED_GETGROUPS && !_DARWIN_C_SOURCE */ +int getgroups(int, gid_t []); +#endif /* _DARWIN_UNLIMITED_GETGROUPS || _DARWIN_C_SOURCE */ +char *getlogin(void); +pid_t getpgrp(void); +pid_t getpid(void); +pid_t getppid(void); +uid_t getuid(void); +int isatty(int); +int link(const char *, const char *); +off_t lseek(int, off_t, int); +long pathconf(const char *, int); + +int pause(void) __DARWIN_ALIAS_C(pause); + +int pipe(int [2]); + +ssize_t read(int, void *, size_t) __DARWIN_ALIAS_C(read); + +int rmdir(const char *); +int setgid(gid_t); +int setpgid(pid_t, pid_t); +pid_t setsid(void); +int setuid(uid_t); + +unsigned int + sleep(unsigned int) __DARWIN_ALIAS_C(sleep); + +long sysconf(int); +pid_t tcgetpgrp(int); +int tcsetpgrp(int, pid_t); +char *ttyname(int); + +#if __DARWIN_UNIX03 +int ttyname_r(int, char *, size_t) __DARWIN_ALIAS(ttyname_r); +#else /* !__DARWIN_UNIX03 */ +char *ttyname_r(int, char *, size_t); +#endif /* __DARWIN_UNIX03 */ + +int unlink(const char *); + +ssize_t write(int __fd, const void * __buf, size_t __nbyte) __DARWIN_ALIAS_C(write); +__END_DECLS + + + +/* Additional functionality provided by: + * POSIX.2-1992 C Language Binding Option + */ + +#if __DARWIN_C_LEVEL >= 199209L +__BEGIN_DECLS +size_t confstr(int, char *, size_t) __DARWIN_ALIAS(confstr); + +int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt); + +extern char *optarg; /* getopt(3) external variables */ +extern int optind, opterr, optopt; +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199209L */ + + + +/* Additional functionality provided by: + * POSIX.1c-1995, + * POSIX.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + */ + +#if __DARWIN_C_LEVEL >= 199506L +#include <_ctermid.h> + /* These F_* are really XSI or Issue 6 */ +#define F_ULOCK 0 /* unlock locked section */ +#define F_LOCK 1 /* lock a section for exclusive use */ +#define F_TLOCK 2 /* test and lock a section for exclusive use */ +#define F_TEST 3 /* test a section for locks by other procs */ + + __BEGIN_DECLS + +/* Begin XSI */ +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +#if !defined(_POSIX_C_SOURCE) +__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED +#endif +void *brk(const void *); +int chroot(const char *) __POSIX_C_DEPRECATED(199506L); +#endif + +char *crypt(const char *, const char *); +#if __DARWIN_UNIX03 +void encrypt(char *, int) __DARWIN_ALIAS(encrypt); +#else /* !__DARWIN_UNIX03 */ +int encrypt(char *, int); +#endif /* __DARWIN_UNIX03 */ +int fchdir(int); +long gethostid(void); +pid_t getpgid(pid_t); +pid_t getsid(pid_t); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +int getdtablesize(void) __POSIX_C_DEPRECATED(199506L); +int getpagesize(void) __pure2 __POSIX_C_DEPRECATED(199506L); +char *getpass(const char *) __POSIX_C_DEPRECATED(199506L); +#endif + +/* Removed in Issue 7 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L +char *getwd(char *) __POSIX_C_DEPRECATED(200112L); /* obsoleted by getcwd() */ +#endif + +int lchown(const char *, uid_t, gid_t) __DARWIN_ALIAS(lchown); + +int lockf(int, int, off_t) __DARWIN_ALIAS_C(lockf); + +int nice(int) __DARWIN_ALIAS(nice); + +ssize_t pread(int __fd, void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pread); + +ssize_t pwrite(int __fd, const void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pwrite); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +/* Note that Issue 5 changed the argument as intprt_t, + * but we keep it as int for binary compatability. */ +#if !defined(_POSIX_C_SOURCE) +__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED +#endif +void *sbrk(int); +#endif + +#if __DARWIN_UNIX03 +pid_t setpgrp(void) __DARWIN_ALIAS(setpgrp); +#else /* !__DARWIN_UNIX03 */ +int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */ +#endif /* __DARWIN_UNIX03 */ + +int setregid(gid_t, gid_t) __DARWIN_ALIAS(setregid); + +int setreuid(uid_t, uid_t) __DARWIN_ALIAS(setreuid); + +void swab(const void * __restrict, void * __restrict, ssize_t); +void sync(void); +int truncate(const char *, off_t); +useconds_t ualarm(useconds_t, useconds_t); +int usleep(useconds_t) __DARWIN_ALIAS_C(usleep); +pid_t vfork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +/* End XSI */ + +int fsync(int) __DARWIN_ALIAS_C(fsync); + +int ftruncate(int, off_t); +int getlogin_r(char *, size_t); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199506L */ + + + +/* Additional functionality provided by: + * POSIX.1-2001 + * ISO C99 + */ + +#if __DARWIN_C_LEVEL >= 200112L +__BEGIN_DECLS +int fchown(int, uid_t, gid_t); +int gethostname(char *, size_t); +ssize_t readlink(const char * __restrict, char * __restrict, size_t); +int setegid(gid_t); +int seteuid(uid_t); +int symlink(const char *, const char *); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#include + +#include +#include +#include + +__BEGIN_DECLS +void _Exit(int) __dead2; +int accessx_np(const struct accessx_descriptor *, size_t, int *, uid_t); +int acct(const char *); +int add_profil(char *, size_t, unsigned long, unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +void endusershell(void); +int execvP(const char * __file, const char * __searchpath, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +char *fflagstostr(unsigned long); +int getdomainname(char *, int); +int getgrouplist(const char *, int, int *, int *); +#if defined(__has_include) +#if __has_include() +#include +#else +#include +#endif +#else +#include +#endif +mode_t getmode(const void *, mode_t); +int getpeereid(int, uid_t *, gid_t *); +int getsgroups_np(int *, uuid_t); +char *getusershell(void); +int getwgroups_np(int *, uuid_t); +int initgroups(const char *, int); +int issetugid(void); +char *mkdtemp(char *); +int mknod(const char *, mode_t, dev_t); +int mkpath_np(const char *path, mode_t omode) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); /* returns errno */ +int mkpathat_np(int dfd, const char *path, mode_t omode) /* returns errno */ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +int mkstemp(char *); +int mkstemps(char *, int); +char *mktemp(char *); +int mkostemp(char *path, int oflags) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +int mkostemps(char *path, int slen, int oflags) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +/* Non-portable mkstemp that uses open_dprotected_np */ +int mkstemp_dprotected_np(char *path, int dpclass, int dpflags) + __OSX_UNAVAILABLE __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +char *mkdtempat_np(int dfd, char *path) + __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) + __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +int mkstempsat_np(int dfd, char *path, int slen) + __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) + __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +int mkostempsat_np(int dfd, char *path, int slen, int oflags) + __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) + __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +int nfssvc(int, void *); +int profil(char *, size_t, unsigned long, unsigned int); + +__deprecated_msg("Use of per-thread security contexts is error-prone and discouraged.") +int pthread_setugid_np(uid_t, gid_t); +int pthread_getugid_np( uid_t *, gid_t *); + +int reboot(int); +int revoke(const char *); + +__deprecated int rcmd(char **, int, const char *, const char *, const char *, int *); +__deprecated int rcmd_af(char **, int, const char *, const char *, const char *, int *, + int); +__deprecated int rresvport(int *); +__deprecated int rresvport_af(int *, int); +__deprecated int iruserok(unsigned long, int, const char *, const char *); +__deprecated int iruserok_sa(const void *, int, int, const char *, const char *); +__deprecated int ruserok(const char *, int, const char *, const char *); + +int setdomainname(const char *, int); +int setgroups(int, const gid_t *); +void sethostid(long); +int sethostname(const char *, int); +#if __DARWIN_UNIX03 +void setkey(const char *) __DARWIN_ALIAS(setkey); +#else /* !__DARWIN_UNIX03 */ +int setkey(const char *); +#endif /* __DARWIN_UNIX03 */ +int setlogin(const char *); +void *setmode(const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(setmode)); +int setrgid(gid_t); +int setruid(uid_t); +int setsgroups_np(int, const uuid_t); +void setusershell(void); +int setwgroups_np(int, const uuid_t); +int strtofflags(char **, unsigned long *, unsigned long *); +int swapon(const char *); +int ttyslot(void); +int undelete(const char *); +int unwhiteout(const char *); +void *valloc(size_t); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +__OS_AVAILABILITY_MSG(ios,deprecated=10.0,"syscall(2) is unsupported; " + "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") +__OS_AVAILABILITY_MSG(macosx,deprecated=10.12,"syscall(2) is unsupported; " + "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") +int syscall(int, ...); + +extern char *suboptarg; /* getsubopt(3) external variable */ +int getsubopt(char **, char * const *, char **); + +/* HFS & HFS Plus semantics system calls go here */ +#ifdef __LP64__ +int fgetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int fsetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int getattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(getattrlist); +int setattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(setattrlist); +int exchangedata(const char*,const char*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; + +#else /* __LP64__ */ +int fgetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int fsetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int getattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(getattrlist); +int setattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(setattrlist); +int exchangedata(const char*,const char*,unsigned long) + __OSX_DEPRECATED(10.0, 10.13, "use renamex_np with the RENAME_SWAP flag") + __IOS_DEPRECATED(2.0, 11.0, "use renamex_np with the RENAME_SWAP flag") + __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; + +#endif /* __LP64__ */ + +struct fssearchblock; +struct searchstate; + +int searchfs(const char *, struct fssearchblock *, unsigned long *, unsigned int, unsigned int, struct searchstate *) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int fsctl(const char *,unsigned long,void*,unsigned int); +int ffsctl(int,unsigned long,void*,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); + +#define SYNC_VOLUME_FULLSYNC 0x01 /* Flush data and metadata to platter, not just to disk cache */ +#define SYNC_VOLUME_WAIT 0x02 /* Wait for sync to complete */ + +int fsync_volume_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); +int sync_volume_np(const char *, int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); + +extern int optreset; + +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#endif /* _UNISTD_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/uuid/uuid.h b/lib/libc/include/any-macos.11-any/uuid/uuid.h new file mode 100644 index 0000000000..ce75c9e0e1 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/uuid/uuid.h @@ -0,0 +1,79 @@ +/* + * Public include file for the UUID library + * + * Copyright (C) 1996, 1997, 1998 Theodore Ts'o. + * + * %Begin-Header% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * %End-Header% + */ + +#ifndef _UUID_UUID_H +#define _UUID_UUID_H + +#include +#include + +#ifndef _UUID_STRING_T +#define _UUID_STRING_T +typedef __darwin_uuid_string_t uuid_string_t; +#endif /* _UUID_STRING_T */ + +#define UUID_DEFINE(name, u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15) \ + static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15} + +UUID_DEFINE(UUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +#ifdef __cplusplus +extern "C" { +#endif + +void uuid_clear(uuid_t uu); + +int uuid_compare(const uuid_t uu1, const uuid_t uu2); + +void uuid_copy(uuid_t dst, const uuid_t src); + +void uuid_generate(uuid_t out); +void uuid_generate_random(uuid_t out); +void uuid_generate_time(uuid_t out); + +void uuid_generate_early_random(uuid_t out); + +int uuid_is_null(const uuid_t uu); + +int uuid_parse(const uuid_string_t in, uuid_t uu); + +void uuid_unparse(const uuid_t uu, uuid_string_t out); +void uuid_unparse_lower(const uuid_t uu, uuid_string_t out); +void uuid_unparse_upper(const uuid_t uu, uuid_string_t out); + +#ifdef __cplusplus +} +#endif + +#endif /* _UUID_UUID_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/xpc/activity.h b/lib/libc/include/any-macos.11-any/xpc/activity.h new file mode 100644 index 0000000000..c48051f145 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/xpc/activity.h @@ -0,0 +1,446 @@ +#ifndef __XPC_ACTIVITY_H__ +#define __XPC_ACTIVITY_H__ + +#ifndef __XPC_INDIRECT__ +#error "Please #include instead of this file directly." +// For HeaderDoc. +#include +#endif // __XPC_INDIRECT__ + +#ifdef __BLOCKS__ + +XPC_ASSUME_NONNULL_BEGIN +__BEGIN_DECLS + +/* + * The following are a collection of keys and values used to set an activity's + * execution criteria. + */ + +/*! + * @constant XPC_ACTIVITY_INTERVAL + * An integer property indicating the desired time interval (in seconds) of the + * activity. The activity will not be run more than once per time interval. + * Due to the nature of XPC Activity finding an opportune time to run + * the activity, any two occurrences may be more or less than 'interval' + * seconds apart, but on average will be 'interval' seconds apart. + * The presence of this key implies the following, unless overridden: + * - XPC_ACTIVITY_REPEATING with a value of true + * - XPC_ACTIVITY_DELAY with a value of half the 'interval' + * The delay enforces a minimum distance between any two occurrences. + * - XPC_ACTIVITY_GRACE_PERIOD with a value of half the 'interval'. + * The grace period is the amount of time allowed to pass after the end of + * the interval before more aggressive scheduling occurs. The grace period + * does not increase the size of the interval. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_INTERVAL; + +/*! + * @constant XPC_ACTIVITY_REPEATING + * A boolean property indicating whether this is a repeating activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_REPEATING; + +/*! + * @constant XPC_ACTIVITY_DELAY + * An integer property indicating the number of seconds to delay before + * beginning the activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_DELAY; + +/*! + * @constant XPC_ACTIVITY_GRACE_PERIOD + * An integer property indicating the number of seconds to allow as a grace + * period before the scheduling of the activity becomes more aggressive. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_GRACE_PERIOD; + + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_1_MIN; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_5_MIN; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_15_MIN; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_30_MIN; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_1_HOUR; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_4_HOURS; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_8_HOURS; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_1_DAY; + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const int64_t XPC_ACTIVITY_INTERVAL_7_DAYS; + +/*! + * @constant XPC_ACTIVITY_PRIORITY + * A string property indicating the priority of the activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_PRIORITY; + +/*! + * @constant XPC_ACTIVITY_PRIORITY_MAINTENANCE + * A string indicating activity is maintenance priority. + * + * Maintenance priority is intended for user-invisible maintenance tasks + * such as garbage collection or optimization. + * + * Maintenance activities are not permitted to run if the device thermal + * condition exceeds a nominal level or if the battery level is lower than 20%. + * In Low Power Mode (on supported devices), maintenance activities are not + * permitted to run while the device is on battery, or plugged in and the + * battery level is lower than 30%. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_PRIORITY_MAINTENANCE; + +/*! + * @constant XPC_ACTIVITY_PRIORITY_UTILITY + * A string indicating activity is utility priority. + * + * Utility priority is intended for user-visible tasks such as fetching data + * from the network, copying files, or importing data. + * + * Utility activities are not permitted to run if the device thermal condition + * exceeds a moderate level or if the battery level is less than 10%. In Low + * Power Mode (on supported devices) when on battery power, utility activities + * are only permitted when they are close to their deadline (90% of their time + * window has elapsed). + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_PRIORITY_UTILITY; + +/*! + * @constant XPC_ACTIVITY_ALLOW_BATTERY + * A Boolean value indicating whether the activity should be allowed to run + * while the computer is on battery power. The default value is false for + * maintenance priority activity and true for utility priority activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_ALLOW_BATTERY; + +/*! + * @constant XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP + * A Boolean value indicating whether the activity should only be performed + * while device appears to be asleep. Note that the definition of screen sleep + * may vary by platform and may include states where the device is known to be + * idle despite the fact that the display itself is still powered. Defaults to + * false. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const char * const XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP; // bool + +/*! + * @constant XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL + * An integer percentage of minimum battery charge required to allow the + * activity to run. A default minimum battery level is determined by the + * system. + */ +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_9, __MAC_10_9, __IPHONE_7_0, __IPHONE_7_0, + "REQUIRE_BATTERY_LEVEL is not implemented") +XPC_EXPORT +const char * const XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL; // int (%) + +/*! + * @constant XPC_ACTIVITY_REQUIRE_HDD_SPINNING + * A Boolean value indicating whether the activity should only be performed + * while the hard disk drive (HDD) is spinning. Computers with flash storage + * are considered to be equivalent to HDD spinning. Defaults to false. + */ +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_9, __MAC_10_9, __IPHONE_7_0, __IPHONE_7_0, + "REQUIRE_HDD_SPINNING is not implemented") +XPC_EXPORT +const char * const XPC_ACTIVITY_REQUIRE_HDD_SPINNING; // bool + +/*! + * @define XPC_TYPE_ACTIVITY + * A type representing the XPC activity object. + */ +#define XPC_TYPE_ACTIVITY (&_xpc_type_activity) +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +XPC_TYPE(_xpc_type_activity); + +/*! + * @typedef xpc_activity_t + * + * @abstract + * An XPC activity object. + * + * @discussion + * This object represents a set of execution criteria and a current execution + * state for background activity on the system. Once an activity is registered, + * the system will evaluate its criteria to determine whether the activity is + * eligible to run under current system conditions. When an activity becomes + * eligible to run, its execution state will be updated and an invocation of + * its handler block will be made. + */ +XPC_DECL(xpc_activity); + +/*! + * @typedef xpc_activity_handler_t + * + * @abstract + * A block that is called when an XPC activity becomes eligible to run. + */ +XPC_NONNULL1 +typedef void (^xpc_activity_handler_t)(xpc_activity_t activity); + +/*! + * @constant XPC_ACTIVITY_CHECK_IN + * This constant may be passed to xpc_activity_register() as the criteria + * dictionary in order to check in with the system for previously registered + * activity using the same identifier (for example, an activity taken from a + * launchd property list). + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT +const xpc_object_t XPC_ACTIVITY_CHECK_IN; + +/*! + * @function xpc_activity_register + * + * @abstract + * Registers an activity with the system. + * + * @discussion + * Registers a new activity with the system. The criteria of the activity are + * described by the dictionary passed to this function. If an activity with the + * same identifier already exists, the criteria provided override the existing + * criteria unless the special dictionary XPC_ACTIVITY_CHECK_IN is used. The + * XPC_ACTIVITY_CHECK_IN dictionary instructs the system to first look up an + * existing activity without modifying its criteria. Once the existing activity + * is found (or a new one is created with an empty set of criteria) the handler + * will be called with an activity object in the XPC_ACTIVITY_STATE_CHECK_IN + * state. + * + * @param identifier + * A unique identifier for the activity. Each application has its own namespace. + * The identifier should remain constant across registrations, relaunches of + * the application, and reboots. It should identify the kind of work being done, + * not a particular invocation of the work. + * + * @param criteria + * A dictionary of criteria for the activity. + * + * @param handler + * The handler block to be called when the activity changes state to one of the + * following states: + * - XPC_ACTIVITY_STATE_CHECK_IN (optional) + * - XPC_ACTIVITY_STATE_RUN + * + * The handler block is never invoked reentrantly. It will be invoked on a + * dispatch queue with an appropriate priority to perform the activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 XPC_NONNULL3 +void +xpc_activity_register(const char *identifier, xpc_object_t criteria, + xpc_activity_handler_t handler); + +/*! + * @function xpc_activity_copy_criteria + * + * @abstract + * Returns an XPC dictionary describing the execution criteria of an activity. + * This will return NULL in cases where the activity has already completed, e.g. + * when checking in to an event that finished and was not rescheduled. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_RETURNS_RETAINED XPC_NONNULL1 +xpc_object_t _Nullable +xpc_activity_copy_criteria(xpc_activity_t activity); + +/*! + * @function xpc_activity_set_criteria + * + * @abstract + * Modifies the execution criteria of an activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 +void +xpc_activity_set_criteria(xpc_activity_t activity, xpc_object_t criteria); + +/*! + * @enum xpc_activity_state_t + * An activity is defined to be in one of the following states. Applications + * may check the current state of the activity using xpc_activity_get_state() + * in the handler block provided to xpc_activity_register(). + * + * The application can modify the state of the activity by calling + * xpc_activity_set_state() with one of the following: + * - XPC_ACTIVITY_STATE_DEFER + * - XPC_ACTIVITY_STATE_CONTINUE + * - XPC_ACTIVITY_STATE_DONE + * + * @constant XPC_ACTIVITY_STATE_CHECK_IN + * An activity in this state has just completed a checkin with the system after + * XPC_ACTIVITY_CHECK_IN was provided as the criteria dictionary to + * xpc_activity_register. The state gives the application an opportunity to + * inspect and modify the activity's criteria. + * + * @constant XPC_ACTIVITY_STATE_WAIT + * An activity in this state is waiting for an opportunity to run. This value + * is never returned within the activity's handler block, as the block is + * invoked in response to XPC_ACTIVITY_STATE_CHECK_IN or XPC_ACTIVITY_STATE_RUN. + * + * Note: + * A launchd job may idle exit while an activity is in the wait state and be + * relaunched in response to the activity becoming runnable. The launchd job + * simply needs to re-register for the activity on its next launch by passing + * XPC_ACTIVITY_STATE_CHECK_IN to xpc_activity_register(). + * + * @constant XPC_ACTIVITY_STATE_RUN + * An activity in this state is eligible to run based on its criteria. + * + * @constant XPC_ACTIVITY_STATE_DEFER + * An application may pass this value to xpc_activity_set_state() to indicate + * that the activity should be deferred (placed back into the WAIT state) until + * a time when its criteria are met again. Deferring an activity does not reset + * any of its time-based criteria (in other words, it will remain past due). + * + * IMPORTANT: + * This should be done in response to observing xpc_activity_should_defer(). + * It should not be done unilaterally. If you determine that conditions are bad + * to do your activity's work for reasons you can't express in a criteria + * dictionary, you should set the activity's state to XPC_ACTIVITY_STATE_DONE. + * + * + * @constant XPC_ACTIVITY_STATE_CONTINUE + * An application may pass this value to xpc_activity_set_state() to indicate + * that the activity will continue its operation beyond the return of its + * handler block. This can be used to extend an activity to include asynchronous + * operations. The activity's handler block will not be invoked again until the + * state has been updated to either XPC_ACTIVITY_STATE_DEFER or, in the case + * of repeating activity, XPC_ACTIVITY_STATE_DONE. + * + * @constant XPC_ACTIVITY_STATE_DONE + * An application may pass this value to xpc_activity_set_state() to indicate + * that the activity has completed. For non-repeating activity, the resources + * associated with the activity will be automatically released upon return from + * the handler block. For repeating activity, timers present in the activity's + * criteria will be reset. + */ +enum { + XPC_ACTIVITY_STATE_CHECK_IN, + XPC_ACTIVITY_STATE_WAIT, + XPC_ACTIVITY_STATE_RUN, + XPC_ACTIVITY_STATE_DEFER, + XPC_ACTIVITY_STATE_CONTINUE, + XPC_ACTIVITY_STATE_DONE, +}; +typedef long xpc_activity_state_t; + +/*! + * @function xpc_activity_get_state + * + * @abstract + * Returns the current state of an activity. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 +xpc_activity_state_t +xpc_activity_get_state(xpc_activity_t activity); + +/*! + * @function xpc_activity_set_state + * + * @abstract + * Updates the current state of an activity. + * + * @return + * Returns true if the state was successfully updated; otherwise, returns + * false if the requested state transition is not valid. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 +bool +xpc_activity_set_state(xpc_activity_t activity, xpc_activity_state_t state); + +/*! + * @function xpc_activity_should_defer + * + * @abstract + * Test whether an activity should be deferred. + * + * @discussion + * This function may be used to test whether the criteria of a long-running + * activity are still satisfied. If not, the system indicates that the + * application should defer the activity. The application may acknowledge the + * deferral by calling xpc_activity_set_state() with XPC_ACTIVITY_STATE_DEFER. + * Once deferred, the system will place the activity back into the WAIT state + * and re-invoke the handler block at the earliest opportunity when the criteria + * are once again satisfied. + * + * @return + * Returns true if the activity should be deferred. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 +bool +xpc_activity_should_defer(xpc_activity_t activity); + +/*! + * @function xpc_activity_unregister + * + * @abstract + * Unregisters an activity found by its identifier. + * + * @discussion + * A dynamically registered activity will be deleted in response to this call. + * Statically registered activity (from a launchd property list) will be + * deleted until the job is next loaded (e.g. at next boot). + * + * Unregistering an activity has no effect on any outstanding xpc_activity_t + * objects or any currently executing xpc_activity_handler_t blocks; however, + * no new handler block invocations will be made after it is unregistered. + * + * @param identifier + * The identifier of the activity to unregister. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +XPC_EXPORT XPC_NONNULL1 +void +xpc_activity_unregister(const char *identifier); + +__END_DECLS +XPC_ASSUME_NONNULL_END + +#endif // __BLOCKS__ + +#endif // __XPC_ACTIVITY_H__ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/xpc/availability.h b/lib/libc/include/any-macos.11-any/xpc/availability.h new file mode 100644 index 0000000000..4005a84bdf --- /dev/null +++ b/lib/libc/include/any-macos.11-any/xpc/availability.h @@ -0,0 +1,124 @@ +#ifndef __XPC_AVAILABILITY_H__ +#define __XPC_AVAILABILITY_H__ + +#include + +// Certain parts of the project use all the project's headers but have to build +// against newer OSX SDKs than ebuild uses -- liblaunch_host being the example. +// So we need to define these. +#ifndef __MAC_10_16 +#define __MAC_10_16 101600 +#endif // __MAC_10_16 + +#ifndef __MAC_10_15 +#define __MAC_10_15 101500 +#define __AVAILABILITY_INTERNAL__MAC_10_15 \ +__attribute__((availability(macosx, introduced=10.15))) +#endif // __MAC_10_15 + +#ifndef __MAC_10_14 +#define __MAC_10_14 101400 +#define __AVAILABILITY_INTERNAL__MAC_10_14 \ +__attribute__((availability(macosx, introduced=10.14))) +#endif // __MAC_10_14 + +#ifndef __MAC_10_13 +#define __MAC_10_13 101300 +#define __AVAILABILITY_INTERNAL__MAC_10_13 \ + __attribute__((availability(macosx, introduced=10.13))) +#endif // __MAC_10_13 + +#ifndef __MAC_10_12 +#define __MAC_10_12 101200 +#define __AVAILABILITY_INTERNAL__MAC_10_12 \ + __attribute__((availability(macosx, introduced=10.12))) +#endif // __MAC_10_12 + +#ifndef __MAC_10_11 +#define __MAC_10_11 101100 +#define __AVAILABILITY_INTERNAL__MAC_10_11 \ + __attribute__((availability(macosx, introduced=10.11))) +#endif // __MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 +#define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 +#endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 + +#if __has_include() +#include +#else // __has_include() +#ifndef IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED +#define IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 999999 +#endif // IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED +#endif // __has_include() + +#ifndef __WATCHOS_UNAVAILABLE +#define __WATCHOS_UNAVAILABLE +#endif + +#ifndef __TVOS_UNAVAILABLE +#define __TVOS_UNAVAILABLE +#endif + +// simulator host-side bits build against SDKs not having __*_AVAILABLE() yet +#ifndef __OSX_AVAILABLE +#define __OSX_AVAILABLE(...) +#endif + +#ifndef __IOS_AVAILABLE +#define __IOS_AVAILABLE(...) +#endif + +#ifndef __TVOS_AVAILABLE +#define __TVOS_AVAILABLE(...) +#endif + +#ifndef __WATCHOS_AVAILABLE +#define __WATCHOS_AVAILABLE(...) +#endif + +#ifndef __API_AVAILABLE +#define __API_AVAILABLE(...) +#endif + +#endif // __XPC_AVAILABILITY_H__ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/xpc/base.h b/lib/libc/include/any-macos.11-any/xpc/base.h new file mode 100644 index 0000000000..ab708965cc --- /dev/null +++ b/lib/libc/include/any-macos.11-any/xpc/base.h @@ -0,0 +1,213 @@ +// Copyright (c) 2009-2011 Apple Inc. All rights reserved. + +#ifndef __XPC_BASE_H__ +#define __XPC_BASE_H__ + +#include + +__BEGIN_DECLS + +#if !defined(__has_include) +#define __has_include(x) 0 +#endif // !defined(__has_include) + +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif // !defined(__has_attribute) + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif // !defined(__has_feature) + +#if !defined(__has_extension) +#define __has_extension(x) 0 +#endif // !defined(__has_extension) + +#if __has_include() +#include +#else // __has_include() +#include +#endif // __has_include() + +#include + +#ifndef __XPC_INDIRECT__ +#error "Please #include instead of this file directly." +#endif // __XPC_INDIRECT__ + +#pragma mark Attribute Shims +#ifdef __GNUC__ +#define XPC_CONSTRUCTOR __attribute__((constructor)) +#define XPC_NORETURN __attribute__((__noreturn__)) +#define XPC_NOTHROW __attribute__((__nothrow__)) +#define XPC_NONNULL1 __attribute__((__nonnull__(1))) +#define XPC_NONNULL2 __attribute__((__nonnull__(2))) +#define XPC_NONNULL3 __attribute__((__nonnull__(3))) +#define XPC_NONNULL4 __attribute__((__nonnull__(4))) +#define XPC_NONNULL5 __attribute__((__nonnull__(5))) +#define XPC_NONNULL6 __attribute__((__nonnull__(6))) +#define XPC_NONNULL7 __attribute__((__nonnull__(7))) +#define XPC_NONNULL8 __attribute__((__nonnull__(8))) +#define XPC_NONNULL9 __attribute__((__nonnull__(9))) +#define XPC_NONNULL10 __attribute__((__nonnull__(10))) +#define XPC_NONNULL11 __attribute__((__nonnull__(11))) +#define XPC_NONNULL_ALL __attribute__((__nonnull__)) +#define XPC_SENTINEL __attribute__((__sentinel__)) +#define XPC_PURE __attribute__((__pure__)) +#define XPC_WARN_RESULT __attribute__((__warn_unused_result__)) +#define XPC_MALLOC __attribute__((__malloc__)) +#define XPC_UNUSED __attribute__((__unused__)) +#define XPC_USED __attribute__((__used__)) +#define XPC_PACKED __attribute__((__packed__)) +#define XPC_PRINTF(m, n) __attribute__((format(printf, m, n))) +#define XPC_INLINE static __inline__ __attribute__((__always_inline__)) +#define XPC_NOINLINE __attribute__((noinline)) +#define XPC_NOIMPL __attribute__((unavailable)) + +#if __has_attribute(noescape) +#define XPC_NOESCAPE __attribute__((__noescape__)) +#else +#define XPC_NOESCAPE +#endif + +#if __has_extension(attribute_unavailable_with_message) +#define XPC_UNAVAILABLE(m) __attribute__((unavailable(m))) +#else // __has_extension(attribute_unavailable_with_message) +#define XPC_UNAVAILABLE(m) XPC_NOIMPL +#endif // __has_extension(attribute_unavailable_with_message) + +#define XPC_EXPORT extern __attribute__((visibility("default"))) +#define XPC_NOEXPORT __attribute__((visibility("hidden"))) +#define XPC_WEAKIMPORT extern __attribute__((weak_import)) +#define XPC_DEBUGGER_EXCL XPC_NOEXPORT XPC_USED +#define XPC_TRANSPARENT_UNION __attribute__((transparent_union)) +#if __clang__ +#define XPC_DEPRECATED(m) __attribute__((deprecated(m))) +#else // __clang__ +#define XPC_DEPRECATED(m) __attribute__((deprecated)) +#endif // __clang + +#if defined(__XPC_TEST__) && __XPC_TEST__ +#define XPC_TESTSTATIC +#define XPC_TESTEXTERN extern +#else // defined(__XPC_TEST__) && __XPC_TEST__ +#define XPC_TESTSTATIC static +#endif // defined(__XPC_TEST__) && __XPC_TEST__ + +#if __has_feature(objc_arc) +#define XPC_GIVES_REFERENCE __strong +#define XPC_UNRETAINED __unsafe_unretained +#define XPC_BRIDGE(xo) ((__bridge void *)(xo)) +#define XPC_BRIDGEREF_BEGIN(xo) ((__bridge_retained void *)(xo)) +#define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) ((__bridge void *)(xo)) +#define XPC_BRIDGEREF_MIDDLE(xo) ((__bridge id)(xo)) +#define XPC_BRIDGEREF_END(xo) ((__bridge_transfer id)(xo)) +#else // __has_feature(objc_arc) +#define XPC_GIVES_REFERENCE +#define XPC_UNRETAINED +#define XPC_BRIDGE(xo) (xo) +#define XPC_BRIDGEREF_BEGIN(xo) (xo) +#define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) (xo) +#define XPC_BRIDGEREF_MIDDLE(xo) (xo) +#define XPC_BRIDGEREF_END(xo) (xo) +#endif // __has_feature(objc_arc) + +#define _xpc_unreachable() __builtin_unreachable() +#else // __GNUC__ +/*! @parseOnly */ +#define XPC_CONSTRUCTOR +/*! @parseOnly */ +#define XPC_NORETURN +/*! @parseOnly */ +#define XPC_NOTHROW +/*! @parseOnly */ +#define XPC_NONNULL1 +/*! @parseOnly */ +#define XPC_NONNULL2 +/*! @parseOnly */ +#define XPC_NONNULL3 +/*! @parseOnly */ +#define XPC_NONNULL4 +/*! @parseOnly */ +#define XPC_NONNULL5 +/*! @parseOnly */ +#define XPC_NONNULL6 +/*! @parseOnly */ +#define XPC_NONNULL7 +/*! @parseOnly */ +#define XPC_NONNULL8 +/*! @parseOnly */ +#define XPC_NONNULL9 +/*! @parseOnly */ +#define XPC_NONNULL10 +/*! @parseOnly */ +#define XPC_NONNULL11 +/*! @parseOnly */ +#define XPC_NONNULL(n) +/*! @parseOnly */ +#define XPC_NONNULL_ALL +/*! @parseOnly */ +#define XPC_SENTINEL +/*! @parseOnly */ +#define XPC_PURE +/*! @parseOnly */ +#define XPC_WARN_RESULT +/*! @parseOnly */ +#define XPC_MALLOC +/*! @parseOnly */ +#define XPC_UNUSED +/*! @parseOnly */ +#define XPC_PACKED +/*! @parseOnly */ +#define XPC_PRINTF(m, n) +/*! @parseOnly */ +#define XPC_INLINE static inline +/*! @parseOnly */ +#define XPC_NOINLINE +/*! @parseOnly */ +#define XPC_NOIMPL +/*! @parseOnly */ +#define XPC_EXPORT extern +/*! @parseOnly */ +#define XPC_WEAKIMPORT +/*! @parseOnly */ +#define XPC_DEPRECATED +/*! @parseOnly */ +#define XPC_UNAVAILABLE(m) +/*! @parseOnly */ +#define XPC_NOESCAPE +#endif // __GNUC__ + +#if __has_feature(assume_nonnull) +#define XPC_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +#define XPC_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +#else +#define XPC_ASSUME_NONNULL_BEGIN +#define XPC_ASSUME_NONNULL_END +#endif + +#if __has_feature(nullability_on_arrays) +#define XPC_NONNULL_ARRAY _Nonnull +#else +#define XPC_NONNULL_ARRAY +#endif + +#ifdef OS_CLOSED_OPTIONS +#define XPC_FLAGS_ENUM(_name, _type, ...) \ + OS_CLOSED_OPTIONS(_name, _type, __VA_ARGS__) +#else // OS_CLOSED_ENUM +#define XPC_FLAGS_ENUM(_name, _type, ...) \ + OS_ENUM(_name, _type, __VA_ARGS__) +#endif // OS_CLOSED_ENUM + +#ifdef OS_CLOSED_ENUM +#define XPC_ENUM(_name, _type, ...) \ + OS_CLOSED_ENUM(_name, _type, __VA_ARGS__) +#else // OS_CLOSED_ENUM +#define XPC_ENUM(_name, _type, ...) \ + OS_ENUM(_name, _type, __VA_ARGS__) +#endif // OS_CLOSED_ENUM + +__END_DECLS + +#endif // __XPC_BASE_H__ \ No newline at end of file diff --git a/lib/libc/include/any-macos.11-any/xpc/connection.h b/lib/libc/include/any-macos.11-any/xpc/connection.h new file mode 100644 index 0000000000..fda085bb12 --- /dev/null +++ b/lib/libc/include/any-macos.11-any/xpc/connection.h @@ -0,0 +1,748 @@ +#ifndef __XPC_CONNECTION_H__ +#define __XPC_CONNECTION_H__ + +#ifndef __XPC_INDIRECT__ +#error "Please #include instead of this file directly." +// For HeaderDoc. +#include +#endif // __XPC_INDIRECT__ + +#ifndef __BLOCKS__ +#error "XPC connections require Blocks support." +#endif // __BLOCKS__ + +XPC_ASSUME_NONNULL_BEGIN +__BEGIN_DECLS + +/*! + * @constant XPC_ERROR_CONNECTION_INTERRUPTED + * Will be delivered to the connection's event handler if the remote service + * exited. The connection is still live even in this case, and resending a + * message will cause the service to be launched on-demand. This error serves + * as a client's indication that it should resynchronize any state that it had + * given the service. + * + * Any messages in the queue to be sent will be unwound and canceled when this + * error occurs. In the case where a message waiting to be sent has a reply + * handler, that handler will be invoked with this error. In the context of the + * reply handler, this error indicates that a reply to the message will never + * arrive. + * + * Messages that do not have reply handlers associated with them will be + * silently disposed of. This error will only be given to peer connections. + */ +#define XPC_ERROR_CONNECTION_INTERRUPTED \ + XPC_GLOBAL_OBJECT(_xpc_error_connection_interrupted) +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT +const struct _xpc_dictionary_s _xpc_error_connection_interrupted; + +/*! + * @constant XPC_ERROR_CONNECTION_INVALID + * Will be delivered to the connection's event handler if the named service + * provided to xpc_connection_create() could not be found in the XPC service + * namespace. The connection is useless and should be disposed of. + * + * Any messages in the queue to be sent will be unwound and canceled when this + * error occurs, similarly to the behavior when XPC_ERROR_CONNECTION_INTERRUPTED + * occurs. The only difference is that the XPC_ERROR_CONNECTION_INVALID will be + * given to outstanding reply handlers and the connection's event handler. + * + * This error may be given to any type of connection. + */ +#define XPC_ERROR_CONNECTION_INVALID \ + XPC_GLOBAL_OBJECT(_xpc_error_connection_invalid) +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT +const struct _xpc_dictionary_s _xpc_error_connection_invalid; + +/*! + * @constant XPC_ERROR_TERMINATION_IMMINENT + * On macOS, this error will be delivered to a peer connection's event handler + * when the XPC runtime has determined that the program should exit and that + * all outstanding transactions must be wound down, and no new transactions can + * be opened. + * + * After this error has been delivered to the event handler, no more messages + * will be received by the connection. The runtime will still attempt to deliver + * outgoing messages, but this error should be treated as an indication that + * the program will exit very soon, and any outstanding business over the + * connection should be wrapped up as quickly as possible and the connection + * canceled shortly thereafter. + * + * This error will only be delivered to peer connections received through a + * listener or the xpc_main() event handler. + */ +#define XPC_ERROR_TERMINATION_IMMINENT \ + XPC_GLOBAL_OBJECT(_xpc_error_termination_imminent) +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT +const struct _xpc_dictionary_s _xpc_error_termination_imminent; + +/*! + * @constant XPC_CONNECTION_MACH_SERVICE_LISTENER + * Passed to xpc_connection_create_mach_service(). This flag indicates that the + * caller is the listener for the named service. This flag may only be passed + * for services which are advertised in the process' launchd.plist(5). You may + * not use this flag to dynamically add services to the Mach bootstrap + * namespace. + */ +#define XPC_CONNECTION_MACH_SERVICE_LISTENER (1 << 0) + +/*! + * @constant XPC_CONNECTION_MACH_SERVICE_PRIVILEGED + * Passed to xpc_connection_create_mach_service(). This flag indicates that the + * job advertising the service name in its launchd.plist(5) should be in the + * privileged Mach bootstrap. This is typically accomplished by placing your + * launchd.plist(5) in /Library/LaunchDaemons. If specified alongside the + * XPC_CONNECTION_MACH_SERVICE_LISTENER flag, this flag is a no-op. + */ +#define XPC_CONNECTION_MACH_SERVICE_PRIVILEGED (1 << 1) + +/*! + * @typedef xpc_finalizer_f + * A function that is invoked when a connection is being torn down and its + * context needs to be freed. The sole argument is the value that was given to + * {@link xpc_connection_set_context} or NULL if no context has been set. It is + * not safe to reference the connection from within this function. + * + * @param value + * The context object that is to be disposed of. + */ +typedef void (*xpc_finalizer_t)(void * _Nullable value); + +/*! + * @function xpc_connection_create + * Creates a new connection object. + * + * @param name + * If non-NULL, the name of the service with which to connect. The returned + * connection will be a peer. + * + * If NULL, an anonymous listener connection will be created. You can embed the + * ability to create new peer connections in an endpoint, which can be inserted + * into a message and sent to another process . + * + * @param targetq + * The GCD queue to which the event handler block will be submitted. This + * parameter may be NULL, in which case the connection's target queue will be + * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. + * The target queue may be changed later with a call to + * xpc_connection_set_target_queue(). + * + * @result + * A new connection object. The caller is responsible for disposing of the + * returned object with {@link xpc_release} when it is no longer needed. + * + * @discussion + * This method will succeed even if the named service does not exist. This is + * because the XPC namespace is not queried for the service name until the + * connection has been activated. See {@link xpc_connection_activate()}. + * + * XPC connections, like dispatch sources, are returned in an inactive state, so + * you must call {@link xpc_connection_activate()} in order to begin receiving + * events from the connection. Also like dispatch sources, connections must be + * activated and not suspended in order to be safely released. It is + * a programming error to release an inactive or suspended connection. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT +xpc_connection_t +xpc_connection_create(const char * _Nullable name, + dispatch_queue_t _Nullable targetq); + +/*! + * @function xpc_connection_create_mach_service + * Creates a new connection object representing a Mach service. + * + * @param name + * The name of the remote service with which to connect. The service name must + * exist in a Mach bootstrap that is accessible to the process and be advertised + * in a launchd.plist. + * + * @param targetq + * The GCD queue to which the event handler block will be submitted. This + * parameter may be NULL, in which case the connection's target queue will be + * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. + * The target queue may be changed later with a call to + * xpc_connection_set_target_queue(). + * + * @param flags + * Additional attributes with which to create the connection. + * + * @result + * A new connection object. + * + * @discussion + * If the XPC_CONNECTION_MACH_SERVICE_LISTENER flag is given to this method, + * then the connection returned will be a listener connection. Otherwise, a peer + * connection will be returned. See the documentation for + * {@link xpc_connection_set_event_handler()} for the semantics of listener + * connections versus peer connections. + * + * This method will succeed even if the named service does not exist. This is + * because the Mach namespace is not queried for the service name until the + * connection has been activated. See {@link xpc_connection_activate()}. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL1 +xpc_connection_t +xpc_connection_create_mach_service(const char *name, + dispatch_queue_t _Nullable targetq, uint64_t flags); + +/*! + * @function xpc_connection_create_from_endpoint + * Creates a new connection from the given endpoint. + * + * @param endpoint + * The endpoint from which to create the new connection. + * + * @result + * A new peer connection to the listener represented by the given endpoint. + * + * The same responsibilities of setting an event handler and activating the + * connection after calling xpc_connection_create() apply to the connection + * returned by this API. Since the connection yielded by this API is not + * associated with a name (and therefore is not rediscoverable), this connection + * will receive XPC_ERROR_CONNECTION_INVALID if the listening side crashes, + * exits or cancels the listener connection. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL_ALL +xpc_connection_t +xpc_connection_create_from_endpoint(xpc_endpoint_t endpoint); + +/*! + * @function xpc_connection_set_target_queue + * Sets the target queue of the given connection. + * + * @param connection + * The connection object which is to be manipulated. + * + * @param targetq + * The GCD queue to which the event handler block will be submitted. This + * parameter may be NULL, in which case the connection's target queue will be + * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. + * + * @discussion + * Setting the target queue is asynchronous and non-preemptive and therefore + * this method will not interrupt the execution of an already-running event + * handler block. Setting the target queue may be likened to issuing a barrier + * to the connection which does the actual work of changing the target queue. + * + * The XPC runtime guarantees this non-preemptiveness even for concurrent target + * queues. If the target queue is a concurrent queue, then XPC still guarantees + * that there will never be more than one invocation of the connection's event + * handler block executing concurrently. If you wish to process events + * concurrently, you can dispatch_async(3) to a concurrent queue from within + * the event handler. + * + * IMPORTANT: When called from within the event handler block, + * dispatch_get_current_queue(3) is NOT guaranteed to return a pointer to the + * queue set with this method. + * + * Despite this seeming inconsistency, the XPC runtime guarantees that, when the + * target queue is a serial queue, the event handler block will execute + * synchonously with respect to other blocks submitted to that same queue. When + * the target queue is a concurrent queue, the event handler block may run + * concurrently with other blocks submitted to that queue, but it will never run + * concurrently with other invocations of itself for the same connection, as + * discussed previously. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL1 +void +xpc_connection_set_target_queue(xpc_connection_t connection, + dispatch_queue_t _Nullable targetq); + +/*! + * @function xpc_connection_set_event_handler + * Sets the event handler block for the connection. + * + * @param connection + * The connection object which is to be manipulated. + * + * @param handler + * The event handler block. + * + * @discussion + * Setting the event handler is asynchronous and non-preemptive, and therefore + * this method will not interrupt the execution of an already-running event + * handler block. If the event handler is executing at the time of this call, it + * will finish, and then the connection's event handler will be changed before + * the next invocation of the event handler. The XPC runtime guarantees this + * non-preemptiveness even for concurrent target queues. + * + * Connection event handlers are non-reentrant, so it is safe to call + * xpc_connection_set_event_handler() from within the event handler block. + * + * The event handler's execution should be treated as a barrier to all + * connection activity. When it is executing, the connection will not attempt to + * send or receive messages, including reply messages. Thus, it is not safe to + * call xpc_connection_send_message_with_reply_sync() on the connection from + * within the event handler. + * + * You do not hold a reference on the object received as the event handler's + * only argument. Regardless of the type of object received, it is safe to call + * xpc_retain() on the object to obtain a reference to it. + * + * A connection may receive different events depending upon whether it is a + * listener or not. Any connection may receive an error in its event handler. + * But while normal connections may receive messages in addition to errors, + * listener connections will receive connections and and not messages. + * + * Connections received by listeners are equivalent to those returned by + * xpc_connection_create() with a non-NULL name argument and a NULL targetq + * argument with the exception that you do not hold a reference on them. + * You must set an event handler and activate the connection. If you do not wish + * to accept the connection, you may simply call xpc_connection_cancel() on it + * and return. The runtime will dispose of it for you. + * + * If there is an error in the connection, this handler will be invoked with the + * error dictionary as its argument. This dictionary will be one of the well- + * known XPC_ERROR_* dictionaries. + * + * Regardless of the type of event, ownership of the event object is NOT + * implicitly transferred. Thus, the object will be released and deallocated at + * some point in the future after the event handler returns. If you wish the + * event's lifetime to persist, you must retain it with xpc_retain(). + * + * Connections received through the event handler will be released and + * deallocated after the connection has gone invalid and delivered that event to + * its event handler. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_set_event_handler(xpc_connection_t connection, + xpc_handler_t handler); + +/*! + * @function xpc_connection_activate + * Activates the connection. Connections start in an inactive state, so you must + * call xpc_connection_activate() on a connection before it will send or receive + * any messages. + * + * @param connection + * The connection object which is to be manipulated. + * + * @discussion + * Calling xpc_connection_activate() on an active connection has no effect. + * Releasing the last reference on an inactive connection that was created with + * an xpc_connection_create*() call is undefined. + * + * For backward compatibility reasons, xpc_connection_resume() on an inactive + * and not otherwise suspended xpc connection has the same effect as calling + * xpc_connection_activate(). For new code, using xpc_connection_activate() + * is preferred. + */ +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_activate(xpc_connection_t connection); + +/*! + * @function xpc_connection_suspend + * Suspends the connection so that the event handler block will not fire and + * that the connection will not attempt to send any messages it has in its + * queue. All calls to xpc_connection_suspend() must be balanced with calls to + * xpc_connection_resume() before releasing the last reference to the + * connection. + * + * @param connection + * The connection object which is to be manipulated. + * + * @discussion + * Suspension is asynchronous and non-preemptive, and therefore this method will + * not interrupt the execution of an already-running event handler block. If + * the event handler is executing at the time of this call, it will finish, and + * then the connection will be suspended before the next scheduled invocation + * of the event handler. The XPC runtime guarantees this non-preemptiveness even + * for concurrent target queues. + * + * Connection event handlers are non-reentrant, so it is safe to call + * xpc_connection_suspend() from within the event handler block. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_suspend(xpc_connection_t connection); + +/*! + * @function xpc_connection_resume + * Resumes the connection. + * + * @param connection + * The connection object which is to be manipulated. + * + * @discussion + * In order for a connection to become live, every call to + * xpc_connection_suspend() must be balanced with a call to + * xpc_connection_resume(). + * + * For backward compatibility reasons, xpc_connection_resume() on an inactive + * and not otherwise suspended xpc connection has the same effect as calling + * xpc_connection_activate(). For new code, using xpc_connection_activate() + * is preferred. + * + * Calling xpc_connection_resume() more times than xpc_connection_suspend() + * has been called is otherwise considered an error. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_resume(xpc_connection_t connection); + +/*! + * @function xpc_connection_send_message + * Sends a message over the connection to the destination service. + * + * @param connection + * The connection over which the message shall be sent. + * + * @param message + * The message to send. This must be a dictionary object. This dictionary is + * logically copied by the connection, so it is safe to modify the dictionary + * after this call. + * + * @discussion + * Messages are delivered in FIFO order. This API is safe to call from multiple + * GCD queues. There is no indication that a message was delivered successfully. + * This is because even once the message has been successfully enqueued on the + * remote end, there are no guarantees about when the runtime will dequeue the + * message and invoke the other connection's event handler block. + * + * If this API is used to send a message that is in reply to another message, + * there is no guarantee of ordering between the invocations of the connection's + * event handler and the reply handler for that message, even if they are + * targeted to the same queue. + * + * After extensive study, we have found that clients who are interested in + * the state of the message on the server end are typically holding open + * transactions related to that message. And the only reliable way to track the + * lifetime of that transaction is at the protocol layer. So the server should + * send a reply message, which upon receiving, will cause the client to close + * its transaction. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_send_message(xpc_connection_t connection, xpc_object_t message); + +/*! + * @function xpc_connection_send_barrier + * Issues a barrier against the connection's message-send activity. + * + * @param connection + * The connection against which the barrier is to be issued. + * + * @param barrier + * The barrier block to issue. This barrier prevents concurrent message-send + * activity on the connection. No messages will be sent while the barrier block + * is executing. + * + * @discussion + * XPC guarantees that, even if the connection's target queue is a concurrent + * queue, there are no other messages being sent concurrently while the barrier + * block is executing. XPC does not guarantee that the receipt of messages + * (either through the connection's event handler or through reply handlers) + * will be suspended while the barrier is executing. + * + * A barrier is issued relative to the message-send queue. Thus, if you call + * xpc_connection_send_message() five times and then call + * xpc_connection_send_barrier(), the barrier will be invoked after the fifth + * message has been sent and its memory disposed of. You may safely cancel a + * connection from within a barrier block. + * + * If a barrier is issued after sending a message which expects a reply, the + * behavior is the same as described above. The receipt of a reply message will + * not influence when the barrier runs. + * + * A barrier block can be useful for throttling resource consumption on the + * connected side of a connection. For example, if your connection sends many + * large messages, you can use a barrier to limit the number of messages that + * are inflight at any given time. This can be particularly useful for messages + * that contain kernel resources (like file descriptors) which have a system- + * wide limit. + * + * If a barrier is issued on a canceled connection, it will be invoked + * immediately. If a connection has been canceled and still has outstanding + * barriers, those barriers will be invoked as part of the connection's + * unwinding process. + * + * It is important to note that a barrier block's execution order is not + * guaranteed with respect to other blocks that have been scheduled on the + * target queue of the connection. Or said differently, + * xpc_connection_send_barrier(3) is not equivalent to dispatch_async(3). + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_send_barrier(xpc_connection_t connection, + dispatch_block_t barrier); + +/*! + * @function xpc_connection_send_message_with_reply + * Sends a message over the connection to the destination service and associates + * a handler to be invoked when the remote service sends a reply message. + * + * @param connection + * The connection over which the message shall be sent. + * + * @param message + * The message to send. This must be a dictionary object. + * + * @param replyq + * The GCD queue to which the reply handler will be submitted. This may be a + * concurrent queue. + * + * @param handler + * The handler block to invoke when a reply to the message is received from + * the connection. If the remote service exits prematurely before the reply was + * received, the XPC_ERROR_CONNECTION_INTERRUPTED error will be returned. + * If the connection went invalid before the message could be sent, the + * XPC_ERROR_CONNECTION_INVALID error will be returned. + * + * @discussion + * If the given GCD queue is a concurrent queue, XPC cannot guarantee that there + * will not be multiple reply handlers being invoked concurrently. XPC does not + * guarantee any ordering for the invocation of reply handers. So if multiple + * messages are waiting for replies and the connection goes invalid, there is no + * guarantee that the reply handlers will be invoked in FIFO order. Similarly, + * XPC does not guarantee that reply handlers will not run concurrently with + * the connection's event handler in the case that the reply queue and the + * connection's target queue are the same concurrent queue. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 XPC_NONNULL4 +void +xpc_connection_send_message_with_reply(xpc_connection_t connection, + xpc_object_t message, dispatch_queue_t _Nullable replyq, + xpc_handler_t handler); + +/*! + * @function xpc_connection_send_message_with_reply_sync + * Sends a message over the connection and blocks the caller until a reply is + * received. + * + * @param connection + * The connection over which the message shall be sent. + * + * @param message + * The message to send. This must be a dictionary object. + * + * @result + * The message that the remote service sent in reply to the original message. + * If the remote service exits prematurely before the reply was received, the + * XPC_ERROR_CONNECTION_INTERRUPTED error will be returned. If the connection + * went invalid before the message could be sent, the + * XPC_ERROR_CONNECTION_INVALID error will be returned. + * + * You are responsible for releasing the returned object. + * + * @discussion + * This API supports priority inversion avoidance, and should be used instead of + * combining xpc_connection_send_message_with_reply() with a semaphore. + * + * Invoking this API from a queue that is a part of the target queue hierarchy + * results in deadlocks under certain conditions. + * + * Be judicious about your use of this API. It can block indefinitely, so if you + * are using it to implement an API that can be called from the main thread, you + * may wish to consider allowing the API to take a queue and callback block so + * that results may be delivered asynchronously if possible. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT XPC_RETURNS_RETAINED +xpc_object_t +xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, + xpc_object_t message); + +/*! + * @function xpc_connection_cancel + * Cancels the connection and ensures that its event handler will not fire + * again. After this call, any messages that have not yet been sent will be + * discarded, and the connection will be unwound. If there are messages that are + * awaiting replies, they will have their reply handlers invoked with the + * XPC_ERROR_CONNECTION_INVALID error. + * + * @param connection + * The connection object which is to be manipulated. + * + * @discussion + * Cancellation is asynchronous and non-preemptive and therefore this method + * will not interrupt the execution of an already-running event handler block. + * If the event handler is executing at the time of this call, it will finish, + * and then the connection will be canceled, causing a final invocation of the + * event handler to be scheduled with the XPC_ERROR_CONNECTION_INVALID error. + * After that invocation, there will be no further invocations of the event + * handler. + * + * The XPC runtime guarantees this non-preemptiveness even for concurrent target + * queues. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL +void +xpc_connection_cancel(xpc_connection_t connection); + +/*! + * @function xpc_connection_get_name + * Returns the name of the service with which the connections was created. + * + * @param connection + * The connection object which is to be examined. + * + * @result + * The name of the remote service. If you obtained the connection through an + * invocation of another connection's event handler, NULL is returned. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT +const char * _Nullable +xpc_connection_get_name(xpc_connection_t connection); + +/*! + * @function xpc_connection_get_euid + * Returns the EUID of the remote peer. + * + * @param connection + * The connection object which is to be examined. + * + * @result + * The EUID of the remote peer at the time the connection was made. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT +uid_t +xpc_connection_get_euid(xpc_connection_t connection); + +/*! + * @function xpc_connection_get_egid + * Returns the EGID of the remote peer. + * + * @param connection + * The connection object which is to be examined. + * + * @result + * The EGID of the remote peer at the time the connection was made. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT +gid_t +xpc_connection_get_egid(xpc_connection_t connection); + +/*! + * @function xpc_connection_get_pid + * Returns the PID of the remote peer. + * + * @param connection + * The connection object which is to be examined. + * + * @result + * The PID of the remote peer. + * + * @discussion + * A given PID is not guaranteed to be unique across an entire boot cycle. + * Great care should be taken when dealing with this information, as it can go + * stale after the connection is established. OS X recycles PIDs, and therefore + * another process could spawn and claim the PID before a message is actually + * received from the connection. + * + * XPC will deliver an error to your event handler if the remote process goes + * away, but there are no guarantees as to the timing of this notification's + * delivery either at the kernel layer or at the XPC layer. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT +pid_t +xpc_connection_get_pid(xpc_connection_t connection); + +/*! + * @function xpc_connection_get_asid + * Returns the audit session identifier of the remote peer. + * + * @param connection + * The connection object which is to be examined. + * + * @result + * The audit session ID of the remote peer at the time the connection was made. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT +au_asid_t +xpc_connection_get_asid(xpc_connection_t connection); + +/*! + * @function xpc_connection_set_context + * Sets context on an connection. + * + * @param connection + * The connection which is to be manipulated. + * + * @param context + * The context to associate with the connection. + * + * @discussion + * If you must manage the memory of the context object, you must set a finalizer + * to dispose of it. If this method is called on a connection which already has + * context associated with it, the finalizer will NOT be invoked. The finalizer + * is only invoked when the connection is being deallocated. + * + * It is recommended that, instead of changing the actual context pointer + * associated with the object, you instead change the state of the context + * object itself. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL1 +void +xpc_connection_set_context(xpc_connection_t connection, + void * _Nullable context); + +/*! + * @function xpc_connection_get_context + * Returns the context associated with the connection. + * + * @param connection + * The connection which is to be examined. + * + * @result + * The context associated with the connection. NULL if there has been no context + * associated with the object. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT +void * _Nullable +xpc_connection_get_context(xpc_connection_t connection); + +/*! + * @function xpc_connection_set_finalizer_f + * Sets the finalizer for the given connection. + * + * @param connection + * The connection on which to set the finalizer. + * + * @param finalizer + * The function that will be invoked when the connection's retain count has + * dropped to zero and is being torn down. + * + * @discussion + * This method disposes of the context value associated with a connection, as + * set by {@link xpc_connection_set_context}. + * + * For many uses of context objects, this API allows for a convenient shorthand + * for freeing them. For example, for a context object allocated with malloc(3): + * + * xpc_connection_set_finalizer_f(object, free); + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) +XPC_EXPORT XPC_NONNULL1 +void +xpc_connection_set_finalizer_f(xpc_connection_t connection, + xpc_finalizer_t _Nullable finalizer); + +__END_DECLS +XPC_ASSUME_NONNULL_END + +#endif // __XPC_CONNECTION_H__ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/AvailabilityMacros.h b/lib/libc/include/any-macos.12-any/AvailabilityMacros.h similarity index 100% rename from lib/libc/include/any-macos-any/AvailabilityMacros.h rename to lib/libc/include/any-macos.12-any/AvailabilityMacros.h diff --git a/lib/libc/include/any-macos-any/dispatch/base.h b/lib/libc/include/any-macos.12-any/dispatch/base.h similarity index 100% rename from lib/libc/include/any-macos-any/dispatch/base.h rename to lib/libc/include/any-macos.12-any/dispatch/base.h diff --git a/lib/libc/include/any-macos-any/libproc.h b/lib/libc/include/any-macos.12-any/libproc.h similarity index 100% rename from lib/libc/include/any-macos-any/libproc.h rename to lib/libc/include/any-macos.12-any/libproc.h diff --git a/lib/libc/include/any-macos-any/mach/clock.h b/lib/libc/include/any-macos.12-any/mach/clock.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/clock.h rename to lib/libc/include/any-macos.12-any/mach/clock.h diff --git a/lib/libc/include/any-macos-any/mach/clock_priv.h b/lib/libc/include/any-macos.12-any/mach/clock_priv.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/clock_priv.h rename to lib/libc/include/any-macos.12-any/mach/clock_priv.h diff --git a/lib/libc/include/any-macos-any/mach/exception_types.h b/lib/libc/include/any-macos.12-any/mach/exception_types.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/exception_types.h rename to lib/libc/include/any-macos.12-any/mach/exception_types.h diff --git a/lib/libc/include/any-macos-any/mach/host_priv.h b/lib/libc/include/any-macos.12-any/mach/host_priv.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/host_priv.h rename to lib/libc/include/any-macos.12-any/mach/host_priv.h diff --git a/lib/libc/include/any-macos-any/mach/host_security.h b/lib/libc/include/any-macos.12-any/mach/host_security.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/host_security.h rename to lib/libc/include/any-macos.12-any/mach/host_security.h diff --git a/lib/libc/include/any-macos-any/mach/lock_set.h b/lib/libc/include/any-macos.12-any/mach/lock_set.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/lock_set.h rename to lib/libc/include/any-macos.12-any/mach/lock_set.h diff --git a/lib/libc/include/any-macos-any/mach/mach.h b/lib/libc/include/any-macos.12-any/mach/mach.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/mach.h rename to lib/libc/include/any-macos.12-any/mach/mach.h diff --git a/lib/libc/include/any-macos-any/mach/mach_host.h b/lib/libc/include/any-macos.12-any/mach/mach_host.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/mach_host.h rename to lib/libc/include/any-macos.12-any/mach/mach_host.h diff --git a/lib/libc/include/any-macos-any/mach/mach_port.h b/lib/libc/include/any-macos.12-any/mach/mach_port.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/mach_port.h rename to lib/libc/include/any-macos.12-any/mach/mach_port.h diff --git a/lib/libc/include/any-macos-any/mach/mach_voucher_types.h b/lib/libc/include/any-macos.12-any/mach/mach_voucher_types.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/mach_voucher_types.h rename to lib/libc/include/any-macos.12-any/mach/mach_voucher_types.h diff --git a/lib/libc/include/any-macos-any/mach/machine.h b/lib/libc/include/any-macos.12-any/mach/machine.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/machine.h rename to lib/libc/include/any-macos.12-any/mach/machine.h diff --git a/lib/libc/include/any-macos-any/mach/message.h b/lib/libc/include/any-macos.12-any/mach/message.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/message.h rename to lib/libc/include/any-macos.12-any/mach/message.h diff --git a/lib/libc/include/any-macos-any/mach/port.h b/lib/libc/include/any-macos.12-any/mach/port.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/port.h rename to lib/libc/include/any-macos.12-any/mach/port.h diff --git a/lib/libc/include/any-macos-any/mach/processor.h b/lib/libc/include/any-macos.12-any/mach/processor.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/processor.h rename to lib/libc/include/any-macos.12-any/mach/processor.h diff --git a/lib/libc/include/any-macos-any/mach/processor_set.h b/lib/libc/include/any-macos.12-any/mach/processor_set.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/processor_set.h rename to lib/libc/include/any-macos.12-any/mach/processor_set.h diff --git a/lib/libc/include/any-macos-any/mach/thread_act.h b/lib/libc/include/any-macos.12-any/mach/thread_act.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/thread_act.h rename to lib/libc/include/any-macos.12-any/mach/thread_act.h diff --git a/lib/libc/include/any-macos-any/mach/thread_policy.h b/lib/libc/include/any-macos.12-any/mach/thread_policy.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/thread_policy.h rename to lib/libc/include/any-macos.12-any/mach/thread_policy.h diff --git a/lib/libc/include/any-macos-any/mach/vm_map.h b/lib/libc/include/any-macos.12-any/mach/vm_map.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/vm_map.h rename to lib/libc/include/any-macos.12-any/mach/vm_map.h diff --git a/lib/libc/include/any-macos-any/mach/vm_prot.h b/lib/libc/include/any-macos.12-any/mach/vm_prot.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/vm_prot.h rename to lib/libc/include/any-macos.12-any/mach/vm_prot.h diff --git a/lib/libc/include/any-macos-any/mach/vm_statistics.h b/lib/libc/include/any-macos.12-any/mach/vm_statistics.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/vm_statistics.h rename to lib/libc/include/any-macos.12-any/mach/vm_statistics.h diff --git a/lib/libc/include/any-macos-any/mach/vm_types.h b/lib/libc/include/any-macos.12-any/mach/vm_types.h similarity index 100% rename from lib/libc/include/any-macos-any/mach/vm_types.h rename to lib/libc/include/any-macos.12-any/mach/vm_types.h diff --git a/lib/libc/include/any-macos-any/mach_debug/mach_debug_types.h b/lib/libc/include/any-macos.12-any/mach_debug/mach_debug_types.h similarity index 100% rename from lib/libc/include/any-macos-any/mach_debug/mach_debug_types.h rename to lib/libc/include/any-macos.12-any/mach_debug/mach_debug_types.h diff --git a/lib/libc/include/any-macos-any/malloc/malloc.h b/lib/libc/include/any-macos.12-any/malloc/malloc.h similarity index 100% rename from lib/libc/include/any-macos-any/malloc/malloc.h rename to lib/libc/include/any-macos.12-any/malloc/malloc.h diff --git a/lib/libc/include/any-macos-any/netinet6/in6.h b/lib/libc/include/any-macos.12-any/netinet6/in6.h similarity index 100% rename from lib/libc/include/any-macos-any/netinet6/in6.h rename to lib/libc/include/any-macos.12-any/netinet6/in6.h diff --git a/lib/libc/include/any-macos-any/objc/NSObjCRuntime.h b/lib/libc/include/any-macos.12-any/objc/NSObjCRuntime.h similarity index 100% rename from lib/libc/include/any-macos-any/objc/NSObjCRuntime.h rename to lib/libc/include/any-macos.12-any/objc/NSObjCRuntime.h diff --git a/lib/libc/include/any-macos-any/objc/message.h b/lib/libc/include/any-macos.12-any/objc/message.h similarity index 100% rename from lib/libc/include/any-macos-any/objc/message.h rename to lib/libc/include/any-macos.12-any/objc/message.h diff --git a/lib/libc/include/any-macos-any/objc/objc-api.h b/lib/libc/include/any-macos.12-any/objc/objc-api.h similarity index 100% rename from lib/libc/include/any-macos-any/objc/objc-api.h rename to lib/libc/include/any-macos.12-any/objc/objc-api.h diff --git a/lib/libc/include/any-macos-any/os/base.h b/lib/libc/include/any-macos.12-any/os/base.h similarity index 100% rename from lib/libc/include/any-macos-any/os/base.h rename to lib/libc/include/any-macos.12-any/os/base.h diff --git a/lib/libc/include/any-macos-any/pthread.h b/lib/libc/include/any-macos.12-any/pthread.h similarity index 100% rename from lib/libc/include/any-macos-any/pthread.h rename to lib/libc/include/any-macos.12-any/pthread.h diff --git a/lib/libc/include/any-macos-any/simd/base.h b/lib/libc/include/any-macos.12-any/simd/base.h similarity index 100% rename from lib/libc/include/any-macos-any/simd/base.h rename to lib/libc/include/any-macos.12-any/simd/base.h diff --git a/lib/libc/include/any-macos-any/simd/math.h b/lib/libc/include/any-macos.12-any/simd/math.h similarity index 100% rename from lib/libc/include/any-macos-any/simd/math.h rename to lib/libc/include/any-macos.12-any/simd/math.h diff --git a/lib/libc/include/any-macos-any/stdio.h b/lib/libc/include/any-macos.12-any/stdio.h similarity index 100% rename from lib/libc/include/any-macos-any/stdio.h rename to lib/libc/include/any-macos.12-any/stdio.h diff --git a/lib/libc/include/any-macos-any/stdlib.h b/lib/libc/include/any-macos.12-any/stdlib.h similarity index 100% rename from lib/libc/include/any-macos-any/stdlib.h rename to lib/libc/include/any-macos.12-any/stdlib.h diff --git a/lib/libc/include/any-macos-any/sys/resource.h b/lib/libc/include/any-macos.12-any/sys/resource.h similarity index 100% rename from lib/libc/include/any-macos-any/sys/resource.h rename to lib/libc/include/any-macos.12-any/sys/resource.h diff --git a/lib/libc/include/any-macos-any/sys/socket.h b/lib/libc/include/any-macos.12-any/sys/socket.h similarity index 100% rename from lib/libc/include/any-macos-any/sys/socket.h rename to lib/libc/include/any-macos.12-any/sys/socket.h diff --git a/lib/libc/include/any-macos-any/xpc/base.h b/lib/libc/include/any-macos.12-any/xpc/base.h similarity index 100% rename from lib/libc/include/any-macos-any/xpc/base.h rename to lib/libc/include/any-macos.12-any/xpc/base.h diff --git a/lib/libc/include/any-macos-any/xpc/connection.h b/lib/libc/include/any-macos.12-any/xpc/connection.h similarity index 100% rename from lib/libc/include/any-macos-any/xpc/connection.h rename to lib/libc/include/any-macos.12-any/xpc/connection.h diff --git a/lib/libc/include/any-macos.13-any/AvailabilityInternal.h b/lib/libc/include/any-macos.13-any/AvailabilityInternal.h index 4e1e72d8e8..710f24cc92 100644 --- a/lib/libc/include/any-macos.13-any/AvailabilityInternal.h +++ b/lib/libc/include/any-macos.13-any/AvailabilityInternal.h @@ -55,7 +55,7 @@ #ifdef __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ /* compiler sets __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ when -mtvos-version-min is used */ #define __TV_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ - #define __TV_OS_VERSION_MAX_ALLOWED __TVOS_16_1 + #define __TV_OS_VERSION_MAX_ALLOWED __TVOS_16_2 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 90000 #endif @@ -65,7 +65,7 @@ #ifdef __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ /* compiler sets __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ when -mwatchos-version-min is used */ #define __WATCH_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ - #define __WATCH_OS_VERSION_MAX_ALLOWED __WATCHOS_9_1 + #define __WATCH_OS_VERSION_MAX_ALLOWED __WATCHOS_9_2 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 90000 #endif @@ -90,14 +90,14 @@ #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED /* make sure a default max version is set */ #ifndef __MAC_OS_X_VERSION_MAX_ALLOWED - #define __MAC_OS_X_VERSION_MAX_ALLOWED __MAC_13_0 + #define __MAC_OS_X_VERSION_MAX_ALLOWED __MAC_13_1 #endif #endif /* __MAC_OS_X_VERSION_MIN_REQUIRED */ #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED /* make sure a default max version is set */ #ifndef __IPHONE_OS_VERSION_MAX_ALLOWED - #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_16_1 + #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_16_2 #endif /* make sure a valid min is set */ #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_2_0 diff --git a/lib/libc/include/any-macos.13-any/AvailabilityVersions.h b/lib/libc/include/any-macos.13-any/AvailabilityVersions.h index f889a84b18..e488b55232 100644 --- a/lib/libc/include/any-macos.13-any/AvailabilityVersions.h +++ b/lib/libc/include/any-macos.13-any/AvailabilityVersions.h @@ -68,6 +68,7 @@ #define __MAC_12_2 120200 #define __MAC_12_3 120300 #define __MAC_13_0 130000 +#define __MAC_13_1 130100 /* __MAC_NA is not defined to a value but is used as a token by macros to indicate that the API is unavailable */ #define __IPHONE_2_0 20000 @@ -132,6 +133,7 @@ #define __IPHONE_15_4 150400 #define __IPHONE_16_0 160000 #define __IPHONE_16_1 160100 +#define __IPHONE_16_2 160200 /* __IPHONE_NA is not defined to a value but is used as a token by macros to indicate that the API is unavailable */ #define __TVOS_9_0 90000 @@ -169,6 +171,7 @@ #define __TVOS_15_4 150400 #define __TVOS_16_0 160000 #define __TVOS_16_1 160100 +#define __TVOS_16_2 160200 #define __WATCHOS_1_0 10000 #define __WATCHOS_2_0 20000 @@ -203,6 +206,7 @@ #define __WATCHOS_8_5 80500 #define __WATCHOS_9_0 90000 #define __WATCHOS_9_1 90100 +#define __WATCHOS_9_2 90200 /* * Set up standard Mac OS X versions diff --git a/lib/libc/include/any-macos.13-any/net/if.h b/lib/libc/include/any-macos.13-any/net/if.h index d06305aaa0..ca9aed4888 100644 --- a/lib/libc/include/any-macos.13-any/net/if.h +++ b/lib/libc/include/any-macos.13-any/net/if.h @@ -152,7 +152,7 @@ struct if_clonereq { #define IFNET_SLOWHZ 1 /* granularity is 1 second */ #define IFQ_DEF_C_TARGET_DELAY (10ULL * 1000 * 1000) /* 10 ms */ #define IFQ_DEF_C_UPDATE_INTERVAL (100ULL * 1000 * 1000) /* 100 ms */ -#define IFQ_DEF_L4S_TARGET_DELAY (10ULL * 1000 * 1000) /* 10 ms */ +#define IFQ_DEF_L4S_TARGET_DELAY (2ULL * 1000 * 1000) /* 2 ms */ #define IFQ_DEF_L4S_UPDATE_INTERVAL (100ULL * 1000 * 1000) /* 100 ms */ #define IFQ_LL_C_TARGET_DELAY (10ULL * 1000 * 1000) /* 10 ms */ #define IFQ_LL_C_UPDATE_INTERVAL (100ULL * 1000 * 1000) /* 100 ms */ diff --git a/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h b/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h index 6d0429add1..1212cd91dd 100644 --- a/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h +++ b/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h @@ -383,6 +383,12 @@ #define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_1(x) #endif +#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 160200 +#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_2(x) x +#else +#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_2(x) +#endif + #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1000 #define __DARWIN_ALIAS_STARTING_MAC___MAC_10_0(x) x #else @@ -633,4 +639,10 @@ #define __DARWIN_ALIAS_STARTING_MAC___MAC_13_0(x) x #else #define __DARWIN_ALIAS_STARTING_MAC___MAC_13_0(x) +#endif + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 130100 +#define __DARWIN_ALIAS_STARTING_MAC___MAC_13_1(x) x +#else +#define __DARWIN_ALIAS_STARTING_MAC___MAC_13_1(x) #endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/sys/constrained_ctypes.h b/lib/libc/include/any-macos.13-any/sys/constrained_ctypes.h index da3aaff482..2d65fd2dec 100644 --- a/lib/libc/include/any-macos.13-any/sys/constrained_ctypes.h +++ b/lib/libc/include/any-macos.13-any/sys/constrained_ctypes.h @@ -31,9 +31,8 @@ #include -/* This file introduces macros for constraining pointer - * types to specific contracts: - * +/* + * Constraining pointer types based on contracts. * * 1. List of supported constrained pointers. * @@ -184,12 +183,19 @@ * `basetag`: the prefix of the constrained type. * * This macro acts differently in the user-space and the kernel-space - * code. When used in the former, it will only declare types which are - * ABI-safe. See `ABI Compatibility Considerations' below for more details. + * code. + * When used in the user-space code, the macro will declare + * types which are ABI-safe. See `ABI Compatibility Considerations' + * below for more details on ABI-safety. In the user-space code, + * the macro is guarded by the `__CCT_ENABLE_USER_SPACE' compilation + * flag. + * When used in the kernel-space code, the macro will declare + * the common constrained types. * * Examples: * - * (1) When used from the user space, + * (1) When used from the user space, and `__CCT_ENABLE_USER_SPACE' + * is defined, the expression * `__CCT_DECLARE_CONSTRAINED_PTR_TYPES(struct socket, socket);' * will declare types: * @@ -224,16 +230,32 @@ * * `basetype`: the pointee type. * `basetag`: the prefix of the constrained type. - * `...`: list of `REF', `CREF', `BPTR' or `PTR', which represent - * the desired constraints. + * `...`: list of constraints: + * - `__CCT_REF' for the "reference" contract; + * - `__CCT_CREF' for the "const reference" contract; + * - `__CCT_PTR' for the "checked pointer" contract; or + * - `__CCT_BPTR' for the "bidirectional pointer" contract. * * Examples: * - * (1) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, REF)' - * will declare the type `socket_ref_t`: + * (1) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, __CCT_REF)' + * will declare the type + * `reference' pointer to `struct socket' + * and call this type by `socket_ref_t' * - * (2) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, REF, PTR, REF)' - * will declare the type `socket_ref_ptr_ref_t`: + * (2) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, __CCT_REF, __CCT_PTR)' + * will declare the type + * `checked' pointer to `socket_ref_t' + * which in turn is equivalent to the type + * `checked' pointer to `reference' pointer to `struct socket' + * + * (3) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, __CCT_REF, __CCT_PTR, __CCT_REF)' + * will declare the type + * `reference' pointer to `socket_ref_ptr_t' + * which is equivalent to the type + * `reference' pointer to `checked' pointer to `socket_ref_t' + * which in turn is equivalent to the type + * `reference' pointer to `checked' pointer to `reference' pointer to `struct socket' * * * 3. Using constrained pointer types. @@ -513,27 +535,28 @@ * Support for other compilers will be added after the introduction of support * for pointer tagging on those compilers. */ +#if defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE) #if defined(__clang__) -#define __CCT_CONTRACT_ATTR_REF __single -#define __CCT_CONTRACT_ATTR_CREF const __single +#define __CCT_CONTRACT_ATTR___CCT_REF __single +#define __CCT_CONTRACT_ATTR___CCT_CREF const __single #if __has_ptrcheck -#define __CCT_CONTRACT_ATTR_BPTR __bidi_indexable -#define __CCT_CONTRACT_ATTR_PTR __indexable +#define __CCT_CONTRACT_ATTR___CCT_BPTR __bidi_indexable +#define __CCT_CONTRACT_ATTR___CCT_PTR __indexable #else /* __clang__ + __has_ptrcheck */ -#define __CCT_CONTRACT_ATTR_BPTR -#define __CCT_CONTRACT_ATTR_PTR +#define __CCT_CONTRACT_ATTR___CCT_BPTR +#define __CCT_CONTRACT_ATTR___CCT_PTR #endif /* __clang__ + !__has_ptrcheck */ #else /* !__clang__ */ -#define __CCT_CONTRACT_ATTR_REF -#define __CCT_CONTRACT_ATTR_CREF const -#define __CCT_CONTRACT_ATTR_BPTR -#define __CCT_CONTRACT_ATTR_PTR +#define __CCT_CONTRACT_ATTR___CCT_REF +#define __CCT_CONTRACT_ATTR___CCT_CREF const +#define __CCT_CONTRACT_ATTR___CCT_BPTR +#define __CCT_CONTRACT_ATTR___CCT_PTR #endif /* __clang__ */ -#define __CCT_CONTRACT_TAG_REF _ref -#define __CCT_CONTRACT_TAG_CREF _cref -#define __CCT_CONTRACT_TAG_BPTR _bptr -#define __CCT_CONTRACT_TAG_PTR _ptr +#define __CCT_CONTRACT_TAG___CCT_REF _ref +#define __CCT_CONTRACT_TAG___CCT_CREF _cref +#define __CCT_CONTRACT_TAG___CCT_BPTR _bptr +#define __CCT_CONTRACT_TAG___CCT_PTR _ptr /* Helper macros */ #define __CCT_DEFER(F, ...) F(__VA_ARGS__) @@ -572,20 +595,43 @@ typedef basetype * __CCT_CONTRACT_TO_ATTR(kind1) * __CCT_CONTRACT_TO_ATTR(kind2) \ * __CCT_CONTRACT_TO_ATTR(kind3) \ __CCT_DEFER(__CONCAT, basetag, __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_3(kind1, kind2, kind3)) +#endif /* defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE) */ /* * Lower level type constructor. */ +#if defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE) #define __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...) \ __CCT_DISPATCH(__CCT_DECLARE_CONSTRAINED_PTR_TYPE, basetype, basetag, __VA_ARGS__) +#else /* !defined(KERNEL) && !defined(__CCT_ENABLE_USER_SPACE) */ +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-semi" +#endif /* defined(__clang__) */ +#define __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...) +#if defined(__clang__) +#pragma clang diagnostic pop +#endif /* defined(__clang__) */ +#endif /* !defined(KERNEL) && !defined(__CCT_ENABLE_USER_SPACE) */ /* * Higher level type constructors. - * The constrained types that can potentially break the ABI are not exposed - * into the user-space. */ +#if defined(__CCT_ENABLE_USER_SPACE) +/* Limiting the higher-level constructor to the ABI-preserving constructs. */ #define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag) \ -__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, REF); \ -__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, REF, REF) + __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF); \ + __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_REF) +#else /* !defined(__CCT_ENABLE_USER_SPACE) */ +/* Disabling the higher-level constructor */ +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-semi" +#endif /* defined(__clang__) */ +#define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag) +#if defined(__clang__) +#pragma clang diagnostic pop +#endif /* defined(__clang__) */ +#endif /* !defined(__CCT_ENABLE_USER_SPACE) */ #endif /* __CONSTRAINED_CTYPES__ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/vis.h b/lib/libc/include/any-macos.13-any/vis.h new file mode 100644 index 0000000000..b22f6ab385 --- /dev/null +++ b/lib/libc/include/any-macos.13-any/vis.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* $NetBSD: vis.h,v 1.25 2017/04/23 01:57:36 christos Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)vis.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _VIS_H_ +#define _VIS_H_ + +#include <_types.h> +#include + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x0001 /* use octal \ddd format */ +#define VIS_CSTYLE 0x0002 /* use \[nrft0..] where appropiate */ + +/* + * to alter set of characters encoded (default is to encode all + * non-graphic except space, tab, and newline). + */ +#define VIS_SP 0x0004 /* also encode space */ +#define VIS_TAB 0x0008 /* also encode tab */ +#define VIS_NL 0x0010 /* also encode newline */ +#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x0020 /* only encode "unsafe" characters */ +#define VIS_DQ 0x8000 /* also encode double quotes */ + +/* + * other + */ +#define VIS_NOSLASH 0x0040 /* inhibit printing '\' */ +#define VIS_HTTP1808 0x0080 /* http-style escape % hex hex */ +#define VIS_HTTPSTYLE 0x0080 /* http-style escape % hex hex */ +#define VIS_GLOB 0x0100 /* encode glob(3) magic characters */ +#define VIS_MIMESTYLE 0x0200 /* mime-style escape = HEX HEX */ +#define VIS_HTTP1866 0x0400 /* http-style &#num; or &string; */ +#define VIS_NOESCAPE 0x0800 /* don't decode `\' */ +#define _VIS_END 0x1000 /* for unvis */ +#define VIS_SHELL 0x2000 /* encode shell special characters [not glob] */ +#define VIS_META (VIS_WHITE | VIS_GLOB | VIS_SHELL) +#define VIS_NOLOCALE 0x4000 /* encode using the C locale */ + +/* + * unvis return codes + */ +#define UNVIS_VALID 1 /* character valid */ +#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ +#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ +#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ +#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ + +/* + * unvis flags + */ +#define UNVIS_END _VIS_END /* no more characters */ + +#include + +__BEGIN_DECLS +char *vis(char *, int, int, int); +char *nvis(char *, size_t, int, int, int); + +char *svis(char *, int, int, int, const char *); +char *snvis(char *, size_t, int, int, int, const char *); + +int strvis(char *, const char *, int); +int stravis(char **, const char *, int); +int strnvis(char *, size_t, const char *, int); + +int strsvis(char *, const char *, int, const char *); +int strsnvis(char *, size_t, const char *, int, const char *); + +int strvisx(char *, const char *, size_t, int); +int strnvisx(char *, size_t, const char *, size_t, int); +int strenvisx(char *, size_t, const char *, size_t, int, int *); + +int strsvisx(char *, const char *, size_t, int, const char *); +int strsnvisx(char *, size_t, const char *, size_t, int, const char *); +int strsenvisx(char *, size_t, const char *, size_t , int, const char *, + int *); + +int strunvis(char *, const char *); +int strnunvis(char *, size_t, const char *); + +int strunvisx(char *, const char *, int); +int strnunvisx(char *, size_t, const char *, int); + +int unvis(char *, int, int *, int); +__END_DECLS + +#endif /* !_VIS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/_limits.h b/lib/libc/include/x86_64-macos.11-none/i386/_limits.h index 5763f5a3a8..f942e7abd8 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/_limits.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/_limits.h @@ -22,10 +22,6 @@ #ifndef _I386__LIMITS_H_ #define _I386__LIMITS_H_ -#if defined (__i386__) || defined (__x86_64__) - #define __DARWIN_CLK_TCK 100 /* ticks per second */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _I386__LIMITS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/_mcontext.h b/lib/libc/include/x86_64-macos.11-none/i386/_mcontext.h index b9f40e5e33..424ca21359 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/_mcontext.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/_mcontext.h @@ -29,8 +29,6 @@ #ifndef __I386_MCONTEXT_H_ #define __I386_MCONTEXT_H_ -#if defined (__i386__) || defined (__x86_64__) - #include /* __DARWIN_UNIX03 */ #include #include @@ -211,6 +209,4 @@ typedef _STRUCT_MCONTEXT32 *mcontext_t; #endif #endif /* _MCONTEXT_T */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* __I386_MCONTEXT_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/_param.h b/lib/libc/include/x86_64-macos.11-none/i386/_param.h index ac0ac439aa..b89bc39692 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/_param.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/_param.h @@ -29,8 +29,6 @@ #ifndef _I386__PARAM_H_ #define _I386__PARAM_H_ -#if defined (__i386__) || defined (__x86_64__) - #include /* @@ -44,6 +42,5 @@ #define __DARWIN_ALIGNBYTES32 (sizeof(__uint32_t) - 1) #define __DARWIN_ALIGN32(p) ((__darwin_size_t)((__darwin_size_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32) -#endif /* defined (__i386__) || defined (__x86_64__) */ #endif /* _I386__PARAM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/_types.h b/lib/libc/include/x86_64-macos.11-none/i386/_types.h index b9e77d684c..9dcffa5241 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/_types.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/_types.h @@ -28,8 +28,6 @@ #ifndef _BSD_I386__TYPES_H_ #define _BSD_I386__TYPES_H_ -#if defined (__i386__) || defined (__x86_64__) - /* * This header file contains integer types. It's intended to also contain * flotaing point and other arithmetic types, as needed, later. @@ -121,6 +119,4 @@ typedef __uint32_t __darwin_socklen_t; /* socklen_t (duh) */ typedef long __darwin_ssize_t; /* byte count or error */ typedef long __darwin_time_t; /* time() */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _BSD_I386__TYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/eflags.h b/lib/libc/include/x86_64-macos.11-none/i386/eflags.h index 7faa7d0839..dc73c43126 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/eflags.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/eflags.h @@ -59,8 +59,6 @@ #ifndef _I386_EFLAGS_H_ #define _I386_EFLAGS_H_ -#if defined (__i386__) || defined (__x86_64__) - /* * i386 flags register */ @@ -93,6 +91,4 @@ #define EFL_USER_SET (EFL_IF) #define EFL_USER_CLEAR (EFL_IOPL|EFL_NT|EFL_RF) -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _I386_EFLAGS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/endian.h b/lib/libc/include/x86_64-macos.11-none/i386/endian.h index 104d5babca..95ca16e406 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/endian.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/endian.h @@ -66,8 +66,6 @@ #ifndef _I386__ENDIAN_H_ #define _I386__ENDIAN_H_ -#if defined (__i386__) || defined (__x86_64__) - #include /* * Define _NOQUAD if the compiler does NOT support 64-bit integers. @@ -101,5 +99,4 @@ #include #endif /* defined(KERNEL) || (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ -#endif /* defined (__i386__) || defined (__x86_64__) */ #endif /* !_I386__ENDIAN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/limits.h b/lib/libc/include/x86_64-macos.11-none/i386/limits.h index 292e6bd654..651d770335 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/limits.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/limits.h @@ -36,8 +36,6 @@ #ifndef _I386_LIMITS_H_ #define _I386_LIMITS_H_ -#if defined (__i386__) || defined (__x86_64__) - #include #include @@ -106,6 +104,4 @@ #endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ #endif /* !_ANSI_SOURCE */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _I386_LIMITS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/param.h b/lib/libc/include/x86_64-macos.11-none/i386/param.h index fe2bb9cc06..e8eb8272e7 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/param.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/param.h @@ -72,8 +72,6 @@ #ifndef _I386_PARAM_H_ #define _I386_PARAM_H_ -#if defined (__i386__) || defined (__x86_64__) - #include /* @@ -170,6 +168,4 @@ #define DELAY(n) { int N = (n); while (--N > 0); } #endif /* defined(KERNEL) || defined(STANDALONE) */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _I386_PARAM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/signal.h b/lib/libc/include/x86_64-macos.11-none/i386/signal.h index e699c2b61b..cd837bb7f6 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/signal.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/signal.h @@ -33,8 +33,6 @@ #ifndef _I386_SIGNAL_H_ #define _I386_SIGNAL_H_ 1 -#if defined (__i386__) || defined (__x86_64__) - #include #ifndef _ANSI_SOURCE @@ -42,6 +40,4 @@ typedef int sig_atomic_t; #endif /* ! _ANSI_SOURCE */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _I386_SIGNAL_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/i386/types.h b/lib/libc/include/x86_64-macos.11-none/i386/types.h index 31ffa1f37c..00dee1a917 100644 --- a/lib/libc/include/x86_64-macos.11-none/i386/types.h +++ b/lib/libc/include/x86_64-macos.11-none/i386/types.h @@ -63,12 +63,9 @@ * @(#)types.h 8.3 (Berkeley) 1/5/94 */ -#ifndef _I386_MACHTYPES_H_ -#define _I386_MACHTYPES_H_ +#ifndef _MACHTYPES_H_ #define _MACHTYPES_H_ -#if defined (__i386__) || defined (__x86_64__) - #ifndef __ASSEMBLER__ #include #include @@ -114,5 +111,4 @@ typedef int64_t user_off_t; typedef u_int64_t syscall_arg_t; #endif /* __ASSEMBLER__ */ -#endif /* defined (__i386__) || defined (__x86_64__) */ -#endif /* _I386_MACHTYPES_H_ */ \ No newline at end of file +#endif /* _MACHTYPES_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/_structs.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/_structs.h index 02c135184f..248653b4f8 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/_structs.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/_structs.h @@ -32,8 +32,6 @@ #ifndef _MACH_I386__STRUCTS_H_ #define _MACH_I386__STRUCTS_H_ -#if defined (__i386__) || defined (__x86_64__) - #include /* __DARWIN_UNIX03 */ #include /* __uint8_t */ @@ -1311,6 +1309,4 @@ _STRUCT_X86_CPMU_STATE64 }; #endif /* !__DARWIN_UNIX03 */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386__STRUCTS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/boolean.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/boolean.h index b1d69a193b..d604dfcea2 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/boolean.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/boolean.h @@ -65,14 +65,10 @@ #ifndef _MACH_I386_BOOLEAN_H_ #define _MACH_I386_BOOLEAN_H_ -#if defined (__i386__) || defined (__x86_64__) - #if defined(__x86_64__) && !defined(KERNEL) typedef unsigned int boolean_t; #else typedef int boolean_t; #endif -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_BOOLEAN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/exception.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/exception.h index 1a8b2c0d1d..3f21c3d4e6 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/exception.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/exception.h @@ -59,8 +59,6 @@ #ifndef _MACH_I386_EXCEPTION_H_ #define _MACH_I386_EXCEPTION_H_ -#if defined (__i386__) || defined (__x86_64__) - /* * No machine dependent types for the 80386 */ @@ -134,6 +132,4 @@ */ #define EXC_MASK_MACHINE 0 -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_EXCEPTION_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/fp_reg.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/fp_reg.h index e968978842..eb010ad950 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/fp_reg.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/fp_reg.h @@ -59,8 +59,6 @@ #ifndef _I386_FP_SAVE_H_ #define _I386_FP_SAVE_H_ -#if defined (__i386__) || defined (__x86_64__) - /* * Control register */ @@ -117,6 +115,4 @@ #define FP_387 3 /* 80387 or 80486 */ #define FP_FXSR 4 /* Fast save/restore SIMD Extension */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _I386_FP_SAVE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/kern_return.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/kern_return.h index 3a12665ead..47aa4b8753 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/kern_return.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/kern_return.h @@ -67,12 +67,8 @@ #ifndef _MACH_I386_KERN_RETURN_H_ #define _MACH_I386_KERN_RETURN_H_ -#if defined (__i386__) || defined (__x86_64__) - #ifndef ASSEMBLER typedef int kern_return_t; #endif /* ASSEMBLER */ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_KERN_RETURN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/processor_info.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/processor_info.h index 5a9aeac9cb..4426e0041c 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/processor_info.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/processor_info.h @@ -34,8 +34,4 @@ #ifndef _MACH_I386_PROCESSOR_INFO_H_ #define _MACH_I386_PROCESSOR_INFO_H_ -#if defined (__i386__) || defined (__x86_64__) - -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_PROCESSOR_INFO_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/rpc.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/rpc.h index fcd2829f6b..0298ebb804 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/rpc.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/rpc.h @@ -32,8 +32,4 @@ #ifndef _MACH_I386_RPC_H_ #define _MACH_I386_RPC_H_ -#if defined (__i386__) || defined (__x86_64__) - -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_RPC_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_state.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_state.h index 421917aeb3..4d9825be70 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_state.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_state.h @@ -32,11 +32,11 @@ #ifndef _MACH_I386_THREAD_STATE_H_ #define _MACH_I386_THREAD_STATE_H_ -#if defined (__i386__) || defined (__x86_64__) - /* Size of maximum exported thread state in 32-bit words */ #define I386_THREAD_STATE_MAX (614) /* Size of biggest state possible */ -#endif /* defined (__i386__) || defined (__x86_64__) */ +#if defined (__i386__) || defined(__x86_64__) +#define THREAD_STATE_MAX I386_THREAD_STATE_MAX +#endif #endif /* _MACH_I386_THREAD_STATE_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_status.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_status.h index d401a11fd0..24de7ae76c 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_status.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/thread_status.h @@ -67,12 +67,10 @@ #ifndef _MACH_I386_THREAD_STATUS_H_ #define _MACH_I386_THREAD_STATUS_H_ -#if defined (__i386__) || defined (__x86_64__) - #include -#include #include #include +#include #include @@ -361,6 +359,4 @@ typedef struct x86_avx512_state x86_avx512_state_t; #define MACHINE_THREAD_STATE_COUNT x86_THREAD_STATE_COUNT -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_THREAD_STATUS_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_param.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_param.h index 953f4a1605..fa27fffa2f 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_param.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_param.h @@ -90,8 +90,6 @@ #ifndef _MACH_I386_VM_PARAM_H_ #define _MACH_I386_VM_PARAM_H_ -#if defined (__i386__) || defined (__x86_64__) - #if !defined(KERNEL) && !defined(__ASSEMBLER__) #include @@ -124,11 +122,9 @@ #define VM_MIN_ADDRESS64 ((user_addr_t) 0x0000000000000000ULL) /* - * Default top of user stack, grows down from here. - * Address chosen to be 1G (3rd level page table entry) below SHARED_REGION_BASE_X86_64 - * minus additional 1Meg (1/2 1st level page table coverage) to allow a redzone after it. + * default top of user stack... it grows down from here */ -#define VM_USRSTACK64 ((user_addr_t) (0x00007FF7C0000000ull - (1024 * 1024))) +#define VM_USRSTACK64 ((user_addr_t) 0x00007FFEEFC00000ULL) /* * XXX TODO: Obsolete? @@ -158,6 +154,4 @@ -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_VM_PARAM_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_types.h b/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_types.h index f3e956d3e2..57bc28af88 100644 --- a/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_types.h +++ b/lib/libc/include/x86_64-macos.11-none/mach/i386/vm_types.h @@ -67,13 +67,10 @@ #ifndef _MACH_I386_VM_TYPES_H_ #define _MACH_I386_VM_TYPES_H_ -#if defined (__i386__) || defined (__x86_64__) - #ifndef ASSEMBLER #include #include -#include /* * natural_t and integer_t are Mach's legacy types for machine- @@ -100,9 +97,9 @@ typedef int integer_t; * e.g. an offset into a virtual memory space. */ #ifdef __LP64__ -typedef uintptr_t vm_offset_t __kernel_ptr_semantics; +typedef uintptr_t vm_offset_t; #else /* __LP64__ */ -typedef natural_t vm_offset_t __kernel_ptr_semantics; +typedef natural_t vm_offset_t; #endif /* __LP64__ */ /* @@ -123,12 +120,12 @@ typedef natural_t vm_size_t; * where the size of the map is not known - or we don't * want to have to distinguish. */ -typedef uint64_t mach_vm_address_t __kernel_ptr_semantics; -typedef uint64_t mach_vm_offset_t __kernel_ptr_semantics; +typedef uint64_t mach_vm_address_t; +typedef uint64_t mach_vm_offset_t; typedef uint64_t mach_vm_size_t; -typedef uint64_t vm_map_offset_t __kernel_ptr_semantics; -typedef uint64_t vm_map_address_t __kernel_ptr_semantics; +typedef uint64_t vm_map_offset_t; +typedef uint64_t vm_map_address_t; typedef uint64_t vm_map_size_t; typedef mach_vm_address_t mach_port_context_t; @@ -141,6 +138,4 @@ typedef mach_vm_address_t mach_port_context_t; */ #define MACH_MSG_TYPE_INTEGER_T MACH_MSG_TYPE_INTEGER_32 -#endif /* defined (__i386__) || defined (__x86_64__) */ - #endif /* _MACH_I386_VM_TYPES_H_ */ \ No newline at end of file From 4569a28ea35e7152f01db1d36c493506b6ca71b6 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Sat, 25 Mar 2023 16:33:25 -0400 Subject: [PATCH 115/216] build: fixes from review --- lib/std/Build/CompileStep.zig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/std/Build/CompileStep.zig b/lib/std/Build/CompileStep.zig index 96fd9deb9c..b438331991 100644 --- a/lib/std/Build/CompileStep.zig +++ b/lib/std/Build/CompileStep.zig @@ -140,7 +140,8 @@ link_function_sections: bool = false, /// exported symbols. link_gc_sections: ?bool = null, -linker_dynamicbase: ?bool = null, +/// (Windows) Whether or not to enable ASLR. Maps to the /DYNAMICBASE[:NO] linker argument. +linker_dynamicbase: bool = true, linker_allow_shlib_undefined: ?bool = null, @@ -1476,8 +1477,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { if (self.link_gc_sections) |x| { try zig_args.append(if (x) "--gc-sections" else "--no-gc-sections"); } - if (self.linker_dynamicbase) |x| { - if (!x) try zig_args.append("--no-dynamicbase"); + if (!self.linker_dynamicbase) { + try zig_args.append("--no-dynamicbase"); } if (self.linker_allow_shlib_undefined) |x| { try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined"); From 59a67e9a43fe28537e9d0cf7fd346aaba8a6ce77 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 25 Mar 2023 21:38:35 +0100 Subject: [PATCH 116/216] libc: update macOS libSystem stubs --- lib/libc/darwin/libSystem.11.tbd | 22 +- lib/libc/darwin/libSystem.12.tbd | 787 +++++++++++++++++-------------- lib/libc/darwin/libSystem.13.tbd | 416 ++++++++-------- 3 files changed, 642 insertions(+), 583 deletions(-) diff --git a/lib/libc/darwin/libSystem.11.tbd b/lib/libc/darwin/libSystem.11.tbd index c9a41f65d6..12d4dbeb5c 100644 --- a/lib/libc/darwin/libSystem.11.tbd +++ b/lib/libc/darwin/libSystem.11.tbd @@ -4,17 +4,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 89E331F9-9A00-3EA4-B49F-FA2B91AE9182 + value: EADFB1D1-E113-35B4-BD2D-C1E4C38010D4 - target: x86_64-maccatalyst - value: 89E331F9-9A00-3EA4-B49F-FA2B91AE9182 + value: EADFB1D1-E113-35B4-BD2D-C1E4C38010D4 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: A9F7E132-0FFC-31FC-83C6-3848CA460DF3 + value: A03485B7-4C44-3F47-8BF9-5D6E1BE0CF27 - target: arm64e-maccatalyst - value: A9F7E132-0FFC-31FC-83C6-3848CA460DF3 + value: A03485B7-4C44-3F47-8BF9-5D6E1BE0CF27 install-name: '/usr/lib/libSystem.B.dylib' current-version: 1292.100.5 reexported-libraries: @@ -2058,19 +2058,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: A78F60F4-ABD5-3646-93F9-1F1109C4552D + value: 62A19DE4-50C5-3866-B5B2-43220E379C3B - target: x86_64-maccatalyst - value: A78F60F4-ABD5-3646-93F9-1F1109C4552D + value: 62A19DE4-50C5-3866-B5B2-43220E379C3B - target: arm64-macos - value: B7A2A355-3D98-3BBF-82CC-A82E05B30F1B + value: C11F3472-54B1-3A61-A02F-6A80EA06F414 - target: arm64-maccatalyst - value: B7A2A355-3D98-3BBF-82CC-A82E05B30F1B + value: C11F3472-54B1-3A61-A02F-6A80EA06F414 - target: arm64e-macos - value: 1B63FA43-CA44-3EB6-BF55-54F2E306B3CE + value: D4C172DA-4E97-32E4-8969-C738E4AC9559 - target: arm64e-maccatalyst - value: 1B63FA43-CA44-3EB6-BF55-54F2E306B3CE + value: D4C172DA-4E97-32E4-8969-C738E4AC9559 install-name: '/usr/lib/system/libsystem_kernel.dylib' -current-version: 7195.101.1 +current-version: 7195.101.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] diff --git a/lib/libc/darwin/libSystem.12.tbd b/lib/libc/darwin/libSystem.12.tbd index c82d4fb93a..8537715a3e 100644 --- a/lib/libc/darwin/libSystem.12.tbd +++ b/lib/libc/darwin/libSystem.12.tbd @@ -4,19 +4,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 2F242680-1523-3527-B7BA-13F7398854BF + value: 5E73061C-E99B-3651-BD84-E34B6365E97D - target: x86_64-maccatalyst - value: 2F242680-1523-3527-B7BA-13F7398854BF + value: 5E73061C-E99B-3651-BD84-E34B6365E97D - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 679CDB15-D472-38E8-8840-B38874010D51 + value: DEE4A1ED-F9DF-3515-BE62-166170214E4C - target: arm64e-maccatalyst - value: 679CDB15-D472-38E8-8840-B38874010D51 + value: DEE4A1ED-F9DF-3515-BE62-166170214E4C install-name: '/usr/lib/libSystem.B.dylib' -current-version: 1311 +current-version: 1311.100.3 reexported-libraries: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -59,17 +59,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: B547F879-03EB-3693-80A2-D588EF6EB815 + value: 347DF236-2F9C-3EC3-B164-55417B437B97 - target: x86_64-maccatalyst - value: B547F879-03EB-3693-80A2-D588EF6EB815 + value: 347DF236-2F9C-3EC3-B164-55417B437B97 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: BB47A721-69A7-3EEA-9D9B-82F88FFF2641 + value: E5029B58-FF22-3EC8-9708-A97E2C90C310 - target: arm64e-maccatalyst - value: BB47A721-69A7-3EEA-9D9B-82F88FFF2641 + value: E5029B58-FF22-3EC8-9708-A97E2C90C310 install-name: '/usr/lib/system/libcache.dylib' current-version: 85 parent-umbrella: @@ -77,7 +77,7 @@ parent-umbrella: arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _cache_create, _cache_destroy, _cache_get, _cache_get_and_retain, _cache_get_cost_hint, _cache_get_count_hint, _cache_get_info, @@ -96,25 +96,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 2308E152-A258-36BC-A841-D3E8E9F59F43 + value: C36DA5CF-B8E6-36C1-98EF-FF138B438EE0 - target: x86_64-maccatalyst - value: 2308E152-A258-36BC-A841-D3E8E9F59F43 + value: C36DA5CF-B8E6-36C1-98EF-FF138B438EE0 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: E6CCD148-5E91-3111-BE37-1C19402F4637 + value: 5AAADB40-420D-326A-AC38-CFE1D81DA1E5 - target: arm64e-maccatalyst - value: E6CCD148-5E91-3111-BE37-1C19402F4637 + value: 5AAADB40-420D-326A-AC38-CFE1D81DA1E5 install-name: '/usr/lib/system/libcommonCrypto.dylib' -current-version: 60190 +current-version: 60191.100.1 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _CCAESCmac, _CCAESCmacCreate, _CCAESCmacDestroy, _CCAESCmacFinal, _CCAESCmacOutputSizeFromContext, _CCAESCmacUpdate, _CCBigNumAdd, @@ -190,13 +190,13 @@ tbd-version: 4 targets: [ x86_64-macos, arm64-macos, arm64e-macos ] uuids: - target: x86_64-macos - value: 805EDC9F-9F04-3DF0-96B6-B2530FAE7722 + value: AD346AFB-8737-3E88-B4C5-25D77181AE44 - target: arm64-macos - value: 2CF1B1A8-6B2C-3DA7-9A6F-B08089C83421 + value: 0B616B91-A847-3817-B571-4498A1D36CC0 - target: arm64e-macos - value: 92001FF7-799E-3BA8-BF46-5FA01FFB952C + value: 7E374D5C-9785-3D65-88D2-98B92AD24C78 install-name: '/usr/lib/system/libcompiler_rt.dylib' -current-version: 102.2 +current-version: 103.1 parent-umbrella: - targets: [ x86_64-macos, arm64-macos, arm64e-macos ] umbrella: System @@ -237,7 +237,7 @@ exports: ___paritysi2, ___parityti2, ___popcountdi2, ___popcountsi2, ___popcountti2, ___powixf2, ___subvdi3, ___subvsi3, ___subvti3, ___ucmpdi2, ___ucmpti2, ___udivdi3, ___udivmoddi4, ___umoddi3 ] - - targets: [ arm64-macos, x86_64-macos, arm64e-macos ] + - targets: [ arm64-macos, arm64e-macos, x86_64-macos ] symbols: [ '$ld$hide$os10.10$___chkstk_darwin', '$ld$hide$os10.10$___extendhfsf2', '$ld$hide$os10.10$___truncdfhf2', '$ld$hide$os10.10$___truncsfhf2', '$ld$hide$os10.10$_atomic_flag_clear', '$ld$hide$os10.10$_atomic_flag_clear_explicit', @@ -407,16 +407,16 @@ exports: ___atomic_fetch_or_2, ___atomic_fetch_or_4, ___atomic_fetch_or_8, ___atomic_fetch_sub_1, ___atomic_fetch_sub_2, ___atomic_fetch_sub_4, ___atomic_fetch_sub_8, ___atomic_fetch_xor_1, ___atomic_fetch_xor_2, - ___atomic_fetch_xor_4, ___atomic_fetch_xor_8, ___atomic_load, - ___atomic_load_1, ___atomic_load_2, ___atomic_load_4, ___atomic_load_8, - ___atomic_store, ___atomic_store_1, ___atomic_store_2, ___atomic_store_4, - ___atomic_store_8, ___chkstk_darwin, ___clear_cache, ___clzti2, - ___divti3, ___enable_execute_stack, ___extendhfsf2, ___fixdfti, - ___fixsfti, ___fixunsdfti, ___fixunssfti, ___floattidf, ___floattisf, - ___floatuntidf, ___floatuntisf, ___gcc_personality_v0, ___gnu_f2h_ieee, - ___gnu_h2f_ieee, ___modti3, ___muldc3, ___mulsc3, ___powidf2, - ___powisf2, ___truncdfhf2, ___truncsfhf2, ___udivmodti4, ___udivti3, - ___umodti3, _atomic_flag_clear, _atomic_flag_clear_explicit, + ___atomic_fetch_xor_4, ___atomic_fetch_xor_8, ___atomic_is_lock_free, + ___atomic_load, ___atomic_load_1, ___atomic_load_2, ___atomic_load_4, + ___atomic_load_8, ___atomic_store, ___atomic_store_1, ___atomic_store_2, + ___atomic_store_4, ___atomic_store_8, ___chkstk_darwin, ___clear_cache, + ___clzti2, ___divti3, ___enable_execute_stack, ___extendhfsf2, + ___fixdfti, ___fixsfti, ___fixunsdfti, ___fixunssfti, ___floattidf, + ___floattisf, ___floatuntidf, ___floatuntisf, ___gcc_personality_v0, + ___gnu_f2h_ieee, ___gnu_h2f_ieee, ___modti3, ___muldc3, ___mulsc3, + ___powidf2, ___powisf2, ___truncdfhf2, ___truncsfhf2, ___udivmodti4, + ___udivti3, ___umodti3, _atomic_flag_clear, _atomic_flag_clear_explicit, _atomic_flag_test_and_set, _atomic_flag_test_and_set_explicit, _atomic_signal_fence, _atomic_thread_fence ] --- !tapi-tbd @@ -425,24 +425,24 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: DA53E55D-FBC9-3EF8-A1B0-78CDC0457EC4 + value: C5E0151C-F9E9-3851-841D-F6C2528ADB07 - target: x86_64-maccatalyst - value: DA53E55D-FBC9-3EF8-A1B0-78CDC0457EC4 + value: C5E0151C-F9E9-3851-841D-F6C2528ADB07 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 6BE94DC2-F363-3D76-B056-F45D4B56E152 + value: 97564E56-1B3C-3C9A-B653-AE99C54231AC - target: arm64e-maccatalyst - value: 6BE94DC2-F363-3D76-B056-F45D4B56E152 + value: 97564E56-1B3C-3C9A-B653-AE99C54231AC install-name: '/usr/lib/system/libcopyfile.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _copyfile, _copyfile_state_alloc, _copyfile_state_free, _copyfile_state_get, _copyfile_state_set, _fcopyfile, _xattr_flags_from_name, _xattr_intent_with_flags, @@ -453,19 +453,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 1841B3FA-9360-3F14-903F-265EB054EACB + value: E8AE6CBE-D5F8-32B8-A9D3-A2D8BF77F4D0 - target: x86_64-maccatalyst - value: 1841B3FA-9360-3F14-903F-265EB054EACB + value: E8AE6CBE-D5F8-32B8-A9D3-A2D8BF77F4D0 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 881973B2-0426-325F-8D1A-17D60AE0CBFA + value: 29B2F7FD-0F6D-3F41-B569-FB4AE94F4D6B - target: arm64e-maccatalyst - value: 881973B2-0426-325F-8D1A-17D60AE0CBFA + value: 29B2F7FD-0F6D-3F41-B569-FB4AE94F4D6B install-name: '/usr/lib/system/libcorecrypto.dylib' -current-version: 1217.30.4 +current-version: 1218.100.47 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -484,7 +484,7 @@ exports: _ccaes_intel_xts_encrypt_aesni_mode, _ccaes_intel_xts_encrypt_opt_mode, _ccsha1_vng_intel_SupplementalSSE3_di, _ccsha224_vng_intel_SupplementalSSE3_di, _ccsha256_vng_intel_SupplementalSSE3_di ] - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _CCEC_FAULT_CANARY, _CCRSA_PKCS1_FAULT_CANARY, _CCRSA_PSS_FAULT_CANARY, _CCSS_PRIME_P192, _CCSS_PRIME_P224, _CCSS_PRIME_P256, _CCSS_PRIME_P384, @@ -578,11 +578,12 @@ exports: _ccdh_gp_rfc5114_MODP_1024_160, _ccdh_gp_rfc5114_MODP_2048_224, _ccdh_gp_rfc5114_MODP_2048_256, _ccdh_gp_size, _ccdh_import_full, _ccdh_import_priv, _ccdh_import_pub, _ccdh_init_gp_from_bytes, - _ccdigest, _ccdigest_init, _ccdigest_oid_lookup, _ccdigest_update, - _ccdrbg_factory_nistctr, _ccdrbg_factory_nisthmac, _ccec_blind, - _ccec_compact_export, _ccec_compact_export_pub, _ccec_compact_generate_key, - _ccec_compact_import_priv, _ccec_compact_import_priv_size, - _ccec_compact_import_pub, _ccec_compact_import_pub_size, _ccec_compact_transform_key, + _ccdh_init_safe_gp_from_bytes, _ccdigest, _ccdigest_init, + _ccdigest_oid_lookup, _ccdigest_update, _ccdrbg_factory_nistctr, + _ccdrbg_factory_nisthmac, _ccec_affinify, _ccec_blind, _ccec_compact_export, + _ccec_compact_export_pub, _ccec_compact_generate_key, _ccec_compact_import_priv, + _ccec_compact_import_priv_size, _ccec_compact_import_pub, + _ccec_compact_import_pub_size, _ccec_compact_transform_key, _ccec_compressed_x962_export_pub, _ccec_compressed_x962_export_pub_size, _ccec_compressed_x962_import_pub, _ccec_compute_key, _ccec_cp_192, _ccec_cp_224, _ccec_cp_256, _ccec_cp_384, _ccec_cp_521, _ccec_curve_for_length_lookup, @@ -590,14 +591,15 @@ exports: _ccec_der_export_priv, _ccec_der_export_priv_size, _ccec_der_import_diversified_pub, _ccec_der_import_priv, _ccec_der_import_priv_keytype, _ccec_diversify_min_entropy_len, _ccec_diversify_priv_twin, _ccec_diversify_pub, _ccec_diversify_pub_twin, - _ccec_export_pub, _ccec_extract_rs, _ccec_generate_blinding_keys, + _ccec_export_pub, _ccec_extract_rs, _ccec_full_add, _ccec_generate_blinding_keys, _ccec_generate_key, _ccec_generate_key_deterministic, _ccec_generate_key_fips, - _ccec_generate_key_legacy, _ccec_get_cp, _ccec_get_fullkey_components, - _ccec_get_pubkey_components, _ccec_import_pub, _ccec_keysize_is_supported, - _ccec_make_priv, _ccec_make_pub, _ccec_pairwise_consistency_check, - _ccec_print_full_key, _ccec_print_public_key, _ccec_raw_import_priv_only, - _ccec_raw_import_pub, _ccec_rfc6637_dh_curve_p256, _ccec_rfc6637_dh_curve_p521, - _ccec_rfc6637_unwrap_key, _ccec_rfc6637_unwrap_sha256_kek_aes128, + _ccec_generate_key_legacy, _ccec_generate_scalar_fips_retry, + _ccec_get_cp, _ccec_get_fullkey_components, _ccec_get_pubkey_components, + _ccec_import_pub, _ccec_keysize_is_supported, _ccec_make_priv, + _ccec_make_pub, _ccec_mult_blinded, _ccec_pairwise_consistency_check, + _ccec_print_full_key, _ccec_print_public_key, _ccec_projectify, + _ccec_raw_import_priv_only, _ccec_raw_import_pub, _ccec_rfc6637_dh_curve_p256, + _ccec_rfc6637_dh_curve_p521, _ccec_rfc6637_unwrap_key, _ccec_rfc6637_unwrap_sha256_kek_aes128, _ccec_rfc6637_unwrap_sha512_kek_aes256, _ccec_rfc6637_wrap_key, _ccec_rfc6637_wrap_key_diversified, _ccec_rfc6637_wrap_key_size, _ccec_rfc6637_wrap_sha256_kek_aes128, _ccec_rfc6637_wrap_sha512_kek_aes256, @@ -671,8 +673,7 @@ exports: _ccrsa_sign_pss, _ccrsa_sign_pss_msg, _ccrsa_verify_pkcs1v15, _ccrsa_verify_pkcs1v15_allowshortsigs, _ccrsa_verify_pkcs1v15_digest, _ccrsa_verify_pkcs1v15_msg, _ccrsa_verify_pss_digest, _ccrsa_verify_pss_msg, - _ccrsabssa_blind_message, _ccrsabssa_ciphersuite_rsa2048_sha256, - _ccrsabssa_ciphersuite_rsa2048_sha384, _ccrsabssa_ciphersuite_rsa3072_sha256, + _ccrsabssa_blind_message, _ccrsabssa_ciphersuite_rsa2048_sha384, _ccrsabssa_ciphersuite_rsa3072_sha384, _ccrsabssa_ciphersuite_rsa4096_sha384, _ccrsabssa_sign_blinded_message, _ccrsabssa_unblind_signature, _ccsae_gen_kck_and_pmk, _ccsae_gen_password_value, _ccsae_generate_commitment, @@ -728,8 +729,9 @@ exports: _ccz_set, _ccz_set_bit, _ccz_seti, _ccz_size, _ccz_sub, _ccz_subi, _ccz_trailing_zeros, _ccz_write_int, _ccz_write_int_size, _ccz_write_radix, _ccz_write_radix_size, _ccz_write_uint, - _ccz_write_uint_size, _ccz_zero, _csss_shamir_share_bag_can_recover_secret, - _fipspost_post, _fipspost_trace_vtable ] + _ccz_write_uint_size, _ccz_zero, _cczp_add, _cczp_inv, _cczp_mod, + _cczp_mul, _cczp_sub, _csss_shamir_share_bag_can_recover_secret, + _fipspost_post, _fipspost_trace_vtable, _map_to_curve_sswu ] - targets: [ arm64e-macos, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _ccaes_arm_cbc_decrypt_mode, _ccaes_arm_cbc_encrypt_mode, _ccaes_arm_cfb_decrypt_mode, _ccaes_arm_cfb_encrypt_mode, @@ -744,19 +746,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: D98AD4CA-5E4C-3842-AC57-2C65CDAFFAB9 + value: 31D69D55-9895-326C-AD61-621C5CA87314 - target: x86_64-maccatalyst - value: D98AD4CA-5E4C-3842-AC57-2C65CDAFFAB9 + value: 31D69D55-9895-326C-AD61-621C5CA87314 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 9C4116F5-B8EB-3A00-B4B5-54AF6A76F66B + value: DC048E3B-E023-3D17-AFE5-4FF3DC625608 - target: arm64e-maccatalyst - value: 9C4116F5-B8EB-3A00-B4B5-54AF6A76F66B + value: DC048E3B-E023-3D17-AFE5-4FF3DC625608 install-name: '/usr/lib/system/libdispatch.dylib' -current-version: 1324.30.6 +current-version: 1325.100.36 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -799,23 +801,22 @@ exports: __os_object_retain_with_resurrect, _dispatch_activate, _dispatch_after, _dispatch_after_f, _dispatch_allocator_layout, _dispatch_apply, _dispatch_apply_attr_destroy, _dispatch_apply_attr_init, _dispatch_apply_attr_query, - _dispatch_apply_attr_set_amx_parallelism, _dispatch_apply_f, - _dispatch_apply_with_attr, _dispatch_apply_with_attr_f, _dispatch_assert_queue, - '_dispatch_assert_queue$V2', _dispatch_assert_queue_barrier, - _dispatch_assert_queue_not, '_dispatch_assert_queue_not$V2', - _dispatch_async, _dispatch_async_and_wait, _dispatch_async_and_wait_f, - _dispatch_async_enforce_qos_class_f, _dispatch_async_f, _dispatch_async_swift_job, - _dispatch_atfork_child, _dispatch_atfork_parent, _dispatch_atfork_prepare, - _dispatch_barrier_async, _dispatch_barrier_async_and_wait, - _dispatch_barrier_async_and_wait_f, _dispatch_barrier_async_f, - _dispatch_barrier_sync, _dispatch_barrier_sync_f, _dispatch_benchmark, - _dispatch_benchmark_f, _dispatch_block_cancel, _dispatch_block_create, - _dispatch_block_create_with_qos_class, _dispatch_block_create_with_voucher, - _dispatch_block_create_with_voucher_and_qos_class, _dispatch_block_notify, - _dispatch_block_perform, _dispatch_block_testcancel, _dispatch_block_wait, - _dispatch_channel_async, _dispatch_channel_async_f, _dispatch_channel_cancel, - _dispatch_channel_create, _dispatch_channel_drain, _dispatch_channel_drain_f, - _dispatch_channel_enqueue, _dispatch_channel_foreach_work_item_peek, + _dispatch_apply_attr_set_parallelism, _dispatch_apply_f, _dispatch_apply_with_attr, + _dispatch_apply_with_attr_f, _dispatch_assert_queue, '_dispatch_assert_queue$V2', + _dispatch_assert_queue_barrier, _dispatch_assert_queue_not, + '_dispatch_assert_queue_not$V2', _dispatch_async, _dispatch_async_and_wait, + _dispatch_async_and_wait_f, _dispatch_async_enforce_qos_class_f, + _dispatch_async_f, _dispatch_async_swift_job, _dispatch_atfork_child, + _dispatch_atfork_parent, _dispatch_atfork_prepare, _dispatch_barrier_async, + _dispatch_barrier_async_and_wait, _dispatch_barrier_async_and_wait_f, + _dispatch_barrier_async_f, _dispatch_barrier_sync, _dispatch_barrier_sync_f, + _dispatch_benchmark, _dispatch_benchmark_f, _dispatch_block_cancel, + _dispatch_block_create, _dispatch_block_create_with_qos_class, + _dispatch_block_create_with_voucher, _dispatch_block_create_with_voucher_and_qos_class, + _dispatch_block_notify, _dispatch_block_perform, _dispatch_block_testcancel, + _dispatch_block_wait, _dispatch_channel_async, _dispatch_channel_async_f, + _dispatch_channel_cancel, _dispatch_channel_create, _dispatch_channel_drain, + _dispatch_channel_drain_f, _dispatch_channel_enqueue, _dispatch_channel_foreach_work_item_peek, _dispatch_channel_foreach_work_item_peek_f, _dispatch_channel_testcancel, _dispatch_channel_wakeup, _dispatch_data_apply, _dispatch_data_apply_f, _dispatch_data_copy_region, _dispatch_data_create, _dispatch_data_create_alloc, @@ -869,8 +870,9 @@ exports: _dispatch_source_set_registration_handler, _dispatch_source_set_registration_handler_f, _dispatch_source_set_timer, _dispatch_source_testcancel, _dispatch_suspend, _dispatch_swift_job_should_yield, _dispatch_sync, _dispatch_sync_f, - _dispatch_time, _dispatch_time_to_nsecs, _dispatch_tsd_indexes, - _dispatch_walltime, _dispatch_workloop_copy_current, _dispatch_workloop_create, + _dispatch_time, _dispatch_time_from_nsec, _dispatch_time_to_nsec, + _dispatch_time_to_nsecs, _dispatch_tsd_indexes, _dispatch_walltime, + _dispatch_workloop_copy_current, _dispatch_workloop_create, _dispatch_workloop_create_inactive, _dispatch_workloop_is_current, _dispatch_workloop_set_autorelease_frequency, _dispatch_workloop_set_cpupercent, _dispatch_workloop_set_os_workgroup, _dispatch_workloop_set_qos_class, @@ -903,7 +905,8 @@ exports: _voucher_get_activity_id, _voucher_get_activity_id_and_creator, _voucher_get_current_persona, _voucher_get_current_persona_originator_info, _voucher_get_current_persona_proximate_info, _voucher_kvoucher_debug, - _voucher_process_can_use_arbitrary_personas, _voucher_replace_default_voucher ] + _voucher_process_can_use_arbitrary_personas, _voucher_release, + _voucher_replace_default_voucher, _voucher_retain ] objc-classes: [ OS_dispatch_channel, OS_dispatch_data, OS_dispatch_disk, OS_dispatch_group, OS_dispatch_io, OS_dispatch_mach, OS_dispatch_mach_msg, OS_dispatch_object, OS_dispatch_operation, OS_dispatch_queue, OS_dispatch_queue_attr, @@ -917,26 +920,26 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: D2F8B1F4-12FF-3226-9FCB-75193C2EDE2E + value: 6627654A-F427-3E04-98AC-492A1CA26FCC - target: x86_64-maccatalyst - value: D2F8B1F4-12FF-3226-9FCB-75193C2EDE2E + value: 6627654A-F427-3E04-98AC-492A1CA26FCC - target: arm64-macos - value: 7F570139-CD4C-32F5-B68D-AFB040F45EC4 + value: 23F54944-4C0C-3479-93BE-F3A9D0B05724 - target: arm64-maccatalyst - value: 7F570139-CD4C-32F5-B68D-AFB040F45EC4 + value: 23F54944-4C0C-3479-93BE-F3A9D0B05724 - target: arm64e-macos - value: 96ECED73-F10C-3941-91A7-00254B907499 + value: D9C3F911-6697-3B95-A4F6-4FB979F04A6E - target: arm64e-maccatalyst - value: 96ECED73-F10C-3941-91A7-00254B907499 + value: D9C3F911-6697-3B95-A4F6-4FB979F04A6E install-name: '/usr/lib/system/libdyld.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ arm64-macos, x86_64-macos, arm64e-macos ] + - targets: [ arm64-macos, arm64e-macos, x86_64-macos ] symbols: [ _dyld_shared_cache_for_each_subcache4Rosetta, _dyld_shared_subcache_get_info4Rosetta ] - - targets: [ arm64-macos, x86_64-macos, arm64e-macos, x86_64-maccatalyst, + - targets: [ arm64-macos, arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64-maccatalyst, arm64e-maccatalyst ] symbols: [ _NSAddImage, _NSAddLibrary, _NSAddLibraryWithSearching, _NSAddressOfSymbol, _NSCreateObjectFileImageFromFile, _NSCreateObjectFileImageFromMemory, @@ -952,6 +955,7 @@ exports: _NSVersionOfLinkTimeLibrary, _NSVersionOfRunTimeLibrary, _NXArgc, _NXArgv, __NSGetExecutablePath, ___progname, __dyld_all_twolevel_modules_prebound, __dyld_atfork_parent, __dyld_atfork_prepare, __dyld_bind_fully_image_containing_address, + __dyld_dlopen_atfork_child, __dyld_dlopen_atfork_parent, __dyld_dlopen_atfork_prepare, __dyld_find_foreign_type_protocol_conformance, __dyld_find_protocol_conformance, __dyld_find_unwind_sections, __dyld_for_each_objc_class, __dyld_for_each_objc_protocol, __dyld_fork_child, __dyld_get_image_header, __dyld_get_image_header_containing_address, @@ -1007,17 +1011,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 8F475783-80D3-378E-9A99-82602250DA06 + value: CCF77FC2-C655-30F7-AE37-9470E1C91C88 - target: x86_64-maccatalyst - value: 8F475783-80D3-378E-9A99-82602250DA06 + value: CCF77FC2-C655-30F7-AE37-9470E1C91C88 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: F7CDC52B-7961-3283-A30F-B06E2E6ED6AB + value: 7B91E34D-FEF4-3CAB-ABA5-B2CBCD2BCDC0 - target: arm64e-maccatalyst - value: F7CDC52B-7961-3283-A30F-B06E2E6ED6AB + value: 7B91E34D-FEF4-3CAB-ABA5-B2CBCD2BCDC0 install-name: '/usr/lib/system/libkeymgr.dylib' current-version: 31 parent-umbrella: @@ -1025,7 +1029,7 @@ parent-umbrella: arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ ___keymgr_dwarf2_register_sections, ___keymgr_initializer, __keymgr_get_and_lock_processwide_ptr, __keymgr_get_and_lock_processwide_ptr_2, @@ -1037,24 +1041,24 @@ tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ] uuids: - target: x86_64-macos - value: 962FA64E-23DE-3C77-AD8B-B302B5E892FF + value: 4D6563C4-0109-33EF-9641-5762CA377023 - target: x86_64-maccatalyst - value: 962FA64E-23DE-3C77-AD8B-B302B5E892FF + value: 4D6563C4-0109-33EF-9641-5762CA377023 - target: arm64-macos - value: 45FA69BC-984E-3D28-9D18-B3EEBA237CBE + value: 5098ED51-AC6F-3D86-94CA-DB77E3BF43EE - target: arm64-maccatalyst - value: 45FA69BC-984E-3D28-9D18-B3EEBA237CBE + value: 5098ED51-AC6F-3D86-94CA-DB77E3BF43EE - target: arm64e-macos - value: 8D2BECEF-1038-3F2C-B8EF-B02C03092286 + value: A96A86CA-C4C0-3013-BB2E-5F7572B18A00 - target: arm64e-maccatalyst - value: 8D2BECEF-1038-3F2C-B8EF-B02C03092286 + value: A96A86CA-C4C0-3013-BB2E-5F7572B18A00 install-name: '/usr/lib/system/libmacho.dylib' -current-version: 987 +current-version: 994 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ] umbrella: System exports: - - targets: [ arm64-macos, x86_64-macos, arm64e-macos, x86_64-maccatalyst ] + - targets: [ arm64-macos, arm64e-macos, x86_64-macos, x86_64-maccatalyst ] symbols: [ _NXCombineCpuSubtypes, _NXFindBestFatArch, _NXFindBestFatArch_64, _NXFreeArchInfo, _NXGetAllArchInfos, _NXGetArchInfoFromCpuType, _NXGetArchInfoFromName, _NXGetLocalArchInfo, _get_edata, _get_end, @@ -1097,25 +1101,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: C6D1E49B-561D-3F84-8548-18FE40AB02DA + value: BFB0329D-28B0-3FF8-AF71-FB8798721547 - target: x86_64-maccatalyst - value: C6D1E49B-561D-3F84-8548-18FE40AB02DA + value: BFB0329D-28B0-3FF8-AF71-FB8798721547 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 3D861651-91A7-3D78-B43B-ECAA41D63D9E + value: 49C11AB5-FD65-39BE-A1C7-AD885809511E - target: arm64e-maccatalyst - value: 3D861651-91A7-3D78-B43B-ECAA41D63D9E + value: 49C11AB5-FD65-39BE-A1C7-AD885809511E install-name: '/usr/lib/system/libquarantine.dylib' -current-version: 129.30.3 +current-version: 133.100.3 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ ___esp_check, ___esp_check_ns, ___esp_enabled, ___esp_notify, ___esp_notify_ns, __qtn_error, __qtn_file_alloc, __qtn_file_apply_to_fd, @@ -1151,17 +1155,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: A88ED990-563F-3230-9C80-703A3134AEE4 + value: 06A5E617-FB01-3F34-9A4C-CA3894CE0438 - target: x86_64-maccatalyst - value: A88ED990-563F-3230-9C80-703A3134AEE4 + value: 06A5E617-FB01-3F34-9A4C-CA3894CE0438 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: FA2D8F89-D9C4-316F-9FDC-BFF1A791BD4E + value: 4880993D-A23B-3DCE-942A-4201CE7E5461 - target: arm64e-maccatalyst - value: FA2D8F89-D9C4-316F-9FDC-BFF1A791BD4E + value: 4880993D-A23B-3DCE-942A-4201CE7E5461 install-name: '/usr/lib/system/libremovefile.dylib' current-version: 60 parent-umbrella: @@ -1169,7 +1173,7 @@ parent-umbrella: arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ ___removefile_init_random, ___removefile_random_char, ___removefile_randomize_buffer, ___removefile_rename_unlink, ___removefile_sunlink, ___removefile_tree_walker, @@ -1182,19 +1186,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 7A040D61-D8FB-3F40-99B7-0C84BA2574DC + value: DAA735E5-A64F-3443-8B24-8C5A77A25EFD - target: x86_64-maccatalyst - value: 7A040D61-D8FB-3F40-99B7-0C84BA2574DC + value: DAA735E5-A64F-3443-8B24-8C5A77A25EFD - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 61963381-E322-3D0F-855D-CE1EA31FA4E1 + value: 6B2F4A2F-2C36-3D5D-87F0-9B6BBAE5560C - target: arm64e-maccatalyst - value: 61963381-E322-3D0F-855D-CE1EA31FA4E1 + value: 6B2F4A2F-2C36-3D5D-87F0-9B6BBAE5560C install-name: '/usr/lib/system/libsystem_asl.dylib' -current-version: 390 +current-version: 392.100.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1276,25 +1280,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 247F70CA-E83C-346B-8556-B3DACE78ED36 + value: CCC417A8-9265-3B0C-AF95-98B57ABE5E43 - target: x86_64-maccatalyst - value: 247F70CA-E83C-346B-8556-B3DACE78ED36 + value: CCC417A8-9265-3B0C-AF95-98B57ABE5E43 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 770FEB1F-FE27-3670-810F-A063D281CC8D + value: DF7F3CF2-FF71-3E86-AA3A-46465B8B8DEC - target: arm64e-maccatalyst - value: 770FEB1F-FE27-3670-810F-A063D281CC8D + value: DF7F3CF2-FF71-3E86-AA3A-46465B8B8DEC install-name: '/usr/lib/system/libsystem_blocks.dylib' -current-version: 79 +current-version: 79.1 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _Block_size, __Block_copy, __Block_extended_layout, __Block_has_signature, __Block_isDeallocating, __Block_layout, __Block_object_assign, @@ -1308,19 +1312,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: DE0BB5F4-D3EC-36EB-8B7F-58964E2AAC7C + value: 8E54ECA2-9BD8-3482-9589-B9574434D1AA - target: x86_64-maccatalyst - value: DE0BB5F4-D3EC-36EB-8B7F-58964E2AAC7C + value: 8E54ECA2-9BD8-3482-9589-B9574434D1AA - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 660D7866-E2A2-3651-A0A5-806E9217736B + value: FD566A15-42D8-314A-A99A-B59237DDF5BC - target: arm64e-maccatalyst - value: 660D7866-E2A2-3651-A0A5-806E9217736B + value: FD566A15-42D8-314A-A99A-B59237DDF5BC install-name: '/usr/lib/system/libsystem_c.dylib' -current-version: 1506.30.3 +current-version: 1507.100.9 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1440,13 +1444,13 @@ exports: _dbopen, _devname, _devname_r, _difftime, _digittoint, _digittoint_l, _dirfd, _dirname, _dirname_r, _div, _dprintf, _dprintf_l, _drand48, _duplocale, _dxprintf, _dxprintf_exec, _ecvt, _encrypt, - _endttyent, _endusershell, _endutxent, _endutxent_wtmp, _erand48, - _err, _err_set_exit, _err_set_exit_b, _err_set_file, _errc, - _errx, _execl, _execle, _execlp, _execv, _execvP, _execvp, - _exit, _f_prealloc, _fchmodx_np, _fclose, _fcvt, _fdopen, - '_fdopen$DARWIN_EXTSN', _fdopendir, _feof, _feof_unlocked, - _ferror, _ferror_unlocked, _fflagstostr, _fflush, _fgetc, - _fgetln, _fgetpos, _fgetrune, _fgets, _fgetwc, _fgetwc_l, + _endttyent, _endusershell, _endutxent, _endutxent_wtmp, _environ_lock_np, + _environ_unlock_np, _erand48, _err, _err_set_exit, _err_set_exit_b, + _err_set_file, _errc, _errx, _execl, _execle, _execlp, _execv, + _execvP, _execvp, _exit, _f_prealloc, _fchmodx_np, _fclose, + _fcvt, _fdopen, '_fdopen$DARWIN_EXTSN', _fdopendir, _feof, + _feof_unlocked, _ferror, _ferror_unlocked, _fflagstostr, _fflush, + _fgetc, _fgetln, _fgetpos, _fgetrune, _fgets, _fgetwc, _fgetwc_l, _fgetwln, _fgetwln_l, _fgetws, _fgetws_l, _fileno, _fileno_unlocked, _filesec_dup, _filesec_free, _filesec_get_property, _filesec_init, _filesec_query_property, _filesec_set_property, _filesec_unset_property, @@ -1615,25 +1619,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 238A47F2-BED4-36B9-8080-E88095B11F5A + value: BDBBFF38-0DB7-3B60-BB26-1E7E36715C85 - target: x86_64-maccatalyst - value: 238A47F2-BED4-36B9-8080-E88095B11F5A + value: BDBBFF38-0DB7-3B60-BB26-1E7E36715C85 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 1F580793-A1C3-30C6-A9BC-7789C14677AE + value: B7FB982C-29CC-383B-9C25-60D660BB1433 - target: arm64e-maccatalyst - value: 1F580793-A1C3-30C6-A9BC-7789C14677AE + value: B7FB982C-29CC-383B-9C25-60D660BB1433 install-name: '/usr/lib/system/libsystem_collections.dylib' -current-version: 1506.30.3 +current-version: 1507.100.9 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _os_map_128_clear, _os_map_128_count, _os_map_128_delete, _os_map_128_destroy, _os_map_128_find, _os_map_128_foreach, @@ -1658,19 +1662,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: C13509A3-AE4E-3232-A5CD-4C055C585565 + value: 254B479C-BCCB-3A80-A6D8-246FE621D182 - target: x86_64-maccatalyst - value: C13509A3-AE4E-3232-A5CD-4C055C585565 + value: 254B479C-BCCB-3A80-A6D8-246FE621D182 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 8370E8A5-EADF-3A2C-9D5B-CA148723A5CA + value: F241F139-76C4-38FC-A44C-5D695A58592D - target: arm64e-maccatalyst - value: 8370E8A5-EADF-3A2C-9D5B-CA148723A5CA + value: F241F139-76C4-38FC-A44C-5D695A58592D install-name: '/usr/lib/system/libsystem_configuration.dylib' -current-version: 1163.30.6 +current-version: 1163.100.19 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1698,17 +1702,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: EBCDED71-A48E-3FC6-A05D-81EA84A901AD + value: 03AC1106-F611-3CCA-98AE-8C5FA6ED5C94 - target: x86_64-maccatalyst - value: EBCDED71-A48E-3FC6-A05D-81EA84A901AD + value: 03AC1106-F611-3CCA-98AE-8C5FA6ED5C94 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 30C492F6-C9E6-3C1D-BE52-CA4F4FC824D6 + value: ECF472AD-D73F-3C98-B186-2AD4EE20F4D5 - target: arm64e-maccatalyst - value: 30C492F6-C9E6-3C1D-BE52-CA4F4FC824D6 + value: ECF472AD-D73F-3C98-B186-2AD4EE20F4D5 install-name: '/usr/lib/system/libsystem_containermanager.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1788,17 +1792,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 4B990266-91BF-3E2F-97C0-3B214B3052DC + value: 5E34B58A-2BEE-3AA4-AB65-C32D4619AC2B - target: x86_64-maccatalyst - value: 4B990266-91BF-3E2F-97C0-3B214B3052DC + value: 5E34B58A-2BEE-3AA4-AB65-C32D4619AC2B - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: F2A34B01-C264-3B7E-B3C9-1671E9E3C185 + value: 92325446-C184-3BDF-B839-CFC2A7C558EC - target: arm64e-maccatalyst - value: F2A34B01-C264-3B7E-B3C9-1671E9E3C185 + value: 92325446-C184-3BDF-B839-CFC2A7C558EC install-name: '/usr/lib/system/libsystem_coreservices.dylib' current-version: 133 parent-umbrella: @@ -1806,7 +1810,7 @@ parent-umbrella: arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _NSGetNextSearchPathEnumeration, _NSStartSearchPathEnumeration, _NSStartSearchPathEnumerationPrivate, ___user_local_dirname, @@ -1814,7 +1818,7 @@ exports: __dirhelper, __dirhelper_relative, __get_user_dir_suffix, __libcoreservices_fork_child, __set_user_dir_suffix, _sysdir_get_next_search_path_enumeration, _sysdir_start_search_path_enumeration, _sysdir_start_search_path_enumeration_private ] - - targets: [ x86_64-macos, arm64e-macos, arm64-macos ] + - targets: [ arm64e-macos, x86_64-macos, arm64-macos ] symbols: [ __idle_exit ] --- !tapi-tbd tbd-version: 4 @@ -1822,24 +1826,24 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 735E8A58-EA5A-3989-946E-D19037A7A9AD + value: A1C57F3C-0B85-367D-AFD8-CE4B01B638C6 - target: x86_64-maccatalyst - value: 735E8A58-EA5A-3989-946E-D19037A7A9AD + value: A1C57F3C-0B85-367D-AFD8-CE4B01B638C6 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 01C0D793-E5FB-3141-95D6-32A973F9FFF8 + value: D07777F4-2044-30E7-82FB-8F239F71A802 - target: arm64e-maccatalyst - value: 01C0D793-E5FB-3141-95D6-32A973F9FFF8 + value: D07777F4-2044-30E7-82FB-8F239F71A802 install-name: '/usr/lib/system/libsystem_darwin.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ ___libdarwin_init, ___os_temporary_resource_shortage, _claimfd_np, _close_drop_np, _close_drop_optional_np, _crfprintf_np, _dirstat_np, @@ -1873,25 +1877,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: C2A4351C-A3A5-3B23-AC6E-33E2EC933845 + value: 5E0FC1CB-9A90-3163-8BBF-19076AC6D14C - target: x86_64-maccatalyst - value: C2A4351C-A3A5-3B23-AC6E-33E2EC933845 + value: 5E0FC1CB-9A90-3163-8BBF-19076AC6D14C - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: AED9DAFC-7AB1-31CF-96A1-14C87B614DD3 + value: BCF907AB-64F2-3E2C-A203-9FCA6584C584 - target: arm64e-maccatalyst - value: AED9DAFC-7AB1-31CF-96A1-14C87B614DD3 + value: BCF907AB-64F2-3E2C-A203-9FCA6584C584 install-name: '/usr/lib/system/libsystem_dnssd.dylib' -current-version: 1556.30.12 +current-version: 1557.101.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _DNSServiceAddRecord, _DNSServiceBrowse, _DNSServiceConstructFullName, _DNSServiceCreateConnection, _DNSServiceCreateDelegateConnection, @@ -1916,25 +1920,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: C922FEBB-3F3D-3009-885D-386706502278 + value: 1D848276-387D-39BE-BDCC-6491A766B421 - target: x86_64-maccatalyst - value: C922FEBB-3F3D-3009-885D-386706502278 + value: 1D848276-387D-39BE-BDCC-6491A766B421 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: F0456F65-B4DF-3E14-91DC-C0C2A7954233 + value: 8BCCBE77-3AEB-3BDA-A6B6-4D1D0B7FFBCF - target: arm64e-maccatalyst - value: F0456F65-B4DF-3E14-91DC-C0C2A7954233 + value: 8BCCBE77-3AEB-3BDA-A6B6-4D1D0B7FFBCF install-name: '/usr/lib/system/libsystem_featureflags.dylib' -current-version: 54.30.2 +current-version: 56 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ __os_feature_enabled_impl, __os_feature_enabled_simple_impl ] --- !tapi-tbd @@ -1943,24 +1947,24 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: EC332A01-B383-3BBE-BD01-C732C1A9BF68 + value: 46CC22E7-C847-3A30-8B81-2E6CEF535451 - target: x86_64-maccatalyst - value: EC332A01-B383-3BBE-BD01-C732C1A9BF68 + value: 46CC22E7-C847-3A30-8B81-2E6CEF535451 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 5E36F087-5EF7-33B7-ACDA-CAE1C4A97621 + value: 2CE857CF-271D-3196-9087-0875C4D153BD - target: arm64e-maccatalyst - value: 5E36F087-5EF7-33B7-ACDA-CAE1C4A97621 + value: 2CE857CF-271D-3196-9087-0875C4D153BD install-name: '/usr/lib/system/libsystem_info.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _LI_get_thread_item, _LI_get_thread_list, _LI_ils_create, _LI_set_thread_item, _LI_set_thread_list, ___dn_skipname, @@ -2080,19 +2084,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: A047541D-D968-3125-A5B1-B5A183385249 + value: 26A59789-B846-3ED4-96DC-8DBEF3C0C8E7 - target: x86_64-maccatalyst - value: A047541D-D968-3125-A5B1-B5A183385249 + value: 26A59789-B846-3ED4-96DC-8DBEF3C0C8E7 - target: arm64-macos - value: 2C89227C-13E1-3A3F-8417-67B7C86B441B + value: 8678B4ED-EC14-3851-8DA2-AE9902BBD5FC - target: arm64-maccatalyst - value: 2C89227C-13E1-3A3F-8417-67B7C86B441B + value: 8678B4ED-EC14-3851-8DA2-AE9902BBD5FC - target: arm64e-macos - value: 17550B77-D255-389A-B779-906AF75314B6 + value: 1D7B3B8E-75A1-34EA-AA52-9F7C23155C55 - target: arm64e-maccatalyst - value: 17550B77-D255-389A-B779-906AF75314B6 + value: 1D7B3B8E-75A1-34EA-AA52-9F7C23155C55 install-name: '/usr/lib/system/libsystem_kernel.dylib' -current-version: 8019.30.61 +current-version: 8020.101.4 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2236,14 +2240,14 @@ exports: _fchdir, _fchflags, _fchmod, _fchmodat, _fchown, _fchownat, _fclonefileat, _fcntl, '_fcntl$NOCANCEL', _fdatasync, _ffsctl, _fgetattrlist, _fgetxattr, _fhopen, _fileport_makefd, _fileport_makeport, - _flistxattr, _flock, _fmount, _fpathconf, _fremovexattr, _fs_snapshot_create, - _fs_snapshot_delete, _fs_snapshot_list, _fs_snapshot_mount, - _fs_snapshot_rename, _fs_snapshot_revert, _fs_snapshot_root, - _fsctl, _fsetattrlist, _fsetxattr, _fsgetpath, _fsgetpath_ext, - _fstat, _fstat64, _fstatat, _fstatat64, _fstatfs, _fstatfs64, - _fsync, '_fsync$NOCANCEL', _ftruncate, _futimens, _futimes, - _getattrlist, _getattrlistat, _getattrlistbulk, _getaudit, - _getaudit_addr, _getauid, _getdirentries, _getdirentriesattr, + _flistxattr, _flock, _fmount, _fpathconf, _freadlink, _fremovexattr, + _fs_snapshot_create, _fs_snapshot_delete, _fs_snapshot_list, + _fs_snapshot_mount, _fs_snapshot_rename, _fs_snapshot_revert, + _fs_snapshot_root, _fsctl, _fsetattrlist, _fsetxattr, _fsgetpath, + _fsgetpath_ext, _fstat, _fstat64, _fstatat, _fstatat64, _fstatfs, + _fstatfs64, _fsync, '_fsync$NOCANCEL', _ftruncate, _futimens, + _futimes, _getattrlist, _getattrlistat, _getattrlistbulk, + _getaudit, _getaudit_addr, _getauid, _getdirentries, _getdirentriesattr, _getdtablesize, _getegid, _getentropy, _geteuid, _getfh, _getfsstat, _getfsstat64, _getgid, _getgroups, _gethostuuid, _getiopolicy_np, _getitimer, _getpeername, _getpgid, _getpgrp, _getpid, _getppid, @@ -2435,42 +2439,42 @@ exports: _posix_spawnattr_setpcontrol_np, _posix_spawnattr_setpgroup, _posix_spawnattr_setprocesstype_np, _posix_spawnattr_setsigdefault, _posix_spawnattr_setsigmask, _posix_spawnattr_setspecialport_np, - _posix_spawnattr_setsuidcredport_np, _pread, '_pread$NOCANCEL', - _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, _proc_clear_delayidlesleep, - _proc_clear_dirty, _proc_clear_vmpressure, _proc_current_thread_schedinfo, - _proc_denap_assertion_begin_with_msg, _proc_denap_assertion_complete, - _proc_disable_apptype, _proc_disable_cpumon, _proc_disable_wakemon, - _proc_donate_importance_boost, _proc_enable_apptype, _proc_get_cpumon_params, - _proc_get_dirty, _proc_get_wakemon_params, _proc_importance_assertion_begin_with_msg, - _proc_importance_assertion_complete, _proc_kmsgbuf, _proc_libversion, - _proc_list_dynkqueueids, _proc_list_uptrs, _proc_listallpids, - _proc_listchildpids, _proc_listcoalitions, _proc_listpgrppids, - _proc_listpids, _proc_listpidspath, _proc_name, _proc_pid_rusage, - _proc_piddynkqueueinfo, _proc_pidfdinfo, _proc_pidfileportinfo, - _proc_pidinfo, _proc_pidoriginatorinfo, _proc_pidpath, _proc_pidpath_audittoken, - _proc_regionfilename, _proc_reset_footprint_interval, _proc_resume_cpumon, - _proc_rlimit_control, _proc_set_cpumon_defaults, _proc_set_cpumon_params, - _proc_set_cpumon_params_fatal, _proc_set_csm, _proc_set_delayidlesleep, - _proc_set_dirty, _proc_set_no_smt, _proc_set_owner_vmpressure, - _proc_set_wakemon_defaults, _proc_set_wakemon_params, _proc_setcpu_percentage, - _proc_setpcontrol, _proc_setthread_cpupercent, _proc_setthread_csm, - _proc_setthread_no_smt, _proc_suppress, _proc_terminate, _proc_trace_log, - _proc_track_dirty, _proc_udata_info, _proc_uuid_policy, _processor_assign, - _processor_control, _processor_exit, _processor_get_assignment, - _processor_info, _processor_set_create, _processor_set_default, - _processor_set_destroy, _processor_set_info, _processor_set_max_priority, - _processor_set_policy_control, _processor_set_policy_disable, - _processor_set_policy_enable, _processor_set_stack_usage, - _processor_set_statistics, _processor_set_tasks, _processor_set_tasks_with_flavor, - _processor_set_threads, _processor_start, _pselect, '_pselect$DARWIN_EXTSN', - '_pselect$DARWIN_EXTSN$NOCANCEL', '_pselect$NOCANCEL', _pthread_getugid_np, - _pthread_setugid_np, _ptrace, _pwrite, '_pwrite$NOCANCEL', - _pwritev, '_pwritev$NOCANCEL', _quota, _quotactl, _read, '_read$NOCANCEL', - _readlink, _readlinkat, _readv, '_readv$NOCANCEL', _reboot, - _reboot_np, _recvfrom, '_recvfrom$NOCANCEL', _recvmsg, '_recvmsg$NOCANCEL', - _recvmsg_x, _register_uexc_handler, _removexattr, _rename, - _rename_ext, _renameat, _renameatx_np, _renamex_np, _revoke, - _rmdir, _searchfs, _select, '_select$DARWIN_EXTSN', '_select$DARWIN_EXTSN$NOCANCEL', + _pread, '_pread$NOCANCEL', _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, + _proc_clear_delayidlesleep, _proc_clear_dirty, _proc_clear_vmpressure, + _proc_current_thread_schedinfo, _proc_denap_assertion_begin_with_msg, + _proc_denap_assertion_complete, _proc_disable_apptype, _proc_disable_cpumon, + _proc_disable_wakemon, _proc_donate_importance_boost, _proc_enable_apptype, + _proc_get_cpumon_params, _proc_get_dirty, _proc_get_wakemon_params, + _proc_importance_assertion_begin_with_msg, _proc_importance_assertion_complete, + _proc_kmsgbuf, _proc_libversion, _proc_list_dynkqueueids, + _proc_list_uptrs, _proc_listallpids, _proc_listchildpids, + _proc_listcoalitions, _proc_listpgrppids, _proc_listpids, + _proc_listpidspath, _proc_name, _proc_pid_rusage, _proc_piddynkqueueinfo, + _proc_pidfdinfo, _proc_pidfileportinfo, _proc_pidinfo, _proc_pidoriginatorinfo, + _proc_pidpath, _proc_pidpath_audittoken, _proc_regionfilename, + _proc_reset_footprint_interval, _proc_resume_cpumon, _proc_rlimit_control, + _proc_set_cpumon_defaults, _proc_set_cpumon_params, _proc_set_cpumon_params_fatal, + _proc_set_csm, _proc_set_delayidlesleep, _proc_set_dirty, + _proc_set_no_smt, _proc_set_owner_vmpressure, _proc_set_wakemon_defaults, + _proc_set_wakemon_params, _proc_setcpu_percentage, _proc_setpcontrol, + _proc_setthread_cpupercent, _proc_setthread_csm, _proc_setthread_no_smt, + _proc_suppress, _proc_terminate, _proc_trace_log, _proc_track_dirty, + _proc_udata_info, _proc_uuid_policy, _processor_assign, _processor_control, + _processor_exit, _processor_get_assignment, _processor_info, + _processor_set_create, _processor_set_default, _processor_set_destroy, + _processor_set_info, _processor_set_max_priority, _processor_set_policy_control, + _processor_set_policy_disable, _processor_set_policy_enable, + _processor_set_stack_usage, _processor_set_statistics, _processor_set_tasks, + _processor_set_tasks_with_flavor, _processor_set_threads, + _processor_start, _pselect, '_pselect$DARWIN_EXTSN', '_pselect$DARWIN_EXTSN$NOCANCEL', + '_pselect$NOCANCEL', _pthread_getugid_np, _pthread_setugid_np, + _ptrace, _pwrite, '_pwrite$NOCANCEL', _pwritev, '_pwritev$NOCANCEL', + _quota, _quotactl, _read, '_read$NOCANCEL', _readlink, _readlinkat, + _readv, '_readv$NOCANCEL', _reboot, _reboot_np, _recvfrom, + '_recvfrom$NOCANCEL', _recvmsg, '_recvmsg$NOCANCEL', _recvmsg_x, + _register_uexc_handler, _removexattr, _rename, _rename_ext, + _renameat, _renameatx_np, _renamex_np, _revoke, _rmdir, _searchfs, + _select, '_select$DARWIN_EXTSN', '_select$DARWIN_EXTSN$NOCANCEL', '_select$NOCANCEL', _sem_close, _sem_destroy, _sem_getvalue, _sem_init, _sem_open, _sem_post, _sem_trywait, _sem_unlink, _sem_wait, '_sem_wait$NOCANCEL', _semaphore_create, _semaphore_destroy, @@ -2499,11 +2503,10 @@ exports: _sync, _syscall, _syscall_thread_switch, _system_get_sfi_window, _system_override, _system_set_sfi_window, _system_version_compat_mode, _task_assign, _task_assign_default, _task_create, _task_create_identity_token, - _task_create_suid_cred, _task_dyld_process_info_notify_deregister, - _task_dyld_process_info_notify_get, _task_dyld_process_info_notify_register, - _task_for_pid, _task_generate_corpse, _task_get_assignment, - _task_get_dyld_image_infos, _task_get_emulation_vector, _task_get_exc_guard_behavior, - _task_get_exception_ports, _task_get_exception_ports_info, + _task_dyld_process_info_notify_deregister, _task_dyld_process_info_notify_get, + _task_dyld_process_info_notify_register, _task_for_pid, _task_generate_corpse, + _task_get_assignment, _task_get_dyld_image_infos, _task_get_emulation_vector, + _task_get_exc_guard_behavior, _task_get_exception_ports, _task_get_exception_ports_info, _task_get_mach_voucher, _task_get_special_port, _task_get_state, _task_identity_token_get_task_port, _task_info, _task_inspect, _task_inspect_for_pid, _task_map_corpse_info, _task_map_corpse_info_64, @@ -2518,10 +2521,10 @@ exports: _task_set_phys_footprint_limit, _task_set_policy, _task_set_port_space, _task_set_ras_pc, _task_set_special_port, _task_set_state, _task_suspend, _task_suspend2, _task_swap_exception_ports, - _task_swap_mach_voucher, _task_terminate, _task_test_sync_upcall, - _task_threads, _task_unregister_dyld_image_infos, _task_zone_info, - _terminate_with_payload, _terminate_with_reason, _thread_abort, - _thread_abort_safely, _thread_assign, _thread_assign_default, + _task_swap_mach_voucher, _task_terminate, _task_test_async_upcall_propagation, + _task_test_sync_upcall, _task_threads, _task_unregister_dyld_image_infos, + _task_zone_info, _terminate_with_payload, _terminate_with_reason, + _thread_abort, _thread_abort_safely, _thread_assign, _thread_assign_default, _thread_convert_thread_state, _thread_create, _thread_create_running, _thread_depress_abort, _thread_destruct_special_reply_port, _thread_get_assignment, _thread_get_exception_ports, _thread_get_exception_ports_info, @@ -2565,23 +2568,23 @@ targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-macc arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 661AE5A6-34E0-3786-BAAA-0EA7C1B5436E + value: ED42C002-0A3D-3CFC-A5B4-007E9F8450FD - target: x86_64-maccatalyst - value: 661AE5A6-34E0-3786-BAAA-0EA7C1B5436E + value: ED42C002-0A3D-3CFC-A5B4-007E9F8450FD - target: x86_64h-macos - value: 4CE470DB-BC4F-3CC6-863B-DF899045C30C + value: 5063016F-C5E4-3455-A057-CB3C3EEED7E8 - target: x86_64h-maccatalyst - value: 4CE470DB-BC4F-3CC6-863B-DF899045C30C + value: 5063016F-C5E4-3455-A057-CB3C3EEED7E8 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 6AB180A4-1D1E-3FA1-88B7-A7866EFACFC8 + value: E02AEB06-0AB6-3743-BF8C-02CEFA571365 - target: arm64e-maccatalyst - value: 6AB180A4-1D1E-3FA1-88B7-A7866EFACFC8 + value: E02AEB06-0AB6-3743-BF8C-02CEFA571365 install-name: '/usr/lib/system/libsystem_m.dylib' -current-version: 3204 +current-version: 3204.80.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2710,7 +2713,7 @@ exports: '_tanhl$fenv_access_off', '_tanl$fenv_access_off', '_tgamma$fenv_access_off', '_tgammaf$fenv_access_off', '_tgammal$fenv_access_off', '_trunc$fenv_access_off', '_truncf$fenv_access_off', '_truncl$fenv_access_off' ] - - targets: [ x86_64-macos, arm64e-macos, x86_64h-macos, x86_64-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64h-macos, x86_64-maccatalyst, x86_64h-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ __FE_DFL_ENV, ___Libm_version, ___cos_d2, ___cos_f4, ___cospi, ___cospif, ___exp10, ___exp10f, ___fegetfltrounds, ___fpclassifyd, @@ -2795,25 +2798,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: BA9DF725-FC7D-3856-90F7-0100C841DBFE + value: CD1AD5BA-470D-33FF-A864-5FC3A18AB7C3 - target: x86_64-maccatalyst - value: BA9DF725-FC7D-3856-90F7-0100C841DBFE + value: CD1AD5BA-470D-33FF-A864-5FC3A18AB7C3 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 7C9F7726-62C1-3B03-8130-03E8A2A68DDF + value: 3A021C33-DD59-37F7-9A86-5CEED68FF9BA - target: arm64e-maccatalyst - value: 7C9F7726-62C1-3B03-8130-03E8A2A68DDF + value: 3A021C33-DD59-37F7-9A86-5CEED68FF9BA install-name: '/usr/lib/system/libsystem_malloc.dylib' -current-version: 372.30.4 +current-version: 374.100.5 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ ___mach_stack_logging_copy_uniquing_table, ___mach_stack_logging_enumerate_records, ___mach_stack_logging_frames_for_uniqued_stack, ___mach_stack_logging_get_frames, @@ -2858,24 +2861,24 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: ACE11FA2-1955-3276-9343-D49A2B2059C5 + value: 9394E64A-D1D5-362C-98DB-760C7C15B9BE - target: x86_64-maccatalyst - value: ACE11FA2-1955-3276-9343-D49A2B2059C5 + value: 9394E64A-D1D5-362C-98DB-760C7C15B9BE - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 2F331637-80F6-3208-816F-618DA9081899 + value: 8D842641-0F27-34B1-AEFC-C95B178E5433 - target: arm64e-maccatalyst - value: 2F331637-80F6-3208-816F-618DA9081899 + value: 8D842641-0F27-34B1-AEFC-C95B178E5433 install-name: '/usr/lib/system/libsystem_networkextension.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _NEHelperCacheAddRedirectedAddress, _NEHelperCacheClearRedirectedAddresses, _NEHelperCacheClearUUIDs, _NEHelperCacheCopyAppUUIDMapping, @@ -2883,18 +2886,19 @@ exports: _NEHelperCacheCopySigningIdentifierMapping, _NEHelperCacheSetDomainDictionaries, _NEHelperCacheSetRoutes, _NEHelperCopyAggregatePathRules, _NEHelperCopyAppInfo, _NEHelperCopyCurrentNetworkAsync, _NEHelperCopyCurrentNetworkInfo, - _NEHelperCopyPerAppDomains, _NEHelperCopyPreferredBundleID, - _NEHelperCopyResponse, _NEHelperGetIKESocket, _NEHelperGetIKESocketWithResult, - _NEHelperGetKernelControlSocket, _NEHelperGetKernelControlSocketExtended, - _NEHelperGetNECPSessionFD, _NEHelperGetPFKeySocket, _NEHelperHandleConfigurationsChangedBySC, + _NEHelperCopyPerAppDomains, _NEHelperCopyResponse, _NEHelperGetIKESocket, + _NEHelperGetIKESocketWithResult, _NEHelperGetKernelControlSocket, + _NEHelperGetKernelControlSocketExtended, _NEHelperGetNECPSessionFD, + _NEHelperGetPFKeySocket, _NEHelperHandleConfigurationsChangedBySC, _NEHelperInit, _NEHelperInterfaceRemoveAddress, _NEHelperInterfaceSetAddress, - _NEHelperInterfaceSetMTU, _NEHelperInterfaceSetOption, _NEHelperSendRequest, - _NEHelperSettingsSetArray, _NEHelperSettingsSetBool, _NEHelperSettingsSetNumber, - _NEHelperVPNConfigurationExists, _NEHelperVPNSetEnabled, _g_ne_read_uuid_cache, - _g_ne_uuid_cache_hit, _ne_copy_cached_bundle_identifier_for_uuid, - _ne_copy_cached_preferred_bundle_for_bundle_identifier, _ne_copy_cached_uuids_for_bundle_identifier, - _ne_copy_signature_info_for_pid, _ne_copy_signing_identifier_for_pid, - _ne_copy_uuid_cache, _ne_force_reset_uuid_cache, _ne_get_configuration_generation, + _NEHelperInterfaceSetAddressWithLifetime, _NEHelperInterfaceSetMTU, + _NEHelperInterfaceSetOption, _NEHelperSendRequest, _NEHelperSettingsSetArray, + _NEHelperSettingsSetBool, _NEHelperSettingsSetNumber, _NEHelperVPNConfigurationExists, + _NEHelperVPNSetEnabled, _g_ne_read_uuid_cache, _g_ne_uuid_cache_hit, + _ne_copy_cached_bundle_identifier_for_uuid, _ne_copy_cached_preferred_bundle_for_bundle_identifier, + _ne_copy_cached_uuids_for_bundle_identifier, _ne_copy_signature_info_for_pid, + _ne_copy_signing_identifier_for_pid, _ne_copy_uuid_cache, + _ne_force_reset_uuid_cache, _ne_get_configuration_generation, _ne_is_sockaddr_valid, _ne_log_large_obj, _ne_log_obj, _ne_print_backtrace, _ne_privacy_dns_netagent_id, _ne_privacy_proxy_netagent_id, _ne_session_add_necp_drop_dest_from_dest_list, _ne_session_add_necp_drop_dest_from_path, @@ -2931,10 +2935,11 @@ exports: _ne_session_start_with_options, _ne_session_status_to_string, _ne_session_stop, _ne_session_stop_all_with_plugin_type, _ne_session_stop_reason_to_string, _ne_session_type_to_string, _ne_session_use_as_system_vpn, - _ne_session_vpn_include_all_networks_configs_present, _ne_socket_set_attribution, - _ne_socket_set_domains, _ne_socket_set_is_app_initiated, _ne_socket_set_website_attribution, - _ne_tracker_build_cache, _ne_tracker_build_trie, _ne_tracker_check_info_changed, - _ne_tracker_clear_cache, _ne_tracker_context_get_domain, _ne_tracker_context_get_domain_owner, + _ne_session_vod_evaluate_connection_present, _ne_session_vpn_include_all_networks_configs_present, + _ne_socket_set_attribution, _ne_socket_set_domains, _ne_socket_set_is_app_initiated, + _ne_socket_set_website_attribution, _ne_tracker_build_cache, + _ne_tracker_build_trie, _ne_tracker_check_info_changed, _ne_tracker_clear_cache, + _ne_tracker_context_get_domain, _ne_tracker_context_get_domain_owner, _ne_tracker_context_is_from_app_list, _ne_tracker_context_is_from_web_list, _ne_tracker_get_ddg_dictionary, _ne_tracker_lookup_app_domains, _ne_tracker_set_test_domains, _ne_tracker_validate_domain, @@ -2949,17 +2954,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 6C34EA32-0C1D-35E9-BB3B-32D8185F3C4E + value: 90E8AC4C-D13B-3E0C-82CA-4179D34F4EC6 - target: x86_64-maccatalyst - value: 6C34EA32-0C1D-35E9-BB3B-32D8185F3C4E + value: 90E8AC4C-D13B-3E0C-82CA-4179D34F4EC6 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 3701D756-7023-30C0-9A36-852971092AA9 + value: 5FF2DA89-8A88-34BB-AA68-BA9C5D24E639 - target: arm64e-maccatalyst - value: 3701D756-7023-30C0-9A36-852971092AA9 + value: 5FF2DA89-8A88-34BB-AA68-BA9C5D24E639 install-name: '/usr/lib/system/libsystem_notify.dylib' current-version: 301 parent-umbrella: @@ -2967,7 +2972,7 @@ parent-umbrella: arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ __notify_fork_child, _notify_cancel, _notify_check, _notify_dump_status, _notify_get_event, _notify_get_state, _notify_is_valid_token, @@ -2982,19 +2987,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 4665F1E0-723C-3A58-81D6-220988B34F30 + value: A9552F53-A0CD-3E43-9930-80E582ED51FF - target: x86_64-maccatalyst - value: 4665F1E0-723C-3A58-81D6-220988B34F30 + value: A9552F53-A0CD-3E43-9930-80E582ED51FF - target: arm64-macos - value: DB2D2703-9015-37B8-A9CA-59F9672D5BC6 + value: A8C155A3-9295-340C-94A2-80B29BBA7A10 - target: arm64-maccatalyst - value: DB2D2703-9015-37B8-A9CA-59F9672D5BC6 + value: A8C155A3-9295-340C-94A2-80B29BBA7A10 - target: arm64e-macos - value: 8B28F7A3-6681-3D34-92AE-3688A74F50E6 + value: 84FA5DD0-806C-310E-B047-479924CD688C - target: arm64e-maccatalyst - value: 8B28F7A3-6681-3D34-92AE-3688A74F50E6 + value: 84FA5DD0-806C-310E-B047-479924CD688C install-name: '/usr/lib/system/libsystem_platform.dylib' -current-version: 272 +current-version: 273.100.5 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3074,17 +3079,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: D0578DF0-DD14-3D5D-AD59-248764AC666E + value: CC59553D-E561-3196-9A5C-4DBA8C385275 - target: x86_64-maccatalyst - value: D0578DF0-DD14-3D5D-AD59-248764AC666E + value: CC59553D-E561-3196-9A5C-4DBA8C385275 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 4234FAEC-7D18-30E7-AEAD-E9FB6922AFE9 + value: 21E3CB05-5B01-3BAA-8F17-84E8181778C0 - target: arm64e-maccatalyst - value: 4234FAEC-7D18-30E7-AEAD-E9FB6922AFE9 + value: 21E3CB05-5B01-3BAA-8F17-84E8181778C0 install-name: '/usr/lib/system/libsystem_product_info_filter.dylib' current-version: 10 parent-umbrella: @@ -3097,19 +3102,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 9D8930B0-D6B4-31B4-B7A5-DEBB4C606EF4 + value: 2F6C275D-7E14-3D31-A924-E1BB41D2415F - target: x86_64-maccatalyst - value: 9D8930B0-D6B4-31B4-B7A5-DEBB4C606EF4 + value: 2F6C275D-7E14-3D31-A924-E1BB41D2415F - target: arm64-macos - value: 0BFB3F12-FA30-3002-AF01-0B0D19DEC76B + value: 9507407A-B251-3158-BC81-8CABBEBE34DE - target: arm64-maccatalyst - value: 0BFB3F12-FA30-3002-AF01-0B0D19DEC76B + value: 9507407A-B251-3158-BC81-8CABBEBE34DE - target: arm64e-macos - value: AA39FF66-B3F0-3777-99BC-F4A4C5CBD566 + value: CEE8BC77-6923-34D9-89A3-6F8F7279605E - target: arm64e-maccatalyst - value: AA39FF66-B3F0-3777-99BC-F4A4C5CBD566 + value: CEE8BC77-6923-34D9-89A3-6F8F7279605E install-name: '/usr/lib/system/libsystem_pthread.dylib' -current-version: 485.30.3 +current-version: 486.100.11 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3117,8 +3122,8 @@ parent-umbrella: exports: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] - symbols: [ __pthread_is_threaded, _cthread_yield ] - - targets: [ arm64e-macos, x86_64-macos, arm64-macos, x86_64-maccatalyst, + symbols: [ __pthread_is_threaded, _cthread_yield, _pthread_prefer_alternate_amx_self ] + - targets: [ arm64-macos, arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64-maccatalyst, arm64e-maccatalyst ] symbols: [ ____chkstk_darwin, ___is_threaded, ___pthread_init, ___pthread_late_init, ___pthread_workqueue_setkill, ___unix_conforming, __pthread_atfork_child, @@ -3168,21 +3173,21 @@ exports: _pthread_getspecific, _pthread_install_workgroup_functions_np, _pthread_introspection_getspecific_np, _pthread_introspection_hook_install, _pthread_introspection_setspecific_np, _pthread_is_threaded_np, - _pthread_jit_write_protect_np, _pthread_jit_write_protect_supported_np, - _pthread_jit_write_with_callback_np, _pthread_join, '_pthread_join$NOCANCEL', - _pthread_key_create, _pthread_key_delete, _pthread_key_init_np, - _pthread_kill, _pthread_layout_offsets, _pthread_mach_thread_np, - _pthread_main_np, _pthread_main_thread_np, _pthread_mutex_destroy, - _pthread_mutex_getprioceiling, _pthread_mutex_init, _pthread_mutex_lock, - _pthread_mutex_setprioceiling, _pthread_mutex_trylock, _pthread_mutex_unlock, - _pthread_mutexattr_destroy, _pthread_mutexattr_getpolicy_np, - _pthread_mutexattr_getprioceiling, _pthread_mutexattr_getprotocol, - _pthread_mutexattr_getpshared, _pthread_mutexattr_gettype, - _pthread_mutexattr_init, _pthread_mutexattr_setpolicy_np, + _pthread_jit_write_freeze_callbacks_np, _pthread_jit_write_protect_np, + _pthread_jit_write_protect_supported_np, _pthread_jit_write_with_callback_np, + _pthread_join, '_pthread_join$NOCANCEL', _pthread_key_create, + _pthread_key_delete, _pthread_key_init_np, _pthread_kill, + _pthread_layout_offsets, _pthread_mach_thread_np, _pthread_main_np, + _pthread_main_thread_np, _pthread_mutex_destroy, _pthread_mutex_getprioceiling, + _pthread_mutex_init, _pthread_mutex_lock, _pthread_mutex_setprioceiling, + _pthread_mutex_trylock, _pthread_mutex_unlock, _pthread_mutexattr_destroy, + _pthread_mutexattr_getpolicy_np, _pthread_mutexattr_getprioceiling, + _pthread_mutexattr_getprotocol, _pthread_mutexattr_getpshared, + _pthread_mutexattr_gettype, _pthread_mutexattr_init, _pthread_mutexattr_setpolicy_np, _pthread_mutexattr_setprioceiling, _pthread_mutexattr_setprotocol, _pthread_mutexattr_setpshared, _pthread_mutexattr_settype, _pthread_once, _pthread_override_qos_class_end_np, _pthread_override_qos_class_start_np, - _pthread_prefer_alternate_amx_self, _pthread_qos_max_parallelism, + _pthread_prefer_alternate_cluster_self, _pthread_qos_max_parallelism, _pthread_rwlock_destroy, _pthread_rwlock_init, _pthread_rwlock_rdlock, _pthread_rwlock_tryrdlock, _pthread_rwlock_trywrlock, _pthread_rwlock_unlock, _pthread_rwlock_wrlock, _pthread_rwlockattr_destroy, _pthread_rwlockattr_getpshared, @@ -3204,25 +3209,25 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 878A6693-2E70-3697-A941-8745C00A47D7 + value: F7BD34BF-4F11-3C48-BD8B-BFC81C09CF2A - target: x86_64-maccatalyst - value: 878A6693-2E70-3697-A941-8745C00A47D7 + value: F7BD34BF-4F11-3C48-BD8B-BFC81C09CF2A - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 1214F568-24BF-379F-8A86-FF947EE5F18A + value: 9180A377-715B-3790-81DB-AB51A9F0C3C0 - target: arm64e-maccatalyst - value: 1214F568-24BF-379F-8A86-FF947EE5F18A + value: 9180A377-715B-3790-81DB-AB51A9F0C3C0 install-name: '/usr/lib/system/libsystem_sandbox.dylib' -current-version: 1656.30.23 +current-version: 1657.101.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ _APP_SANDBOX_IOKIT_CLIENT, _APP_SANDBOX_MACH, _APP_SANDBOX_READ, _APP_SANDBOX_READ_WRITE, _IOS_SANDBOX_APPLICATION_GROUP, _IOS_SANDBOX_CONTAINER, @@ -3251,12 +3256,12 @@ exports: _sandbox_check_message_filter_string, _sandbox_consume_extension, _sandbox_consume_fs_extension, _sandbox_consume_mach_extension, _sandbox_container_path_for_audit_token, _sandbox_container_path_for_pid, - _sandbox_enable_root_translation, _sandbox_extension_consume, - _sandbox_extension_issue_file, _sandbox_extension_issue_file_to_process, - _sandbox_extension_issue_file_to_process_by_pid, _sandbox_extension_issue_file_to_self, - _sandbox_extension_issue_generic, _sandbox_extension_issue_generic_to_process, - _sandbox_extension_issue_generic_to_process_by_pid, _sandbox_extension_issue_iokit_registry_entry_class, - _sandbox_extension_issue_iokit_registry_entry_class_to_process, + _sandbox_enable_root_translation, _sandbox_enable_state_flag, + _sandbox_extension_consume, _sandbox_extension_issue_file, + _sandbox_extension_issue_file_to_process, _sandbox_extension_issue_file_to_process_by_pid, + _sandbox_extension_issue_file_to_self, _sandbox_extension_issue_generic, + _sandbox_extension_issue_generic_to_process, _sandbox_extension_issue_generic_to_process_by_pid, + _sandbox_extension_issue_iokit_registry_entry_class, _sandbox_extension_issue_iokit_registry_entry_class_to_process, _sandbox_extension_issue_iokit_registry_entry_class_to_process_by_pid, _sandbox_extension_issue_iokit_user_client_class, _sandbox_extension_issue_mach, _sandbox_extension_issue_mach_to_process, _sandbox_extension_issue_mach_to_process_by_pid, @@ -3266,41 +3271,43 @@ exports: _sandbox_init_from_pid, _sandbox_init_with_extensions, _sandbox_init_with_parameters, _sandbox_issue_extension, _sandbox_issue_fs_extension, _sandbox_issue_fs_rw_extension, _sandbox_issue_mach_extension, _sandbox_message_filter_query, - _sandbox_message_filter_release, _sandbox_note, _sandbox_passthrough_access, - _sandbox_proc_getcontainer, _sandbox_proc_getprofilename, - _sandbox_query_approval_policy_for_path, _sandbox_query_user_intent_for_process_with_audit_token, - _sandbox_reference_release, _sandbox_reference_retain_by_audit_token, + _sandbox_message_filter_release, _sandbox_message_filter_retain, + _sandbox_note, _sandbox_passthrough_access, _sandbox_proc_getcontainer, + _sandbox_proc_getprofilename, _sandbox_query_approval_policy_for_path, + _sandbox_query_user_intent_for_process_with_audit_token, _sandbox_reference_release, + _sandbox_reference_retain_by_audit_token, _sandbox_register_app_bundle, _sandbox_release_fs_extension, _sandbox_requests_integrity_protection_for_preference_domain, _sandbox_set_container_path_for_application_group, _sandbox_set_container_path_for_application_group_with_persona, _sandbox_set_container_path_for_signing_id, _sandbox_set_container_path_for_signing_id_with_persona, _sandbox_spawnattrs_getcontainer, _sandbox_spawnattrs_getprofilename, _sandbox_spawnattrs_init, _sandbox_spawnattrs_setcontainer, - _sandbox_spawnattrs_setprofilename, _sandbox_suspend, _sandbox_unsuspend ] + _sandbox_spawnattrs_setprofilename, _sandbox_suspend, _sandbox_unregister_app_bundle, + _sandbox_unsuspend ] --- !tapi-tbd tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 2A532806-2750-369B-90AB-CD9BDB0ABFB2 + value: 6B34D783-AAA5-3401-8CAD-B0BC5F639834 - target: x86_64-maccatalyst - value: 2A532806-2750-369B-90AB-CD9BDB0ABFB2 + value: 6B34D783-AAA5-3401-8CAD-B0BC5F639834 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 49553CC1-66C3-32B1-91C6-4415DE230F58 + value: A61664A2-D010-3674-95D9-1D06571F9F5A - target: arm64e-maccatalyst - value: 49553CC1-66C3-32B1-91C6-4415DE230F58 + value: A61664A2-D010-3674-95D9-1D06571F9F5A install-name: '/usr/lib/system/libsystem_secinit.dylib' -current-version: 106.30.2 +current-version: 107.100.5 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ __libsecinit_initializer, _libsecinit_delete_all_data_container_content_for_current_user, _libsecinit_fileoperation_save, _libsecinit_fileoperation_set_attributes, @@ -3311,24 +3318,24 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: B08955D2-F6C0-3630-AF94-BE2A61E78516 + value: 8C17C62F-C82C-3A4C-A832-70EBEED5B0CA - target: x86_64-maccatalyst - value: B08955D2-F6C0-3630-AF94-BE2A61E78516 + value: 8C17C62F-C82C-3A4C-A832-70EBEED5B0CA - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 73885FA5-76B6-3AA3-8D91-60B2E0078F99 + value: 753D2289-1662-3922-8A94-FAC9DED81CD5 - target: arm64e-maccatalyst - value: 73885FA5-76B6-3AA3-8D91-60B2E0078F99 + value: 753D2289-1662-3922-8A94-FAC9DED81CD5 install-name: '/usr/lib/system/libsystem_symptoms.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - - targets: [ x86_64-macos, arm64e-macos, x86_64-maccatalyst, arm64e-maccatalyst, + - targets: [ arm64e-macos, x86_64-macos, x86_64-maccatalyst, arm64e-maccatalyst, arm64-macos, arm64-maccatalyst ] symbols: [ __symptoms_daemon_fallback_initial_disposition, __symptoms_daemon_fallback_subseq_disposition, __symptoms_is_daemon_fallback_blacklisted, _symptom_framework_init, @@ -3341,19 +3348,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 19A279BD-191D-3114-808B-09A74E978A6B + value: 5437B3FC-51DA-3F66-8C5C-31F7D5704C73 - target: x86_64-maccatalyst - value: 19A279BD-191D-3114-808B-09A74E978A6B + value: 5437B3FC-51DA-3F66-8C5C-31F7D5704C73 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 362E885B-20EA-395B-BB01-6E46B864294D + value: AAD0C6C8-F622-3FAC-AF4F-A2A021F9AE17 - target: arm64e-maccatalyst - value: 362E885B-20EA-395B-BB01-6E46B864294D + value: AAD0C6C8-F622-3FAC-AF4F-A2A021F9AE17 install-name: '/usr/lib/system/libsystem_trace.dylib' -current-version: 1372.30.3 +current-version: 1375.100.9 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3417,19 +3424,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 3723C625-FBC2-31A2-A4CB-081FD4B807A4 + value: BAF19DAC-B9ED-3544-97E9-E277BA113717 - target: x86_64-maccatalyst - value: 3723C625-FBC2-31A2-A4CB-081FD4B807A4 + value: BAF19DAC-B9ED-3544-97E9-E277BA113717 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: D0A538E3-7A75-395A-993C-A3EA7947F55A + value: 687985E7-0BD0-3898-9FCA-F8BCAAE282AE - target: arm64e-maccatalyst - value: D0A538E3-7A75-395A-993C-A3EA7947F55A + value: 687985E7-0BD0-3898-9FCA-F8BCAAE282AE install-name: '/usr/lib/system/libunwind.dylib' -current-version: 201 +current-version: 202.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3490,19 +3497,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: A9A403F2-4D7D-3760-B4A7-4A9721A2A9B9 + value: FBB81F7D-564A-3971-A28E-6AA174470B4C - target: x86_64-maccatalyst - value: A9A403F2-4D7D-3760-B4A7-4A9721A2A9B9 + value: FBB81F7D-564A-3971-A28E-6AA174470B4C - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: A77B4CE2-0855-3C19-B4A6-47B094CF0DDA + value: 4C6EB90B-BD32-3CAD-9F25-C9F234775EFB - target: arm64e-maccatalyst - value: A77B4CE2-0855-3C19-B4A6-47B094CF0DDA + value: 4C6EB90B-BD32-3CAD-9F25-C9F234775EFB install-name: '/usr/lib/system/libxpc.dylib' -current-version: 2235.30.5 +current-version: 2236.100.61 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3510,10 +3517,12 @@ parent-umbrella: exports: - targets: [ x86_64-maccatalyst, x86_64-macos, arm64e-maccatalyst, arm64e-macos, arm64-macos, arm64-maccatalyst ] - symbols: [ _XPC_ACTIVITY_ALLOW_BATTERY, _XPC_ACTIVITY_APP_REFRESH, _XPC_ACTIVITY_CHECK_IN, - _XPC_ACTIVITY_COMMUNICATES_WITH_PAIRED_DEVICE, _XPC_ACTIVITY_CPU_INTENSIVE, - _XPC_ACTIVITY_DELAY, _XPC_ACTIVITY_DESIRED_MOTION_STATE, _XPC_ACTIVITY_DISK_INTENSIVE, - _XPC_ACTIVITY_DO_IT_LATER, _XPC_ACTIVITY_DUET_ACTIVITY_SCHEDULER_DATA, + symbols: [ _CEAcquireManagedContext, _CEAcquireUnmanagedContext, _CEBuffer_cmp, + _CEConjureContextFromDER, _CEContextQuery, _CEGetErrorString, + _CEPrepareQuery, _CEReleaseManagedContext, _CEValidate, _XPC_ACTIVITY_ALLOW_BATTERY, + _XPC_ACTIVITY_APP_REFRESH, _XPC_ACTIVITY_CHECK_IN, _XPC_ACTIVITY_COMMUNICATES_WITH_PAIRED_DEVICE, + _XPC_ACTIVITY_CPU_INTENSIVE, _XPC_ACTIVITY_DELAY, _XPC_ACTIVITY_DESIRED_MOTION_STATE, + _XPC_ACTIVITY_DISK_INTENSIVE, _XPC_ACTIVITY_DO_IT_LATER, _XPC_ACTIVITY_DUET_ACTIVITY_SCHEDULER_DATA, _XPC_ACTIVITY_DUET_ATTRIBUTE_COST, _XPC_ACTIVITY_DUET_ATTRIBUTE_NAME, _XPC_ACTIVITY_DUET_ATTRIBUTE_VALUE, _XPC_ACTIVITY_DUET_RELATED_APPLICATIONS, _XPC_ACTIVITY_EXCLUSIVE, _XPC_ACTIVITY_EXPECTED_DURATION, @@ -3595,8 +3604,53 @@ exports: _bootstrap_look_up3, _bootstrap_look_up_per_user, _bootstrap_lookup_children, _bootstrap_parent, _bootstrap_register, _bootstrap_register2, _bootstrap_status, _bootstrap_strerror, _bootstrap_subset, - _bootstrap_unprivileged, _create_and_switch_to_per_session_launchd, - _launch_activate_socket, _launch_active_user_switch, _launch_add_external_service, + _bootstrap_unprivileged, _cc_clear, _ccder_blob_decode_bitstring, + _ccder_blob_decode_eckey, _ccder_blob_decode_len, _ccder_blob_decode_len_strict, + _ccder_blob_decode_oid, _ccder_blob_decode_range, _ccder_blob_decode_range_strict, + _ccder_blob_decode_seqii, _ccder_blob_decode_seqii_strict, + _ccder_blob_decode_sequence_tl, _ccder_blob_decode_sequence_tl_strict, + _ccder_blob_decode_tag, _ccder_blob_decode_tl, _ccder_blob_decode_tl_internal, + _ccder_blob_decode_tl_strict, _ccder_blob_decode_uint, _ccder_blob_decode_uint64, + _ccder_blob_decode_uint_n, _ccder_blob_decode_uint_strict, + _ccder_blob_encode_body, _ccder_blob_encode_body_tl, _ccder_blob_encode_eckey, + _ccder_blob_encode_implicit_integer, _ccder_blob_encode_implicit_octet_string, + _ccder_blob_encode_implicit_raw_octet_string, _ccder_blob_encode_implicit_uint64, + _ccder_blob_encode_integer, _ccder_blob_encode_len, _ccder_blob_encode_octet_string, + _ccder_blob_encode_oid, _ccder_blob_encode_raw_octet_string, + _ccder_blob_encode_tag, _ccder_blob_encode_tl, _ccder_blob_encode_uint64, + _ccder_blob_reserve, _ccder_blob_reserve_tl, _ccder_decode_bitstring, + _ccder_decode_constructed_tl, _ccder_decode_constructed_tl_strict, + _ccder_decode_eckey, _ccder_decode_len, _ccder_decode_len_strict, + _ccder_decode_oid, _ccder_decode_seqii, _ccder_decode_seqii_strict, + _ccder_decode_sequence_tl, _ccder_decode_sequence_tl_strict, + _ccder_decode_tag, _ccder_decode_tl, _ccder_decode_tl_strict, + _ccder_decode_uint, _ccder_decode_uint64, _ccder_decode_uint_n, + _ccder_decode_uint_strict, _ccder_encode_body, _ccder_encode_body_nocopy, + _ccder_encode_constructed_tl, _ccder_encode_eckey, _ccder_encode_eckey_size, + _ccder_encode_implicit_integer, _ccder_encode_implicit_octet_string, + _ccder_encode_implicit_raw_octet_string, _ccder_encode_implicit_uint64, + _ccder_encode_integer, _ccder_encode_len, _ccder_encode_octet_string, + _ccder_encode_oid, _ccder_encode_raw_octet_string, _ccder_encode_tag, + _ccder_encode_tl, _ccder_encode_uint64, _ccder_sizeof, _ccder_sizeof_eckey, + _ccder_sizeof_implicit_integer, _ccder_sizeof_implicit_uint64, + _ccder_sizeof_len, _ccder_sizeof_oid, _ccder_sizeof_tag, _ccder_sizeof_uint64, + _ccn_bitlen, _ccn_read_uint, _ccn_write_int, _ccn_write_int_size, + _ccn_write_uint, _ccn_write_uint_padded_ct, _ccn_write_uint_size, + _create_and_switch_to_per_session_launchd, _der_decode_boolean, + _der_decode_key_value, _der_decode_number, _der_decode_string, + _der_encode_number_body, _der_size_array, _der_size_dictionary, + _der_size_element, _der_size_number, _der_vm_CEType_from_context, + _der_vm_bool_from_context, _der_vm_buffer_from_context, _der_vm_context_create, + _der_vm_context_is_valid, _der_vm_execute, _der_vm_execute_match_bool, + _der_vm_execute_match_integer, _der_vm_execute_match_string, + _der_vm_execute_match_string_prefix, _der_vm_execute_nocopy, + _der_vm_execute_select_index, _der_vm_execute_select_key, + _der_vm_execute_select_longest_matching_key, _der_vm_execute_string_prefix_value_allowed, + _der_vm_execute_string_value_allowed, _der_vm_integer_from_context, + _der_vm_iterate, _der_vm_string_from_context, _kCEAPIMisuse, + _kCEAllocationFailed, _kCEInvalidArgument, _kCEMalformedEntitlements, + _kCENoError, _kCEQueryCannotBeSatisfied, _launch_activate_socket, + _launch_active_user_switch, _launch_add_external_service, _launch_bootout_user_service_4coresim, _launch_copy_busy_extension_instances, _launch_copy_endpoints_properties_for_pid, _launch_copy_extension_properties, _launch_copy_extension_properties_for_pid, _launch_copy_properties_for_pid_4assertiond, @@ -3635,10 +3689,10 @@ exports: _os_transaction_copy_description, _os_transaction_create, _os_transaction_get_description, _os_transaction_get_timestamp, _os_transaction_needs_more_time, _place_hold_on_real_loginwindow, - _reboot2, _reboot3, _vproc_release, _vproc_retain, _vproc_standby_begin, - _vproc_standby_end, _vproc_swap_complex, _vproc_swap_integer, - _vproc_swap_string, _vproc_transaction_begin, _vproc_transaction_end, - _vprocmgr_lookup_vproc, _xpc_activity_add_eligibility_changed_handler, + _reboot2, _reboot3, _recursivelyValidateEntitlements, _vproc_release, + _vproc_retain, _vproc_standby_begin, _vproc_standby_end, _vproc_swap_complex, + _vproc_swap_integer, _vproc_swap_string, _vproc_transaction_begin, + _vproc_transaction_end, _vprocmgr_lookup_vproc, _xpc_activity_add_eligibility_changed_handler, _xpc_activity_copy_criteria, _xpc_activity_copy_dispatch_queue, _xpc_activity_copy_identifier, _xpc_activity_debug, _xpc_activity_defer_until_network_change, _xpc_activity_defer_until_percentage, _xpc_activity_get_percentage, @@ -3698,6 +3752,7 @@ exports: _xpc_copy_entitlement_for_token, _xpc_copy_entitlements_data_for_token, _xpc_copy_entitlements_for_pid, _xpc_copy_entitlements_for_self, _xpc_copy_event, _xpc_copy_event_entitlements, _xpc_copy_short_description, + _xpc_create_from_ce_der, _xpc_create_from_ce_der_with_key, _xpc_create_from_plist, _xpc_create_from_plist_descriptor, _xpc_create_from_serialization, _xpc_create_from_serialization_with_ool, _xpc_create_reply_with_format, _xpc_create_reply_with_format_and_arguments, @@ -3778,4 +3833,6 @@ exports: _xpc_type_get_name, _xpc_uint64_create, _xpc_uint64_get_value, _xpc_uuid_create, _xpc_uuid_get_bytes ] objc-classes: [ OS_xpc_object ] + - targets: [ arm64e-maccatalyst, arm64e-macos, arm64-macos, arm64-maccatalyst ] + symbols: [ _cc_abort, _cc_disable_dit, _cc_try_abort, _cc_try_abort_if ] ... diff --git a/lib/libc/darwin/libSystem.13.tbd b/lib/libc/darwin/libSystem.13.tbd index b912905aaa..76e25874ae 100644 --- a/lib/libc/darwin/libSystem.13.tbd +++ b/lib/libc/darwin/libSystem.13.tbd @@ -4,17 +4,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 1C88C6B7-F992-3275-9EF4-4D2CB1CEFAC3 + value: 085E3D5D-7871-3E9E-A097-AAD940171411 - target: x86_64-maccatalyst - value: 1C88C6B7-F992-3275-9EF4-4D2CB1CEFAC3 + value: 085E3D5D-7871-3E9E-A097-AAD940171411 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 4396C12B-BA04-34F0-B859-7FC1914064A3 + value: B54723A8-A25C-3D6C-A51B-2B8BBA733DD3 - target: arm64e-maccatalyst - value: 4396C12B-BA04-34F0-B859-7FC1914064A3 + value: B54723A8-A25C-3D6C-A51B-2B8BBA733DD3 install-name: '/usr/lib/libSystem.B.dylib' current-version: 1319 reexported-libraries: @@ -59,17 +59,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 0D42BFC6-F62E-342B-BDB1-E75B48AF5081 + value: A7D96CB6-7562-3C14-8B54-ED5E484B54E2 - target: x86_64-maccatalyst - value: 0D42BFC6-F62E-342B-BDB1-E75B48AF5081 + value: A7D96CB6-7562-3C14-8B54-ED5E484B54E2 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 9953AE27-E8CB-32B2-98AF-9E871BCDD5D3 + value: 7A88909B-ED36-360D-ACE9-81107AF0FE14 - target: arm64e-maccatalyst - value: 9953AE27-E8CB-32B2-98AF-9E871BCDD5D3 + value: 7A88909B-ED36-360D-ACE9-81107AF0FE14 install-name: '/usr/lib/system/libcache.dylib' current-version: 90 parent-umbrella: @@ -97,19 +97,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: DD06A475-50C9-3264-BAD5-479DA5E8B327 + value: 6E120635-E858-30FE-95F6-64D90E33095D - target: x86_64-maccatalyst - value: DD06A475-50C9-3264-BAD5-479DA5E8B327 + value: 6E120635-E858-30FE-95F6-64D90E33095D - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 7510671C-686A-339D-8F50-B95BFA5D8F10 + value: 452A7C15-97FA-32A0-B514-744E117E2B39 - target: arm64e-maccatalyst - value: 7510671C-686A-339D-8F50-B95BFA5D8F10 + value: 452A7C15-97FA-32A0-B514-744E117E2B39 install-name: '/usr/lib/system/libcommonCrypto.dylib' -current-version: 60198.40.3 +current-version: 60198.60.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -191,11 +191,11 @@ tbd-version: 4 targets: [ x86_64-macos, arm64-macos, arm64e-macos ] uuids: - target: x86_64-macos - value: 9053D30C-239D-30B4-B36D-4E3490F72FE4 + value: E9412018-811C-36B7-9F58-6471398EE465 - target: arm64-macos - value: A7F13C10-9CEA-3A4E-86AB-F65E292E7804 + value: 954CFCC0-97A8-329B-B5AA-FF9046F3E94F - target: arm64e-macos - value: 824DFF0F-A337-32EB-B5DF-3FDD0BBFF9ED + value: 9F57BC0A-3F18-3F00-B772-40B6A8616E26 install-name: '/usr/lib/system/libcompiler_rt.dylib' current-version: 103.1 parent-umbrella: @@ -426,17 +426,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 0CD59665-DEA3-3995-84BC-485D4EA42680 + value: F92F30BA-35BE-3ED9-B562-FBEC1B7089B5 - target: x86_64-maccatalyst - value: 0CD59665-DEA3-3995-84BC-485D4EA42680 + value: F92F30BA-35BE-3ED9-B562-FBEC1B7089B5 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 79AD0FC1-4F88-3589-A602-45F2AA482B59 + value: 3689048E-9EC2-32D9-B833-B5EDE2839092 - target: arm64e-maccatalyst - value: 79AD0FC1-4F88-3589-A602-45F2AA482B59 + value: 3689048E-9EC2-32D9-B833-B5EDE2839092 install-name: '/usr/lib/system/libcopyfile.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -454,19 +454,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: D198406D-6F0D-3857-9CB3-9BA231DFEE00 + value: 1A8A8D34-268F-3D42-936A-8A0029817E22 - target: x86_64-maccatalyst - value: D198406D-6F0D-3857-9CB3-9BA231DFEE00 + value: 1A8A8D34-268F-3D42-936A-8A0029817E22 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 6A5FFEB0-E606-324E-B687-DA95C362CE05 + value: E32C0A9B-EDD0-376D-A504-A06C215E89FE - target: arm64e-maccatalyst - value: 6A5FFEB0-E606-324E-B687-DA95C362CE05 + value: E32C0A9B-EDD0-376D-A504-A06C215E89FE install-name: '/usr/lib/system/libcorecrypto.dylib' -current-version: 1386.40.5 +current-version: 1386.60.8 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -565,8 +565,9 @@ exports: _ccder_encode_tag, _ccder_encode_tl, _ccder_encode_uint64, _ccder_sizeof, _ccder_sizeof_eckey, _ccder_sizeof_implicit_integer, _ccder_sizeof_implicit_octet_string, _ccder_sizeof_implicit_raw_octet_string, - _ccder_sizeof_implicit_uint64, _ccder_sizeof_integer, _ccder_sizeof_len, - _ccder_sizeof_octet_string, _ccder_sizeof_oid, _ccder_sizeof_raw_octet_string, + _ccder_sizeof_implicit_raw_octet_string_overflow, _ccder_sizeof_implicit_uint64, + _ccder_sizeof_integer, _ccder_sizeof_len, _ccder_sizeof_octet_string, + _ccder_sizeof_oid, _ccder_sizeof_overflow, _ccder_sizeof_raw_octet_string, _ccder_sizeof_tag, _ccder_sizeof_uint64, _ccdes3_cbc_decrypt_mode, _ccdes3_cbc_encrypt_mode, _ccdes3_cfb8_decrypt_mode, _ccdes3_cfb8_encrypt_mode, _ccdes3_cfb_decrypt_mode, _ccdes3_cfb_encrypt_mode, _ccdes3_ctr_crypt_mode, @@ -767,17 +768,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 817339A1-D03E-3E54-9C47-ACACF69F6193 + value: 6282E528-6A67-334B-ACCF-1F8FD89369BD - target: x86_64-maccatalyst - value: 817339A1-D03E-3E54-9C47-ACACF69F6193 + value: 6282E528-6A67-334B-ACCF-1F8FD89369BD - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 40C9C98C-00D6-3E8E-9AD3-2ED6CF0D0CFE + value: 191028D2-0477-3EBC-9EEF-A85ACAFC7193 - target: arm64e-maccatalyst - value: 40C9C98C-00D6-3E8E-9AD3-2ED6CF0D0CFE + value: 191028D2-0477-3EBC-9EEF-A85ACAFC7193 install-name: '/usr/lib/system/libdispatch.dylib' current-version: 1412 parent-umbrella: @@ -943,17 +944,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 6C8B449A-78F4-3127-BC23-910719DE96AB + value: 6F97B8FD-BA81-3779-ADB2-5ECD91F42B75 - target: x86_64-maccatalyst - value: 6C8B449A-78F4-3127-BC23-910719DE96AB + value: 6F97B8FD-BA81-3779-ADB2-5ECD91F42B75 - target: arm64-macos - value: C52D0F3B-0BAE-376B-A851-943F95388DD7 + value: 427D321B-B30E-367F-8E2C-1DA6FD2D0962 - target: arm64-maccatalyst - value: C52D0F3B-0BAE-376B-A851-943F95388DD7 + value: 427D321B-B30E-367F-8E2C-1DA6FD2D0962 - target: arm64e-macos - value: 668F3379-151D-3ED4-859C-8F56E7941CDE + value: C1700833-CCA0-3BA5-8614-C149347F5503 - target: arm64e-maccatalyst - value: 668F3379-151D-3ED4-859C-8F56E7941CDE + value: C1700833-CCA0-3BA5-8614-C149347F5503 install-name: '/usr/lib/system/libdyld.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1041,17 +1042,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 564464C5-4B61-34E4-A937-2BDB5399DFCB + value: 4C623CBE-6FF4-3731-A647-6EEF7A6F51C7 - target: x86_64-maccatalyst - value: 564464C5-4B61-34E4-A937-2BDB5399DFCB + value: 4C623CBE-6FF4-3731-A647-6EEF7A6F51C7 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 50343076-2AC5-36B5-8B00-C7182678C6AC + value: B63E11DD-4648-3355-A51C-C1B650654C0F - target: arm64e-maccatalyst - value: 50343076-2AC5-36B5-8B00-C7182678C6AC + value: B63E11DD-4648-3355-A51C-C1B650654C0F install-name: '/usr/lib/system/libkeymgr.dylib' current-version: 31 parent-umbrella: @@ -1071,17 +1072,17 @@ tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ] uuids: - target: x86_64-macos - value: 4573BDD5-4817-3D26-B6A7-38AAE653FCBC + value: 632C478C-AAF6-3330-AA8E-0D0FCA4C6237 - target: x86_64-maccatalyst - value: 4573BDD5-4817-3D26-B6A7-38AAE653FCBC + value: 632C478C-AAF6-3330-AA8E-0D0FCA4C6237 - target: arm64-macos - value: B695C46E-649C-3047-AF7D-ED475E37DE56 + value: F71DA09E-609F-3C9A-95BF-22B22CFAD5A5 - target: arm64-maccatalyst - value: B695C46E-649C-3047-AF7D-ED475E37DE56 + value: F71DA09E-609F-3C9A-95BF-22B22CFAD5A5 - target: arm64e-macos - value: B4352C72-0618-3135-B375-BFF70DB8C3F2 + value: 471DA066-B65F-36B1-93B7-243C71F8838B - target: arm64e-maccatalyst - value: B4352C72-0618-3135-B375-BFF70DB8C3F2 + value: 471DA066-B65F-36B1-93B7-243C71F8838B install-name: '/usr/lib/system/libmacho.dylib' current-version: 1001.2 parent-umbrella: @@ -1131,19 +1132,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 928130DD-5A8D-3546-BA85-242E4051CEF2 + value: 9C3DCECF-ED9C-3F0F-9E9C-28DC842D4D65 - target: x86_64-maccatalyst - value: 928130DD-5A8D-3546-BA85-242E4051CEF2 + value: 9C3DCECF-ED9C-3F0F-9E9C-28DC842D4D65 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 2009EBC7-36D7-32AA-AD6A-25CE4128B3C0 + value: A052DB52-9ECA-39EC-8DD4-05A0856579B7 - target: arm64e-maccatalyst - value: 2009EBC7-36D7-32AA-AD6A-25CE4128B3C0 + value: A052DB52-9ECA-39EC-8DD4-05A0856579B7 install-name: '/usr/lib/system/libquarantine.dylib' -current-version: 146.40.2 +current-version: 146.60.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1189,17 +1190,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: E922FC3F-83F1-3C07-AD9A-13ABE2883681 + value: A7C519E4-A2A5-33E1-B9D6-52951921392F - target: x86_64-maccatalyst - value: E922FC3F-83F1-3C07-AD9A-13ABE2883681 + value: A7C519E4-A2A5-33E1-B9D6-52951921392F - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 51CF7D0E-014B-3E65-BDF3-A2DF337113BA + value: E785FBDF-82C9-3642-A38D-EDB07D118303 - target: arm64e-maccatalyst - value: 51CF7D0E-014B-3E65-BDF3-A2DF337113BA + value: E785FBDF-82C9-3642-A38D-EDB07D118303 install-name: '/usr/lib/system/libremovefile.dylib' current-version: 63 parent-umbrella: @@ -1220,17 +1221,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 136EA7B6-9D44-3363-8949-AF5D21C6D116 + value: D32DFE04-D5D4-3BD7-B9B5-9ED721B993EE - target: x86_64-maccatalyst - value: 136EA7B6-9D44-3363-8949-AF5D21C6D116 + value: D32DFE04-D5D4-3BD7-B9B5-9ED721B993EE - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 60ADB251-3204-34C0-B826-260AEF261E02 + value: 1E8F925A-501E-32BD-9BE3-2EE5FDEA8818 - target: arm64e-maccatalyst - value: 60ADB251-3204-34C0-B826-260AEF261E02 + value: 1E8F925A-501E-32BD-9BE3-2EE5FDEA8818 install-name: '/usr/lib/system/libsystem_asl.dylib' current-version: 395 parent-umbrella: @@ -1314,17 +1315,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 8AE2D1DF-B8E1-3564-810B-65C611BA237B + value: 942C1938-B1BC-3B74-912C-D7E7E2B6DC72 - target: x86_64-maccatalyst - value: 8AE2D1DF-B8E1-3564-810B-65C611BA237B + value: 942C1938-B1BC-3B74-912C-D7E7E2B6DC72 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 2E8EE0E2-160C-3418-AFC4-3FD86B4E7A6E + value: B126606C-8D07-3F9D-AD5E-9864CF11D901 - target: arm64e-maccatalyst - value: 2E8EE0E2-160C-3418-AFC4-3FD86B4E7A6E + value: B126606C-8D07-3F9D-AD5E-9864CF11D901 install-name: '/usr/lib/system/libsystem_blocks.dylib' current-version: 84 parent-umbrella: @@ -1346,17 +1347,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 5EFAF10B-2EC1-32ED-B077-80125E552C8D + value: 376F7CB7-6DD2-3E00-976F-77DD755BDB0D - target: x86_64-maccatalyst - value: 5EFAF10B-2EC1-32ED-B077-80125E552C8D + value: 376F7CB7-6DD2-3E00-976F-77DD755BDB0D - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: A3869999-0792-3E09-B3FB-5E87AE4639BE + value: 756CD0D2-3241-3A74-8C59-02632DCEE221 - target: arm64e-maccatalyst - value: A3869999-0792-3E09-B3FB-5E87AE4639BE + value: 756CD0D2-3241-3A74-8C59-02632DCEE221 install-name: '/usr/lib/system/libsystem_c.dylib' current-version: 1534.40.2 parent-umbrella: @@ -1653,17 +1654,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 308C9B23-5690-30DE-8008-0C50E7C725C5 + value: 2053883C-79F4-3AF8-A37C-DE204E208C60 - target: x86_64-maccatalyst - value: 308C9B23-5690-30DE-8008-0C50E7C725C5 + value: 2053883C-79F4-3AF8-A37C-DE204E208C60 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 89E9EF9E-ED46-307F-B973-6B5C3FB67388 + value: CB445464-28B4-353C-976E-59DA0E229FED - target: arm64e-maccatalyst - value: 89E9EF9E-ED46-307F-B973-6B5C3FB67388 + value: CB445464-28B4-353C-976E-59DA0E229FED install-name: '/usr/lib/system/libsystem_collections.dylib' current-version: 1534.40.2 parent-umbrella: @@ -1696,19 +1697,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 1CCF39AE-1799-327F-BFA5-5CBBC9511318 + value: E7F80C5C-E18C-3201-ACB6-9A4C46B6574B - target: x86_64-maccatalyst - value: 1CCF39AE-1799-327F-BFA5-5CBBC9511318 + value: E7F80C5C-E18C-3201-ACB6-9A4C46B6574B - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 3C081A70-EBBF-3746-A83F-FC93891BAA71 + value: 113A1DDB-1B61-3C33-9FD5-B39A2A29D779 - target: arm64e-maccatalyst - value: 3C081A70-EBBF-3746-A83F-FC93891BAA71 + value: 113A1DDB-1B61-3C33-9FD5-B39A2A29D779 install-name: '/usr/lib/system/libsystem_configuration.dylib' -current-version: 1241.40.2 +current-version: 1241.60.3 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1736,17 +1737,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: B94F5292-7CDC-368F-8D91-0CD73AE80924 + value: D44E0845-001C-3C46-B3A7-E4926DAEF6B3 - target: x86_64-maccatalyst - value: B94F5292-7CDC-368F-8D91-0CD73AE80924 + value: D44E0845-001C-3C46-B3A7-E4926DAEF6B3 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: D48AD081-4875-3F66-ABE1-9B646DD03B9C + value: 2694748C-A452-3438-BB47-161D7B220AE2 - target: arm64e-maccatalyst - value: D48AD081-4875-3F66-ABE1-9B646DD03B9C + value: 2694748C-A452-3438-BB47-161D7B220AE2 install-name: '/usr/lib/system/libsystem_containermanager.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1911,17 +1912,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 47275741-03DA-37A9-85B9-541F4DCB1163 + value: D86D13CC-2AF9-3A17-BCF3-0D16703F99A7 - target: x86_64-maccatalyst - value: 47275741-03DA-37A9-85B9-541F4DCB1163 + value: D86D13CC-2AF9-3A17-BCF3-0D16703F99A7 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 9F1BA0E0-8227-364B-8CF4-86D6870D6937 + value: 6E9DED8E-2A44-33E3-909F-74B4786482A2 - target: arm64e-maccatalyst - value: 9F1BA0E0-8227-364B-8CF4-86D6870D6937 + value: 6E9DED8E-2A44-33E3-909F-74B4786482A2 install-name: '/usr/lib/system/libsystem_coreservices.dylib' current-version: 129 parent-umbrella: @@ -1945,17 +1946,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 4B2F10CE-2D99-3B79-A05A-87DD03065ACB + value: E272E2C2-8511-3C94-8C39-F5319F2812BB - target: x86_64-maccatalyst - value: 4B2F10CE-2D99-3B79-A05A-87DD03065ACB + value: E272E2C2-8511-3C94-8C39-F5319F2812BB - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 859E9F1E-85E4-3469-9733-5846C98B155D + value: 74F6C923-5FF6-39D0-90DE-8FB4812EA263 - target: arm64e-maccatalyst - value: 859E9F1E-85E4-3469-9733-5846C98B155D + value: 74F6C923-5FF6-39D0-90DE-8FB4812EA263 install-name: '/usr/lib/system/libsystem_darwin.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1996,19 +1997,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: C352C6E4-8236-3B91-8ECA-4692191DD227 + value: 77610ACE-81D4-33E5-A343-5FDA27F53E10 - target: x86_64-maccatalyst - value: C352C6E4-8236-3B91-8ECA-4692191DD227 + value: 77610ACE-81D4-33E5-A343-5FDA27F53E10 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 1122C71F-CFA3-38EB-A329-C647E500C9B1 + value: F87EFC17-B673-3488-B503-C67E2FFDE6A0 - target: arm64e-maccatalyst - value: 1122C71F-CFA3-38EB-A329-C647E500C9B1 + value: F87EFC17-B673-3488-B503-C67E2FFDE6A0 install-name: '/usr/lib/system/libsystem_dnssd.dylib' -current-version: 1790.40.31 +current-version: 1790.60.25 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2046,17 +2047,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 2AF1974D-3A00-3461-9FDB-AF641DE4253E + value: 223BBDCF-6D59-3770-9E6A-38B762676030 - target: x86_64-maccatalyst - value: 2AF1974D-3A00-3461-9FDB-AF641DE4253E + value: 223BBDCF-6D59-3770-9E6A-38B762676030 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: C50ECE78-12CE-377F-93BA-B0D8B0D93CE7 + value: EE355E15-A47F-3BED-A955-1041497449AE - target: arm64e-maccatalyst - value: C50ECE78-12CE-377F-93BA-B0D8B0D93CE7 + value: EE355E15-A47F-3BED-A955-1041497449AE install-name: '/usr/lib/system/libsystem_featureflags.dylib' current-version: 71 parent-umbrella: @@ -2073,17 +2074,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 37924254-46CA-3531-9BE4-E9782F4DA626 + value: 7B76D94D-56F7-3B8A-B63D-ED567EFA12F6 - target: x86_64-maccatalyst - value: 37924254-46CA-3531-9BE4-E9782F4DA626 + value: 7B76D94D-56F7-3B8A-B63D-ED567EFA12F6 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 177AEA65-CA0C-38EB-8891-7726D30EC0AB + value: 67168754-ABAC-33C6-AFF7-FF53F1A8745C - target: arm64e-maccatalyst - value: 177AEA65-CA0C-38EB-8891-7726D30EC0AB + value: 67168754-ABAC-33C6-AFF7-FF53F1A8745C install-name: '/usr/lib/system/libsystem_info.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -2210,19 +2211,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 6D1DB971-27A7-3DBC-A7FF-1D25A88E5282 + value: 7C3DCC95-9F42-3C7C-8796-476FF67B9CF7 - target: x86_64-maccatalyst - value: 6D1DB971-27A7-3DBC-A7FF-1D25A88E5282 + value: 7C3DCC95-9F42-3C7C-8796-476FF67B9CF7 - target: arm64-macos - value: B529197C-5FB5-3ABB-915F-9EB576658F0F + value: EB0327EE-CB9C-37ED-AB6A-E9AF74E814F0 - target: arm64-maccatalyst - value: B529197C-5FB5-3ABB-915F-9EB576658F0F + value: EB0327EE-CB9C-37ED-AB6A-E9AF74E814F0 - target: arm64e-macos - value: 66D9DC04-E3C0-329C-B4CA-8C6E2CCA7FD3 + value: AEBF397E-E2EF-3A49-BE58-23D4558511F6 - target: arm64e-maccatalyst - value: 66D9DC04-E3C0-329C-B4CA-8C6E2CCA7FD3 + value: AEBF397E-E2EF-3A49-BE58-23D4558511F6 install-name: '/usr/lib/system/libsystem_kernel.dylib' -current-version: 8792.41.7 +current-version: 8792.61.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2531,7 +2532,7 @@ exports: _os_packet_set_expire_time, _os_packet_set_expiry_action, _os_packet_set_flow_uuid, _os_packet_set_group_end, _os_packet_set_group_start, _os_packet_set_headroom, _os_packet_set_inet_checksum, _os_packet_set_keep_alive, - _os_packet_set_link_broadcast, _os_packet_set_link_ethfcs, + _os_packet_set_l4s_flag, _os_packet_set_link_broadcast, _os_packet_set_link_ethfcs, _os_packet_set_link_header_length, _os_packet_set_link_multicast, _os_packet_set_packetid, _os_packet_set_protocol_segment_size, _os_packet_set_service_class, _os_packet_set_token, _os_packet_set_trace_id, @@ -2557,45 +2558,46 @@ exports: _posix_spawnattr_getprocesstype_np, _posix_spawnattr_getsigdefault, _posix_spawnattr_getsigmask, _posix_spawnattr_init, _posix_spawnattr_set_alt_rosetta_np, _posix_spawnattr_set_crash_behavior_deadline_np, _posix_spawnattr_set_crash_behavior_np, - _posix_spawnattr_set_csm_np, _posix_spawnattr_set_darwin_role_np, - _posix_spawnattr_set_filedesclimit_ext, _posix_spawnattr_set_gid_np, - _posix_spawnattr_set_groups_np, _posix_spawnattr_set_importancewatch_port_np, - _posix_spawnattr_set_jetsam_ttr_np, _posix_spawnattr_set_launch_type_np, - _posix_spawnattr_set_login_np, _posix_spawnattr_set_max_addr_np, - _posix_spawnattr_set_persona_gid_np, _posix_spawnattr_set_persona_groups_np, - _posix_spawnattr_set_persona_np, _posix_spawnattr_set_persona_uid_np, - _posix_spawnattr_set_platform_np, _posix_spawnattr_set_portlimits_ext, - _posix_spawnattr_set_ptrauth_task_port_np, _posix_spawnattr_set_qos_clamp_np, - _posix_spawnattr_set_registered_ports_np, _posix_spawnattr_set_subsystem_root_path_np, - _posix_spawnattr_set_threadlimit_ext, _posix_spawnattr_set_uid_np, - _posix_spawnattr_setarchpref_np, _posix_spawnattr_setauditsessionport_np, - _posix_spawnattr_setbinpref_np, _posix_spawnattr_setcoalition_np, - _posix_spawnattr_setcpumonitor, _posix_spawnattr_setcpumonitor_default, - _posix_spawnattr_setexceptionports_np, _posix_spawnattr_setflags, - _posix_spawnattr_setjetsam_ext, _posix_spawnattr_setmacpolicyinfo_np, - _posix_spawnattr_setnosmt_np, _posix_spawnattr_setpcontrol_np, - _posix_spawnattr_setpgroup, _posix_spawnattr_setprocesstype_np, - _posix_spawnattr_setsigdefault, _posix_spawnattr_setsigmask, - _posix_spawnattr_setspecialport_np, _pread, '_pread$NOCANCEL', - _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, _proc_clear_delayidlesleep, - _proc_clear_dirty, _proc_clear_vmpressure, _proc_current_thread_schedinfo, - _proc_denap_assertion_begin_with_msg, _proc_denap_assertion_complete, - _proc_disable_apptype, _proc_disable_cpumon, _proc_disable_wakemon, - _proc_donate_importance_boost, _proc_enable_apptype, _proc_get_cpumon_params, - _proc_get_dirty, _proc_get_wakemon_params, _proc_importance_assertion_begin_with_msg, - _proc_importance_assertion_complete, _proc_kmsgbuf, _proc_libversion, - _proc_list_dynkqueueids, _proc_list_uptrs, _proc_listallpids, - _proc_listchildpids, _proc_listcoalitions, _proc_listpgrppids, - _proc_listpids, _proc_listpidspath, _proc_name, _proc_pid_rusage, - _proc_piddynkqueueinfo, _proc_pidfdinfo, _proc_pidfileportinfo, - _proc_pidinfo, _proc_pidoriginatorinfo, _proc_pidpath, _proc_pidpath_audittoken, - _proc_regionfilename, _proc_reset_footprint_interval, _proc_resume_cpumon, - _proc_rlimit_control, _proc_set_cpumon_defaults, _proc_set_cpumon_params, - _proc_set_cpumon_params_fatal, _proc_set_csm, _proc_set_delayidlesleep, - _proc_set_dirty, _proc_set_no_smt, _proc_set_owner_vmpressure, - _proc_set_wakemon_defaults, _proc_set_wakemon_params, _proc_setcpu_percentage, - _proc_setpcontrol, _proc_setthread_cpupercent, _proc_setthread_csm, - _proc_setthread_no_smt, _proc_suppress, _proc_terminate, _proc_terminate_all_rsr, + _posix_spawnattr_set_crash_count_np, _posix_spawnattr_set_csm_np, + _posix_spawnattr_set_darwin_role_np, _posix_spawnattr_set_filedesclimit_ext, + _posix_spawnattr_set_gid_np, _posix_spawnattr_set_groups_np, + _posix_spawnattr_set_importancewatch_port_np, _posix_spawnattr_set_jetsam_ttr_np, + _posix_spawnattr_set_launch_type_np, _posix_spawnattr_set_login_np, + _posix_spawnattr_set_max_addr_np, _posix_spawnattr_set_persona_gid_np, + _posix_spawnattr_set_persona_groups_np, _posix_spawnattr_set_persona_np, + _posix_spawnattr_set_persona_uid_np, _posix_spawnattr_set_platform_np, + _posix_spawnattr_set_portlimits_ext, _posix_spawnattr_set_ptrauth_task_port_np, + _posix_spawnattr_set_qos_clamp_np, _posix_spawnattr_set_registered_ports_np, + _posix_spawnattr_set_subsystem_root_path_np, _posix_spawnattr_set_threadlimit_ext, + _posix_spawnattr_set_uid_np, _posix_spawnattr_setarchpref_np, + _posix_spawnattr_setauditsessionport_np, _posix_spawnattr_setbinpref_np, + _posix_spawnattr_setcoalition_np, _posix_spawnattr_setcpumonitor, + _posix_spawnattr_setcpumonitor_default, _posix_spawnattr_setexceptionports_np, + _posix_spawnattr_setflags, _posix_spawnattr_setjetsam_ext, + _posix_spawnattr_setmacpolicyinfo_np, _posix_spawnattr_setnosmt_np, + _posix_spawnattr_setpcontrol_np, _posix_spawnattr_setpgroup, + _posix_spawnattr_setprocesstype_np, _posix_spawnattr_setsigdefault, + _posix_spawnattr_setsigmask, _posix_spawnattr_setspecialport_np, + _pread, '_pread$NOCANCEL', _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, + _proc_clear_delayidlesleep, _proc_clear_dirty, _proc_clear_vmpressure, + _proc_current_thread_schedinfo, _proc_denap_assertion_begin_with_msg, + _proc_denap_assertion_complete, _proc_disable_apptype, _proc_disable_cpumon, + _proc_disable_wakemon, _proc_donate_importance_boost, _proc_enable_apptype, + _proc_get_cpumon_params, _proc_get_dirty, _proc_get_wakemon_params, + _proc_importance_assertion_begin_with_msg, _proc_importance_assertion_complete, + _proc_kmsgbuf, _proc_libversion, _proc_list_dynkqueueids, + _proc_list_uptrs, _proc_listallpids, _proc_listchildpids, + _proc_listcoalitions, _proc_listpgrppids, _proc_listpids, + _proc_listpidspath, _proc_name, _proc_pid_rusage, _proc_piddynkqueueinfo, + _proc_pidfdinfo, _proc_pidfileportinfo, _proc_pidinfo, _proc_pidoriginatorinfo, + _proc_pidpath, _proc_pidpath_audittoken, _proc_regionfilename, + _proc_reset_footprint_interval, _proc_resume_cpumon, _proc_rlimit_control, + _proc_set_cpumon_defaults, _proc_set_cpumon_params, _proc_set_cpumon_params_fatal, + _proc_set_csm, _proc_set_delayidlesleep, _proc_set_dirty, + _proc_set_no_smt, _proc_set_owner_vmpressure, _proc_set_wakemon_defaults, + _proc_set_wakemon_params, _proc_setcpu_percentage, _proc_setpcontrol, + _proc_setthread_cpupercent, _proc_setthread_csm, _proc_setthread_no_smt, + _proc_suppress, _proc_terminate, _proc_terminate_all_rsr, _proc_trace_log, _proc_track_dirty, _proc_udata_info, _proc_uuid_policy, _processor_assign, _processor_control, _processor_exit, _processor_get_assignment, _processor_info, _processor_set_create, _processor_set_default, @@ -2707,21 +2709,21 @@ targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-macc arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 5F7B0A6E-0315-3171-B806-4CCDB23007F4 + value: DC460796-C8A7-3507-8539-C890D9EDDC8C - target: x86_64-maccatalyst - value: 5F7B0A6E-0315-3171-B806-4CCDB23007F4 + value: DC460796-C8A7-3507-8539-C890D9EDDC8C - target: x86_64h-macos - value: 99FD67E1-20A8-36A7-836D-C8F156C98C5D + value: 73F0FC1C-FC2A-3B36-8796-7C2C2CBA7214 - target: x86_64h-maccatalyst - value: 99FD67E1-20A8-36A7-836D-C8F156C98C5D + value: 73F0FC1C-FC2A-3B36-8796-7C2C2CBA7214 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 748648A3-C1FF-3A75-8CE4-95B8334A6D58 + value: 6BEE17F3-04F2-3B1F-B8EB-C94379ABA9BD - target: arm64e-maccatalyst - value: 748648A3-C1FF-3A75-8CE4-95B8334A6D58 + value: 6BEE17F3-04F2-3B1F-B8EB-C94379ABA9BD install-name: '/usr/lib/system/libsystem_m.dylib' current-version: 3226.0.1 parent-umbrella: @@ -2938,19 +2940,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: D95D8C17-9F95-3076-A449-FBC4D1E9AD57 + value: F609F029-BCD0-3A54-B48A-99B3CE8378CE - target: x86_64-maccatalyst - value: D95D8C17-9F95-3076-A449-FBC4D1E9AD57 + value: F609F029-BCD0-3A54-B48A-99B3CE8378CE - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 030A8CB7-CD53-32E1-A0CC-6AC7D7DE93F1 + value: 04185997-16D2-30DA-8691-7C82612635A3 - target: arm64e-maccatalyst - value: 030A8CB7-CD53-32E1-A0CC-6AC7D7DE93F1 + value: 04185997-16D2-30DA-8691-7C82612635A3 install-name: '/usr/lib/system/libsystem_malloc.dylib' -current-version: 409.40.6 +current-version: 409.60.6 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3002,17 +3004,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 33130846-6A1D-33AA-BC75-06695EFCBF20 + value: 09114B12-EC3D-3943-A1BD-9909EE2F85B6 - target: x86_64-maccatalyst - value: 33130846-6A1D-33AA-BC75-06695EFCBF20 + value: 09114B12-EC3D-3943-A1BD-9909EE2F85B6 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 4972C105-1F4D-38BF-87C0-4724101B2CFA + value: 8737AB7F-91FA-3C06-B797-566A62D0751C - target: arm64e-maccatalyst - value: 4972C105-1F4D-38BF-87C0-4724101B2CFA + value: 8737AB7F-91FA-3C06-B797-566A62D0751C install-name: '/usr/lib/system/libsystem_networkextension.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -3095,17 +3097,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 1F9FBDD3-694A-3FF7-A232-F07DF4845ABE + value: 0463374D-9E62-3E58-A668-C9EFF9DB217C - target: x86_64-maccatalyst - value: 1F9FBDD3-694A-3FF7-A232-F07DF4845ABE + value: 0463374D-9E62-3E58-A668-C9EFF9DB217C - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: B2C5AAD6-13E5-3E2E-8DFC-601BAED4AA96 + value: 62FA1CCF-D4BB-3606-BDC9-C2F247A12CE8 - target: arm64e-maccatalyst - value: B2C5AAD6-13E5-3E2E-8DFC-601BAED4AA96 + value: 62FA1CCF-D4BB-3606-BDC9-C2F247A12CE8 install-name: '/usr/lib/system/libsystem_notify.dylib' current-version: 306 parent-umbrella: @@ -3128,17 +3130,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: F07558DB-8B15-3D96-93F9-3A61BBD52F25 + value: F314B62B-98F4-3A7C-8296-8739F8B6855A - target: x86_64-maccatalyst - value: F07558DB-8B15-3D96-93F9-3A61BBD52F25 + value: F314B62B-98F4-3A7C-8296-8739F8B6855A - target: arm64-macos - value: 372B6A5F-EE6F-3F9C-84D1-E8027DB6FA17 + value: ABF0BAEB-706B-3AC1-B6AD-B5CF380B8963 - target: arm64-maccatalyst - value: 372B6A5F-EE6F-3F9C-84D1-E8027DB6FA17 + value: ABF0BAEB-706B-3AC1-B6AD-B5CF380B8963 - target: arm64e-macos - value: 78189670-2F47-332C-9A59-A210157AA97B + value: B215AE90-4ED2-3FCD-8CCC-6C0D93CC4F41 - target: arm64e-maccatalyst - value: 78189670-2F47-332C-9A59-A210157AA97B + value: B215AE90-4ED2-3FCD-8CCC-6C0D93CC4F41 install-name: '/usr/lib/system/libsystem_platform.dylib' current-version: 288 parent-umbrella: @@ -3220,17 +3222,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 13B5E252-77D1-31E1-888D-1C5F4426EA87 + value: 5920E36F-53EC-33F0-B675-8AE48B58418C - target: x86_64-maccatalyst - value: 13B5E252-77D1-31E1-888D-1C5F4426EA87 + value: 5920E36F-53EC-33F0-B675-8AE48B58418C - target: arm64-macos - value: 030D2641-514F-373F-9688-582D9D3B369A + value: 51C613E3-4ABF-359C-B275-2608BB1BE0B6 - target: arm64-maccatalyst - value: 030D2641-514F-373F-9688-582D9D3B369A + value: 51C613E3-4ABF-359C-B275-2608BB1BE0B6 - target: arm64e-macos - value: 886CACA0-5762-3640-8DB2-3FA3B911C062 + value: 132084C6-C347-3489-9AC2-FCAAD21CDB73 - target: arm64e-maccatalyst - value: 886CACA0-5762-3640-8DB2-3FA3B911C062 + value: 132084C6-C347-3489-9AC2-FCAAD21CDB73 install-name: '/usr/lib/system/libsystem_pthread.dylib' current-version: 514 parent-umbrella: @@ -3328,19 +3330,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: A064D0A7-139F-33E5-959C-7067CF94DC2E + value: D199B283-8F09-3F2F-A17E-274BFF7733BE - target: x86_64-maccatalyst - value: A064D0A7-139F-33E5-959C-7067CF94DC2E + value: D199B283-8F09-3F2F-A17E-274BFF7733BE - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 3ADBD543-3E57-332F-972C-A958D9E4FBF8 + value: 3680811A-78F7-361A-ABBE-8E783165AC81 - target: arm64e-maccatalyst - value: 3ADBD543-3E57-332F-972C-A958D9E4FBF8 + value: 3680811A-78F7-361A-ABBE-8E783165AC81 install-name: '/usr/lib/system/libsystem_sandbox.dylib' -current-version: 1845.41.2 +current-version: 1845.60.12 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3415,17 +3417,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 15425DC5-5AEF-3711-A6B1-E3979FBEC662 + value: F24B1FA9-5692-35BA-9A9C-E071B7BFA5D7 - target: x86_64-maccatalyst - value: 15425DC5-5AEF-3711-A6B1-E3979FBEC662 + value: F24B1FA9-5692-35BA-9A9C-E071B7BFA5D7 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: B8D75446-A5A3-3D0C-9C89-B65092333CD2 + value: 82513DC5-565F-3A4E-9431-4511FB0C22FA - target: arm64e-maccatalyst - value: B8D75446-A5A3-3D0C-9C89-B65092333CD2 + value: 82513DC5-565F-3A4E-9431-4511FB0C22FA install-name: '/usr/lib/system/libsystem_secinit.dylib' current-version: 119.40.2 parent-umbrella: @@ -3444,17 +3446,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: CA62E5A0-80F0-3798-B8B6-71088A61F03C + value: A5915FB2-F0C9-3BF0-ADC6-BEB571C73E57 - target: x86_64-maccatalyst - value: CA62E5A0-80F0-3798-B8B6-71088A61F03C + value: A5915FB2-F0C9-3BF0-ADC6-BEB571C73E57 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: DE393954-A39B-305C-BF0D-CF7563473762 + value: B31CD553-083B-39C6-BCB9-B0413ECAF562 - target: arm64e-maccatalyst - value: DE393954-A39B-305C-BF0D-CF7563473762 + value: B31CD553-083B-39C6-BCB9-B0413ECAF562 install-name: '/usr/lib/system/libsystem_symptoms.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -3474,19 +3476,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: EBFC896A-380B-39AB-949F-06BEADFCDBF8 + value: C5359E6E-7B63-3E51-A664-3E3581E15F52 - target: x86_64-maccatalyst - value: EBFC896A-380B-39AB-949F-06BEADFCDBF8 + value: C5359E6E-7B63-3E51-A664-3E3581E15F52 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 73557AF9-086C-3CB4-9E95-CA1D774CAA41 + value: 616F473A-EB21-377D-B3B4-F1581F127F0D - target: arm64e-maccatalyst - value: 73557AF9-086C-3CB4-9E95-CA1D774CAA41 + value: 616F473A-EB21-377D-B3B4-F1581F127F0D install-name: '/usr/lib/system/libsystem_trace.dylib' -current-version: 1406.0.15 +current-version: 1406.60.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3551,17 +3553,17 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 31C10303-6B57-3219-8DEF-ED784DCC67BA + value: E45FA86E-48EB-3926-A24C-323DB84D3700 - target: x86_64-maccatalyst - value: 31C10303-6B57-3219-8DEF-ED784DCC67BA + value: E45FA86E-48EB-3926-A24C-323DB84D3700 - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 60F56A64-C75D-3E87-B275-E1FB9D078C5E + value: 1228EDDF-7C61-3674-8C42-B537FFE9EDDA - target: arm64e-maccatalyst - value: 60F56A64-C75D-3E87-B275-E1FB9D078C5E + value: 1228EDDF-7C61-3674-8C42-B537FFE9EDDA install-name: '/usr/lib/system/libunwind.dylib' current-version: 202.100 parent-umbrella: @@ -3624,19 +3626,19 @@ targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatal arm64e-macos, arm64e-maccatalyst ] uuids: - target: x86_64-macos - value: 38124BDF-4424-32BF-A60B-B4E96BC0EF70 + value: 7E56F9FE-DC35-3354-BA23-4103C09E22DD - target: x86_64-maccatalyst - value: 38124BDF-4424-32BF-A60B-B4E96BC0EF70 + value: 7E56F9FE-DC35-3354-BA23-4103C09E22DD - target: arm64-macos value: 00000000-0000-0000-0000-000000000000 - target: arm64-maccatalyst value: 00000000-0000-0000-0000-000000000000 - target: arm64e-macos - value: 44992A1E-D222-3D40-841D-E2CF9E26F67E + value: 8EF4547D-1AF8-37CF-B15A-29405BF12642 - target: arm64e-maccatalyst - value: 44992A1E-D222-3D40-841D-E2CF9E26F67E + value: 8EF4547D-1AF8-37CF-B15A-29405BF12642 install-name: '/usr/lib/system/libxpc.dylib' -current-version: 2462.41.2 +current-version: 2462.60.15 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] From 14c0b8c54863a4f88ffc0e6a740998bc0ebe89d5 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 21:26:12 -0400 Subject: [PATCH 117/216] x86_64: remove unused Mir encodings This also restores the size of Mir.Inst and simplifies logic in general. --- src/arch/x86_64/CodeGen.zig | 15 +++------------ src/arch/x86_64/Emit.zig | 18 ++++-------------- src/arch/x86_64/Mir.zig | 18 ++++++------------ 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index a2c5b291bf..08b6a9950f 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -668,20 +668,11 @@ fn asmMemoryRegisterImmediate( _ = try self.addInst(.{ .tag = tag, .ops = switch (m) { - .sib => switch (imm) { - .signed => .mri_sib_s, - .unsigned => .mri_sib_u, - }, - .rip => switch (imm) { - .signed => .mri_rip_s, - .unsigned => .mri_sib_u, - }, + .sib => .mri_sib, + .rip => .mri_rip, else => unreachable, }, - .data = .{ .rix = .{ .r = reg, .i = switch (imm) { - .signed => |s| @bitCast(u32, s), - .unsigned => |u| @intCast(u32, u), - }, .payload = switch (m) { + .data = .{ .rix = .{ .r = reg, .i = @intCast(u8, imm.unsigned), .payload = switch (m) { .sib => try self.addExtra(Mir.MemorySib.encode(m)), .rip => try self.addExtra(Mir.MemoryRip.encode(m)), else => unreachable, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index b4218f48a9..b65d22807a 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -359,27 +359,17 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE op2 = .{ .reg = data.rrx.r1 }; op2 = .{ .reg = data.rrx.r2 }; }, - .mri_sib_u, .mri_sib_s => { + .mri_sib => { const msib = emit.mir.extraData(Mir.MemorySib, data.rix.payload).data; - const imm = switch (ops) { - .mri_sib_s => Immediate.s(@bitCast(i32, data.rix.i)), - .mri_sib_u, .lock_mi_rip_u => Immediate.u(data.rix.i), - else => unreachable, - }; op1 = .{ .mem = Mir.MemorySib.decode(msib) }; op2 = .{ .reg = data.rix.r }; - op3 = .{ .imm = imm }; + op3 = .{ .imm = Immediate.u(data.rix.i) }; }, - .mri_rip_u, .mri_rip_s => { + .mri_rip => { const mrip = emit.mir.extraData(Mir.MemoryRip, data.rix.payload).data; - const imm = switch (ops) { - .mri_rip_s => Immediate.s(@bitCast(i32, data.rix.i)), - .mri_rip_u, .lock_mi_rip_u => Immediate.u(data.rix.i), - else => unreachable, - }; op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; op2 = .{ .reg = data.rix.r }; - op3 = .{ .imm = imm }; + op3 = .{ .imm = Immediate.u(data.rix.i) }; }, else => return emit.fail("TODO handle generic encoding: {s}, {s}", .{ @tagName(mnemonic), diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 9b2fa2e969..a6a4115814 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -343,18 +343,12 @@ pub const Inst = struct { /// Memory (RIP), register, register operands. /// Uses `rrx` payload with extra data of type `MemoryRip`. mrr_rip, - /// Memory (SIB), register, immediate (unsigned) operands. + /// Memory (SIB), register, immediate (byte) operands. /// Uses `rix` payload with extra data of type `MemorySib`. - mri_sib_u, - /// Memory (RIP), register, immediate (unsigned) operands. + mri_sib, + /// Memory (RIP), register, immediate (byte) operands. /// Uses `rix` payload with extra data of type `MemoryRip`. - mri_rip_u, - /// Memory (SIB), register, immediate (signed) operands. - /// Uses `rix` payload with extra data of type `MemorySib`. - mri_sib_s, - /// Memory (RIP), register, immediate (signed) operands. - /// Uses `rix` payload with extra data of type `MemoryRip`. - mri_rip_s, + mri_rip, /// Rax, Memory moffs. /// Uses `payload` with extra data of type `MemoryMoffs`. rax_moffs, @@ -481,10 +475,10 @@ pub const Inst = struct { r2: Register, payload: u32, }, - /// Register, immediate, followed by Custom payload found in extra. + /// Register, byte immediate, followed by Custom payload found in extra. rix: struct { r: Register, - i: u32, + i: u8, payload: u32, }, /// String instruction prefix and width. From 65f77878b4d37a2e179c90f5f0b2515d0901a43e Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 21:32:43 -0400 Subject: [PATCH 118/216] std: remove temporary workarounds for stage2_x86_64 These seem to work great now. --- lib/std/io.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/std/io.zig b/lib/std/io.zig index 0faba2b652..d95997f853 100644 --- a/lib/std/io.zig +++ b/lib/std/io.zig @@ -29,8 +29,8 @@ pub const default_mode: ModeOverride = if (is_async) Mode.evented else .blocking fn getStdOutHandle() os.fd_t { if (builtin.os.tag == .windows) { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_aarch64) { - // TODO: this is just a temporary workaround until we advance x86 backend further along. + if (builtin.zig_backend == .stage2_aarch64) { + // TODO: this is just a temporary workaround until we advance aarch64 backend further along. return os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE) catch os.windows.INVALID_HANDLE_VALUE; } return os.windows.peb().ProcessParameters.hStdOutput; @@ -55,8 +55,8 @@ pub fn getStdOut() File { fn getStdErrHandle() os.fd_t { if (builtin.os.tag == .windows) { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_aarch64) { - // TODO: this is just a temporary workaround until we advance x86 backend further along. + if (builtin.zig_backend == .stage2_aarch64) { + // TODO: this is just a temporary workaround until we advance aarch64 backend further along. return os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE) catch os.windows.INVALID_HANDLE_VALUE; } return os.windows.peb().ProcessParameters.hStdError; @@ -81,8 +81,8 @@ pub fn getStdErr() File { fn getStdInHandle() os.fd_t { if (builtin.os.tag == .windows) { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_aarch64) { - // TODO: this is just a temporary workaround until we advance x86 backend further along. + if (builtin.zig_backend == .stage2_aarch64) { + // TODO: this is just a temporary workaround until we advance aarch64 backend further along. return os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE) catch os.windows.INVALID_HANDLE_VALUE; } return os.windows.peb().ProcessParameters.hStdInput; From 4a5628e7306a242ce0d2f14f09eaf17ad4ae87b2 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sun, 26 Mar 2023 15:13:51 +0300 Subject: [PATCH 119/216] Module: fix lazy srcloc resolution for new for loop syntax Closes #15081 --- src/Module.zig | 18 +++++++++--------- .../comptime_if_inside_runtime_for.zig | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 test/cases/compile_errors/comptime_if_inside_runtime_for.zig diff --git a/src/Module.zig b/src/Module.zig index 906bde95c7..9dab3edccd 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2459,7 +2459,7 @@ pub const SrcLoc = struct { return nodeToSpan(tree, node_datas[asm_output].lhs); }, - .node_offset_for_cond, .node_offset_if_cond => |node_off| { + .node_offset_if_cond => |node_off| { const tree = try src_loc.file_scope.getTree(gpa); const node = src_loc.declRelativeToNodeIndex(node_off); const node_tags = tree.nodes.items(.tag); @@ -2471,9 +2471,16 @@ pub const SrcLoc = struct { .while_simple, .while_cont, .@"while", + => tree.fullWhile(node).?.ast.cond_expr, + .for_simple, .@"for", - => tree.fullWhile(node).?.ast.cond_expr, + => { + const inputs = tree.fullFor(node).?.ast.inputs; + const start = tree.firstToken(inputs[0]); + const end = tree.lastToken(inputs[inputs.len - 1]); + return tokensToSpan(tree, start, end, start); + }, .@"orelse" => node, .@"catch" => node, @@ -2967,12 +2974,6 @@ pub const LazySrcLoc = union(enum) { /// The source location points to the initializer of a var decl. /// The Decl is determined contextually. node_offset_var_decl_init: i32, - /// The source location points to a for loop condition expression, - /// found by taking this AST node index offset from the containing - /// Decl AST node, which points to a for loop AST node. Next, navigate - /// to the condition expression. - /// The Decl is determined contextually. - node_offset_for_cond: i32, /// The source location points to the first parameter of a builtin /// function call, found by taking this AST node index offset from the containing /// Decl AST node, which points to a builtin call AST node. Next, navigate @@ -3233,7 +3234,6 @@ pub const LazySrcLoc = union(enum) { .node_offset_var_decl_section, .node_offset_var_decl_addrspace, .node_offset_var_decl_init, - .node_offset_for_cond, .node_offset_builtin_call_arg0, .node_offset_builtin_call_arg1, .node_offset_builtin_call_arg2, diff --git a/test/cases/compile_errors/comptime_if_inside_runtime_for.zig b/test/cases/compile_errors/comptime_if_inside_runtime_for.zig new file mode 100644 index 0000000000..6200776d18 --- /dev/null +++ b/test/cases/compile_errors/comptime_if_inside_runtime_for.zig @@ -0,0 +1,14 @@ +export fn entry() void { + var x: u32 = 0; + for(0..1, 1..2) |_, _| { + var y = x + if(x == 0) 1 else 0; + _ = y; + } +} + +// error +// backend=stage2 +// target=native +// +// :4:15: error: value with comptime-only type 'comptime_int' depends on runtime control flow +// :3:6: note: runtime control flow here From 43ff6c14f96187ec93bbc23432cdbb885f5ab8f1 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Sun, 26 Mar 2023 13:10:36 -0400 Subject: [PATCH 120/216] main: recognize --dynamicbase --- src/main.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.zig b/src/main.zig index 479c7e518c..c96fd25766 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1371,6 +1371,8 @@ fn buildOutputType( linker_opt_bisect_limit = std.math.lossyCast(i32, parseIntSuffix(arg, "-fopt-bisect-limit=".len)); } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { link_eh_frame_hdr = true; + } else if (mem.eql(u8, arg, "--dynamicbase")) { + linker_dynamicbase = true; } else if (mem.eql(u8, arg, "--no-dynamicbase")) { linker_dynamicbase = false; } else if (mem.eql(u8, arg, "--emit-relocs")) { From 1de64dba236d9496ae5f31b59b7a4947ff4d90be Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 25 Mar 2023 19:43:41 +0000 Subject: [PATCH 121/216] std: add the VM_MAKE_TAG macro for darwin. --- lib/std/c/darwin.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index eefa68e6a9..e72bdbe843 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -435,6 +435,10 @@ pub const VM_REGION_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region pub const VM_REGION_EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t); pub const VM_REGION_TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t); +pub fn VM_MAKE_TAG(tag: u8) u32 { + return @as(u32, tag) << 24; +} + pub const vm_region_basic_info_64 = extern struct { protection: vm_prot_t, max_protection: vm_prot_t, From 86625c5a752796b64966541187a5843e11add615 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 25 Mar 2023 23:06:54 -0400 Subject: [PATCH 122/216] x86_64: enable mem dst bin ops, and fix uncovered bugs --- src/arch/x86_64/CodeGen.zig | 224 +++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 103 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 08b6a9950f..b32d7ef214 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1628,7 +1628,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { const reg_bits = self.regBitSize(ty); const cc: Condition = if (ty.isSignedInt()) cc: { try self.genSetReg(ty, limit_reg, dst_mcv); - try self.genBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genShiftBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); try self.genBinOpMir(.xor, ty, limit_mcv, .{ .immediate = (@as(u64, 1) << @intCast(u6, reg_bits - 1)) - 1, }); @@ -1681,7 +1681,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { const reg_bits = self.regBitSize(ty); const cc: Condition = if (ty.isSignedInt()) cc: { try self.genSetReg(ty, limit_reg, dst_mcv); - try self.genBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genShiftBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); try self.genBinOpMir(.xor, ty, limit_mcv, .{ .immediate = (@as(u64, 1) << @intCast(u6, reg_bits - 1)) - 1, }); @@ -1735,7 +1735,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { const cc: Condition = if (ty.isSignedInt()) cc: { try self.genSetReg(ty, limit_reg, lhs_mcv); try self.genBinOpMir(.xor, ty, limit_mcv, rhs_mcv); - try self.genBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genShiftBinOpMir(.sar, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); try self.genBinOpMir(.xor, ty, limit_mcv, .{ .immediate = (@as(u64, 1) << @intCast(u6, reg_bits - 1)) - 1, }); @@ -2509,16 +2509,13 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { - const operand = try self.resolveInst(ty_op.operand); - const dst_mcv: MCValue = blk: { - switch (operand) { - .stack_offset => |off| { - break :blk MCValue{ .stack_offset = off }; - }, - else => return self.fail("TODO implement slice_ptr for {}", .{operand}), - } - }; + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const src_mcv = try self.resolveInst(ty_op.operand); + if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; + + const dst_mcv = try self.allocRegOrMem(inst, true); + const dst_ty = self.air.typeOfIndex(inst); + try self.setRegOrMem(dst_ty, dst_mcv, src_mcv); break :result dst_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -4402,7 +4399,7 @@ fn genBinOp( else => {}, } - const is_commutative: bool = switch (tag) { + const is_commutative = switch (tag) { .add, .addwrap, .bool_or, @@ -4416,6 +4413,20 @@ fn genBinOp( else => false, }; + const needs_reg_dst = switch (tag) { + .add, + .addwrap, + .sub, + .subwrap, + .mul, + .div_float, + .div_exact, + .div_trunc, + .div_floor, + => lhs_ty.isRuntimeFloat(), + + else => false, + }; const lhs_lock: ?RegisterLock = switch (lhs) { .register => |reg| self.register_manager.lockRegAssumeUnused(reg), @@ -4432,10 +4443,10 @@ fn genBinOp( var flipped: bool = false; const dst_mcv: MCValue = blk: { if (maybe_inst) |inst| { - if (lhs.isRegister() and self.reuseOperand(inst, lhs_air, 0, lhs)) { + if ((!needs_reg_dst or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) { break :blk lhs; } - if (is_commutative and rhs.isRegister() and self.reuseOperand(inst, rhs_air, 1, rhs)) { + if (is_commutative and (!needs_reg_dst or rhs.isRegister()) and self.reuseOperand(inst, rhs_air, 1, rhs)) { flipped = true; break :blk rhs; } @@ -4485,33 +4496,37 @@ fn genBinOp( .div_float, .div_exact, - => try self.genBinOpMir(switch (lhs_ty.tag()) { - .f32 => .divss, - .f64 => .divsd, - else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), - }, lhs_ty, dst_mcv, src_mcv), - .div_trunc, .div_floor, => { try self.genBinOpMir(switch (lhs_ty.tag()) { .f32 => .divss, .f64 => .divsd, - else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }), + else => return self.fail("TODO implement genBinOp for {s} {}", .{ + @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?), + }), }, lhs_ty, dst_mcv, src_mcv); - if (Target.x86.featureSetHas(self.target.cpu.features, .sse4_1)) { - const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); - const dst_alias = registerAlias(dst_mcv.register, abi_size); - try self.asmRegisterRegisterImmediate(switch (lhs_ty.tag()) { - .f32 => .roundss, - .f64 => .roundsd, - else => unreachable, - }, dst_alias, dst_alias, Immediate.u(switch (tag) { - .div_trunc => 0b1_0_11, - .div_floor => 0b1_0_01, - else => unreachable, - })); - } else return self.fail("TODO implement round without sse4_1", .{}); + switch (tag) { + .div_float, + .div_exact, + => {}, + .div_trunc, + .div_floor, + => if (Target.x86.featureSetHas(self.target.cpu.features, .sse4_1)) { + const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); + const dst_alias = registerAlias(dst_mcv.register, abi_size); + try self.asmRegisterRegisterImmediate(switch (lhs_ty.tag()) { + .f32 => .roundss, + .f64 => .roundsd, + else => unreachable, + }, dst_alias, dst_alias, Immediate.u(switch (tag) { + .div_trunc => 0b1_0_11, + .div_floor => 0b1_0_01, + else => unreachable, + })); + } else return self.fail("TODO implement round without sse4_1", .{}), + else => unreachable, + } }, .ptr_add, @@ -4568,7 +4583,13 @@ fn genBinOp( }; const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); - switch (dst_mcv) { + const tmp_reg = switch (dst_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(lhs_ty, dst_mcv), + }; + const tmp_lock = self.register_manager.lockReg(tmp_reg); + defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock); + switch (mat_src_mcv) { .none, .undef, .dead, @@ -4576,57 +4597,44 @@ fn genBinOp( .immediate, .eflags, .register_overflow, - .stack_offset, .ptr_stack_offset, - .memory, - .linker_load, => unreachable, - .register => |dst_reg| switch (mat_src_mcv) { - .none, - .undef, - .dead, - .unreach, - .immediate, - .eflags, - .register_overflow, - .ptr_stack_offset, - => unreachable, - .register => |src_reg| try self.asmCmovccRegisterRegister( - registerAlias(dst_reg, abi_size), - registerAlias(src_reg, abi_size), + .register => |src_reg| try self.asmCmovccRegisterRegister( + registerAlias(tmp_reg, abi_size), + registerAlias(src_reg, abi_size), + cc, + ), + .stack_offset => |off| try self.asmCmovccRegisterMemory( + registerAlias(tmp_reg, abi_size), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ + .base = .rbp, + .disp = -off, + }), + cc, + ), + .memory, .linker_load => { + const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); + const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); + defer self.register_manager.unlockReg(addr_reg_lock); + + try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mat_src_mcv); + + // To get the actual address of the value we want to modify we + // we have to go through the GOT + try self.asmRegisterMemory( + .mov, + addr_reg, + Memory.sib(.qword, .{ .base = addr_reg }), + ); + + try self.asmCmovccRegisterMemory( + registerAlias(tmp_reg, abi_size), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), cc, - ), - .stack_offset => |off| try self.asmCmovccRegisterMemory( - registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - }), - cc, - ), - .memory, .linker_load => { - const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); - const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); - defer self.register_manager.unlockReg(addr_reg_lock); - - try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv); - - // To get the actual address of the value we want to modify we - // we have to go through the GOT - try self.asmRegisterMemory( - .mov, - addr_reg, - Memory.sib(.qword, .{ .base = addr_reg }), - ); - - try self.asmCmovccRegisterMemory( - registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), - cc, - ); - }, + ); }, } + try self.setRegOrMem(lhs_ty, dst_mcv, .{ .register = tmp_reg }); }, .Float => try self.genBinOpMir(switch (lhs_ty.tag()) { .f32 => switch (tag) { @@ -4649,8 +4657,8 @@ fn genBinOp( return dst_mcv; } -fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { - const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); +fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { + const abi_size = @intCast(u32, ty.abiSize(self.target.*)); switch (dst_mcv) { .none => unreachable, .undef => unreachable, @@ -4667,12 +4675,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu const dst_reg_lock = self.register_manager.lockReg(dst_reg); defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); - const reg = try self.copyToTmpRegister(dst_ty, src_mcv); - return self.genBinOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg }); + const reg = try self.copyToTmpRegister(ty, src_mcv); + return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = reg }); }, - .register => |src_reg| switch (dst_ty.zigTypeTag()) { + .register => |src_reg| switch (ty.zigTypeTag()) { .Float => { - if (intrinsicsAllowed(self.target.*, dst_ty)) { + if (intrinsicsAllowed(self.target.*, ty)) { return self.asmRegisterRegister(mir_tag, dst_reg.to128(), src_reg.to128()); } @@ -4685,7 +4693,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu ), }, .immediate => |imm| { - switch (self.regBitSize(dst_ty)) { + switch (self.regBitSize(ty)) { 8, 16, 32 => { try self.asmRegisterImmediate( mir_tag, @@ -4704,7 +4712,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu try self.asmRegisterRegister( mir_tag, registerAlias(dst_reg, abi_size), - registerAlias(try self.copyToTmpRegister(dst_ty, src_mcv), abi_size), + registerAlias(try self.copyToTmpRegister(ty, src_mcv), abi_size), ); } }, @@ -4719,8 +4727,8 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu const dst_reg_lock = self.register_manager.lockReg(dst_reg); defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); - const reg = try self.copyToTmpRegister(dst_ty, src_mcv); - return self.genBinOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg }); + const reg = try self.copyToTmpRegister(ty, src_mcv); + return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = reg }); }, .stack_offset => |off| { if (off > math.maxInt(i32)) { @@ -4754,7 +4762,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu }), registerAlias(src_reg, abi_size)); }, .immediate => |imm| { - switch (self.regBitSize(dst_ty)) { + switch (self.regBitSize(ty)) { 8, 16, 32 => { try self.asmMemoryImmediate( mir_tag, @@ -4785,7 +4793,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu .base = .rbp, .disp = -off, }), - registerAlias(try self.copyToTmpRegister(dst_ty, src_mcv), abi_size), + registerAlias(try self.copyToTmpRegister(ty, src_mcv), abi_size), ); } }, @@ -4793,16 +4801,18 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu } }, .memory, + .linker_load, .stack_offset, .ptr_stack_offset, + .eflags, => { - return self.fail("TODO implement x86 genBinOpMir source memory", .{}); - }, - .linker_load => { - return self.fail("TODO implement x86 genBinOpMir source symbol at index in linker", .{}); - }, - .eflags => { - return self.fail("TODO implement x86 genBinOpMir source eflags", .{}); + assert(abi_size <= 8); + + const tmp_reg = try self.copyToTmpRegister(ty, src_mcv); + const tmp_lock = self.register_manager.lockReg(tmp_reg); + defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock); + + return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = tmp_reg }); }, } }, @@ -7151,7 +7161,15 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; - const result = try self.resolveInst(un_op); + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const src_mcv = try self.resolveInst(un_op); + if (self.reuseOperand(inst, un_op, 0, src_mcv)) break :result src_mcv; + + const dst_mcv = try self.allocRegOrMem(inst, true); + const dst_ty = self.air.typeOfIndex(inst); + try self.setRegOrMem(dst_ty, dst_mcv, src_mcv); + break :result dst_mcv; + }; return self.finishAir(inst, result, .{ un_op, .none, .none }); } From 0e5e001278465e508130eb159327e6aa11895f1c Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 26 Mar 2023 03:27:35 -0400 Subject: [PATCH 123/216] std.MultiArrayList: add set and get to Slice --- lib/std/multi_array_list.zig | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index f97e42cc89..b9624692fc 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -49,6 +49,20 @@ pub fn MultiArrayList(comptime S: type) type { return casted_ptr[0..self.len]; } + pub fn set(self: Slice, index: usize, elem: S) void { + inline for (fields) |field_info| { + self.items(@field(Field, field_info.name))[index] = @field(elem, field_info.name); + } + } + + pub fn get(self: Slice, index: usize) S { + var elem: S = undefined; + inline for (fields) |field_info| { + @field(elem, field_info.name) = self.items(@field(Field, field_info.name))[index]; + } + return elem; + } + pub fn toMultiArrayList(self: Slice) Self { if (self.ptrs.len == 0) { return .{}; @@ -156,20 +170,12 @@ pub fn MultiArrayList(comptime S: type) type { /// Overwrite one array element with new data. pub fn set(self: *Self, index: usize, elem: S) void { - const slices = self.slice(); - inline for (fields, 0..) |field_info, i| { - slices.items(@intToEnum(Field, i))[index] = @field(elem, field_info.name); - } + return self.slice().set(index, elem); } /// Obtain all the data for one array element. pub fn get(self: Self, index: usize) S { - const slices = self.slice(); - var result: S = undefined; - inline for (fields, 0..) |field_info, i| { - @field(result, field_info.name) = slices.items(@intToEnum(Field, i))[index]; - } - return result; + return self.slice().get(index); } /// Extend the list by 1 element. Allocates more memory as necessary. From abb37a7cb8d4bfae2da6d2cb9e9e6305ef6e52c4 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 26 Mar 2023 21:33:56 -0400 Subject: [PATCH 124/216] x86_64: factor out lowering from emitting --- src/arch/x86_64/CodeGen.zig | 21 +- src/arch/x86_64/Emit.zig | 909 ++++--------------- src/arch/x86_64/Encoding.zig | 290 +++---- src/arch/x86_64/Lower.zig | 465 ++++++++++ src/arch/x86_64/Mir.zig | 19 +- src/arch/x86_64/bits.zig | 2 +- src/arch/x86_64/encoder.zig | 919 ++++++++++++-------- src/arch/x86_64/encodings.zig | 1539 +++++++++++++++++---------------- 8 files changed, 2102 insertions(+), 2062 deletions(-) create mode 100644 src/arch/x86_64/Lower.zig diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b32d7ef214..5ab0e64615 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -341,19 +341,22 @@ pub fn generate( defer mir.deinit(bin_file.allocator); var emit = Emit{ - .mir = mir, + .lower = .{ + .allocator = bin_file.allocator, + .mir = mir, + .target = &bin_file.options.target, + .src_loc = src_loc, + }, .bin_file = bin_file, .debug_output = debug_output, - .target = &bin_file.options.target, - .src_loc = src_loc, .code = code, .prev_di_pc = 0, .prev_di_line = module_fn.lbrace_line, .prev_di_column = module_fn.lbrace_column, }; defer emit.deinit(); - emit.lowerMir() catch |err| switch (err) { - error.EmitFail => return Result{ .fail = emit.err_msg.? }, + emit.emitMir() catch |err| switch (err) { + error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? }, error.InvalidInstruction, error.CannotEncode => |e| { const msg = switch (e) { error.InvalidInstruction => "CodeGen failed to find a viable instruction.", @@ -7070,16 +7073,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void if (reg.to64() == .rax) { // If this is RAX, we can use a direct load. // Otherwise, we need to load the address, then indirectly load the value. - var moffs: Mir.MemoryMoffs = .{ - .seg = @enumToInt(Register.ds), - .msb = undefined, - .lsb = undefined, - }; - moffs.encodeOffset(x); _ = try self.addInst(.{ .tag = .mov_moffs, .ops = .rax_moffs, - .data = .{ .payload = try self.addExtra(moffs) }, + .data = .{ .payload = try self.addExtra(Mir.MemoryMoffs.encode(.ds, x)) }, }); } else { // Rather than duplicate the logic used for the move, we just use a self-call with a new MCValue. diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index b65d22807a..052139a4e5 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -1,40 +1,8 @@ -//! This file contains the functionality for lowering x86_64 MIR into -//! machine code +//! This file contains the functionality for emitting x86_64 MIR as machine code -const Emit = @This(); - -const std = @import("std"); -const assert = std.debug.assert; -const bits = @import("bits.zig"); -const abi = @import("abi.zig"); -const encoder = @import("encoder.zig"); -const link = @import("../../link.zig"); -const log = std.log.scoped(.codegen); -const math = std.math; -const mem = std.mem; -const testing = std.testing; - -const Air = @import("../../Air.zig"); -const Allocator = mem.Allocator; -const CodeGen = @import("CodeGen.zig"); -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; -const Encoder = bits.Encoder; -const ErrorMsg = Module.ErrorMsg; -const Immediate = bits.Immediate; -const Instruction = encoder.Instruction; -const MCValue = @import("CodeGen.zig").MCValue; -const Memory = bits.Memory; -const Mir = @import("Mir.zig"); -const Module = @import("../../Module.zig"); -const Register = bits.Register; -const Type = @import("../../type.zig").Type; - -mir: Mir, +lower: Lower, bin_file: *link.File, debug_output: DebugInfoOutput, -target: *const std.Target, -err_msg: ?*ErrorMsg = null, -src_loc: Module.SrcLoc, code: *std.ArrayList(u8), prev_di_line: u32, @@ -45,12 +13,163 @@ prev_di_pc: usize, code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .{}, relocs: std.ArrayListUnmanaged(Reloc) = .{}, -const InnerError = error{ - OutOfMemory, - EmitFail, - InvalidInstruction, - CannotEncode, -}; +pub const Error = Lower.Error || error{EmitFail}; + +pub fn emitMir(emit: *Emit) Error!void { + for (0..emit.lower.mir.instructions.len) |i| { + const index = @intCast(Mir.Inst.Index, i); + const inst = emit.lower.mir.instructions.get(index); + + const start_offset = @intCast(u32, emit.code.items.len); + try emit.code_offset_mapping.putNoClobber(emit.lower.allocator, index, start_offset); + for (try emit.lower.lowerMir(inst)) |lower_inst| try lower_inst.encode(emit.code.writer()); + const end_offset = @intCast(u32, emit.code.items.len); + + switch (inst.tag) { + else => {}, + + .jmp_reloc => try emit.relocs.append(emit.lower.allocator, .{ + .source = start_offset, + .target = inst.data.inst, + .offset = end_offset - 4, + .length = 5, + }), + + .call_extern => if (emit.bin_file.cast(link.File.MachO)) |macho_file| { + // Add relocation to the decl. + const atom_index = macho_file.getAtomIndexForSymbol( + .{ .sym_index = inst.data.relocation.atom_index, .file = null }, + ).?; + const target = macho_file.getGlobalByIndex(inst.data.relocation.sym_index); + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ + .type = @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), + .target = target, + .offset = end_offset - 4, + .addend = 0, + .pcrel = true, + .length = 2, + }); + } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { + // Add relocation to the decl. + const atom_index = coff_file.getAtomIndexForSymbol( + .{ .sym_index = inst.data.relocation.atom_index, .file = null }, + ).?; + const target = coff_file.getGlobalByIndex(inst.data.relocation.sym_index); + try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ + .type = .direct, + .target = target, + .offset = end_offset - 4, + .addend = 0, + .pcrel = true, + .length = 2, + }); + } else return emit.fail("TODO implement {} for {}", .{ inst.tag, emit.bin_file.tag }), + + .lea_linker => if (emit.bin_file.cast(link.File.MachO)) |macho_file| { + const metadata = + emit.lower.mir.extraData(Mir.LeaRegisterReloc, inst.data.payload).data; + const reloc_type = switch (inst.ops) { + .got_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_GOT), + .direct_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), + else => unreachable, + }; + const atom_index = macho_file.getAtomIndexForSymbol(.{ + .sym_index = metadata.atom_index, + .file = null, + }).?; + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ + .type = reloc_type, + .target = .{ .sym_index = metadata.sym_index, .file = null }, + .offset = @intCast(u32, end_offset - 4), + .addend = 0, + .pcrel = true, + .length = 2, + }); + } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { + const metadata = + emit.lower.mir.extraData(Mir.LeaRegisterReloc, inst.data.payload).data; + const atom_index = coff_file.getAtomIndexForSymbol(.{ + .sym_index = metadata.atom_index, + .file = null, + }).?; + try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ + .type = switch (inst.ops) { + .got_reloc => .got, + .direct_reloc => .direct, + .import_reloc => .import, + else => unreachable, + }, + .target = switch (inst.ops) { + .got_reloc, + .direct_reloc, + => .{ .sym_index = metadata.sym_index, .file = null }, + .import_reloc => coff_file.getGlobalByIndex(metadata.sym_index), + else => unreachable, + }, + .offset = @intCast(u32, end_offset - 4), + .addend = 0, + .pcrel = true, + .length = 2, + }); + } else return emit.fail("TODO implement {} for {}", .{ inst.tag, emit.bin_file.tag }), + + .jcc => try emit.relocs.append(emit.lower.allocator, .{ + .source = start_offset, + .target = inst.data.inst_cc.inst, + .offset = end_offset - 4, + .length = 6, + }), + + .dbg_line => { + const dbg_line_column = + emit.lower.mir.extraData(Mir.DbgLineColumn, inst.data.payload).data; + try emit.dbgAdvancePCAndLine(dbg_line_column.line, dbg_line_column.column); + }, + + .dbg_prologue_end => { + switch (emit.debug_output) { + .dwarf => |dw| { + try dw.setPrologueEnd(); + log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{ + emit.prev_di_line, emit.prev_di_column, + }); + try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column); + }, + .plan9 => {}, + .none => {}, + } + }, + + .dbg_epilogue_begin => { + switch (emit.debug_output) { + .dwarf => |dw| { + try dw.setEpilogueBegin(); + log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{ + emit.prev_di_line, emit.prev_di_column, + }); + try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column); + }, + .plan9 => {}, + .none => {}, + } + }, + } + } + try emit.fixupRelocs(); +} + +pub fn deinit(emit: *Emit) void { + emit.relocs.deinit(emit.lower.allocator); + emit.code_offset_mapping.deinit(emit.lower.allocator); + emit.* = undefined; +} + +fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error { + return switch (emit.lower.fail(format, args)) { + error.LowerFail => error.EmitFail, + else => |e| e, + }; +} const Reloc = struct { /// Offset of the instruction. @@ -63,148 +182,7 @@ const Reloc = struct { length: u5, }; -pub fn lowerMir(emit: *Emit) InnerError!void { - const mir_tags = emit.mir.instructions.items(.tag); - - for (mir_tags, 0..) |tag, index| { - const inst = @intCast(u32, index); - try emit.code_offset_mapping.putNoClobber(emit.bin_file.allocator, inst, emit.code.items.len); - switch (tag) { - .adc, - .add, - .@"and", - .bsf, - .bsr, - .bswap, - .bt, - .btc, - .btr, - .bts, - .call, - .cbw, - .cwde, - .cdqe, - .cwd, - .cdq, - .cqo, - .cmp, - .cmpxchg, - .div, - .fisttp, - .fld, - .idiv, - .imul, - .int3, - .jmp, - .lea, - .lfence, - .lzcnt, - .mfence, - .mov, - .movbe, - .movzx, - .mul, - .neg, - .nop, - .not, - .@"or", - .pop, - .popcnt, - .push, - .rcl, - .rcr, - .ret, - .rol, - .ror, - .sal, - .sar, - .sbb, - .sfence, - .shl, - .shld, - .shr, - .shrd, - .sub, - .syscall, - .@"test", - .tzcnt, - .ud2, - .xadd, - .xchg, - .xor, - - .addss, - .cmpss, - .divss, - .maxss, - .minss, - .movss, - .mulss, - .roundss, - .subss, - .ucomiss, - .addsd, - .cmpsd, - .divsd, - .maxsd, - .minsd, - .movsd, - .mulsd, - .roundsd, - .subsd, - .ucomisd, - => try emit.mirEncodeGeneric(tag, inst), - - .cmps, - .lods, - .movs, - .scas, - .stos, - => try emit.mirString(tag, inst), - - .cmpxchgb => try emit.mirCmpxchgBytes(inst), - - .jmp_reloc => try emit.mirJmpReloc(inst), - - .call_extern => try emit.mirCallExtern(inst), - - .lea_linker => try emit.mirLeaLinker(inst), - - .mov_moffs => try emit.mirMovMoffs(inst), - - .movsx => try emit.mirMovsx(inst), - .cmovcc => try emit.mirCmovcc(inst), - .setcc => try emit.mirSetcc(inst), - .jcc => try emit.mirJcc(inst), - - .dbg_line => try emit.mirDbgLine(inst), - .dbg_prologue_end => try emit.mirDbgPrologueEnd(inst), - .dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst), - - .push_regs => try emit.mirPushPopRegisterList(.push, inst), - .pop_regs => try emit.mirPushPopRegisterList(.pop, inst), - - .dead => {}, - } - } - - try emit.fixupRelocs(); -} - -pub fn deinit(emit: *Emit) void { - emit.relocs.deinit(emit.bin_file.allocator); - emit.code_offset_mapping.deinit(emit.bin_file.allocator); - emit.* = undefined; -} - -fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { - @setCold(true); - assert(emit.err_msg == null); - emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args); - return error.EmitFail; -} - -fn fixupRelocs(emit: *Emit) InnerError!void { +fn fixupRelocs(emit: *Emit) Error!void { // TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size. // This should be reversed like it is done in aarch64 MIR emit code: start with the smallest // possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution @@ -217,532 +195,7 @@ fn fixupRelocs(emit: *Emit) InnerError!void { } } -fn encode(emit: *Emit, mnemonic: Instruction.Mnemonic, ops: Instruction.Init) InnerError!void { - const inst = try Instruction.new(mnemonic, ops); - return inst.encode(emit.code.writer()); -} - -fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { - const mnemonic = inline for (@typeInfo(Instruction.Mnemonic).Enum.fields) |field| { - if (mem.eql(u8, field.name, @tagName(tag))) break @field(Instruction.Mnemonic, field.name); - } else unreachable; - - const ops = emit.mir.instructions.items(.ops)[inst]; - const data = emit.mir.instructions.items(.data)[inst]; - - const prefix: Instruction.Prefix = switch (ops) { - .lock_m_sib, - .lock_m_rip, - .lock_mi_sib_u, - .lock_mi_rip_u, - .lock_mi_sib_s, - .lock_mi_rip_s, - .lock_mr_sib, - .lock_mr_rip, - .lock_moffs_rax, - => .lock, - else => .none, - }; - - var op1: Instruction.Operand = .none; - var op2: Instruction.Operand = .none; - var op3: Instruction.Operand = .none; - var op4: Instruction.Operand = .none; - - switch (ops) { - .none => {}, - .i_s => op1 = .{ .imm = Immediate.s(@bitCast(i32, data.i)) }, - .i_u => op1 = .{ .imm = Immediate.u(data.i) }, - .r => op1 = .{ .reg = data.r }, - .rr => { - op1 = .{ .reg = data.rr.r1 }; - op2 = .{ .reg = data.rr.r2 }; - }, - .rrr => { - op1 = .{ .reg = data.rrr.r1 }; - op2 = .{ .reg = data.rrr.r2 }; - op3 = .{ .reg = data.rrr.r3 }; - }, - .ri_s, .ri_u => { - const imm = switch (ops) { - .ri_s => Immediate.s(@bitCast(i32, data.ri.i)), - .ri_u => Immediate.u(data.ri.i), - else => unreachable, - }; - op1 = .{ .reg = data.ri.r }; - op2 = .{ .imm = imm }; - }, - .ri64 => { - const imm64 = emit.mir.extraData(Mir.Imm64, data.rx.payload).data; - op1 = .{ .reg = data.rx.r }; - op2 = .{ .imm = Immediate.u(Mir.Imm64.decode(imm64)) }; - }, - .rri_s, .rri_u => { - const imm = switch (ops) { - .rri_s => Immediate.s(@bitCast(i32, data.rri.i)), - .rri_u => Immediate.u(data.rri.i), - else => unreachable, - }; - op1 = .{ .reg = data.rri.r1 }; - op2 = .{ .reg = data.rri.r2 }; - op3 = .{ .imm = imm }; - }, - .m_sib, .lock_m_sib => { - const msib = emit.mir.extraData(Mir.MemorySib, data.payload).data; - op1 = .{ .mem = Mir.MemorySib.decode(msib) }; - }, - .m_rip, .lock_m_rip => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.payload).data; - op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; - }, - .mi_sib_s, .mi_sib_u, .lock_mi_sib_s, .lock_mi_sib_u => { - const msib = emit.mir.extraData(Mir.MemorySib, data.ix.payload).data; - const imm = switch (ops) { - .mi_sib_s, .lock_mi_sib_s => Immediate.s(@bitCast(i32, data.ix.i)), - .mi_sib_u, .lock_mi_sib_u => Immediate.u(data.ix.i), - else => unreachable, - }; - op1 = .{ .mem = Mir.MemorySib.decode(msib) }; - op2 = .{ .imm = imm }; - }, - .mi_rip_u, .mi_rip_s, .lock_mi_rip_u, .lock_mi_rip_s => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.ix.payload).data; - const imm = switch (ops) { - .mi_rip_s, .lock_mi_rip_s => Immediate.s(@bitCast(i32, data.ix.i)), - .mi_rip_u, .lock_mi_rip_u => Immediate.u(data.ix.i), - else => unreachable, - }; - op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; - op2 = .{ .imm = imm }; - }, - .rm_sib, .mr_sib, .lock_mr_sib => { - const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data; - const op_r = .{ .reg = data.rx.r }; - const op_m = .{ .mem = Mir.MemorySib.decode(msib) }; - switch (ops) { - .rm_sib => { - op1 = op_r; - op2 = op_m; - }, - .mr_sib, .lock_mr_sib => { - op1 = op_m; - op2 = op_r; - }, - else => unreachable, - } - }, - .rm_rip, .mr_rip, .lock_mr_rip => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data; - const op_r = .{ .reg = data.rx.r }; - const op_m = .{ .mem = Mir.MemoryRip.decode(mrip) }; - switch (ops) { - .rm_rip => { - op1 = op_r; - op2 = op_m; - }, - .mr_rip, .lock_mr_rip => { - op1 = op_m; - op2 = op_r; - }, - else => unreachable, - } - }, - .mrr_sib => { - const msib = emit.mir.extraData(Mir.MemorySib, data.rrx.payload).data; - op1 = .{ .mem = Mir.MemorySib.decode(msib) }; - op2 = .{ .reg = data.rrx.r1 }; - op2 = .{ .reg = data.rrx.r2 }; - }, - .mrr_rip => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.rrx.payload).data; - op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; - op2 = .{ .reg = data.rrx.r1 }; - op2 = .{ .reg = data.rrx.r2 }; - }, - .mri_sib => { - const msib = emit.mir.extraData(Mir.MemorySib, data.rix.payload).data; - op1 = .{ .mem = Mir.MemorySib.decode(msib) }; - op2 = .{ .reg = data.rix.r }; - op3 = .{ .imm = Immediate.u(data.rix.i) }; - }, - .mri_rip => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.rix.payload).data; - op1 = .{ .mem = Mir.MemoryRip.decode(mrip) }; - op2 = .{ .reg = data.rix.r }; - op3 = .{ .imm = Immediate.u(data.rix.i) }; - }, - else => return emit.fail("TODO handle generic encoding: {s}, {s}", .{ - @tagName(mnemonic), - @tagName(ops), - }), - } - - return emit.encode(mnemonic, .{ - .prefix = prefix, - .op1 = op1, - .op2 = op2, - .op3 = op3, - .op4 = op4, - }); -} - -fn mirString(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - switch (ops) { - .string => { - const data = emit.mir.instructions.items(.data)[inst].string; - const mnemonic = switch (tag) { - inline .cmps, .lods, .movs, .scas, .stos => |comptime_tag| switch (data.width) { - inline else => |comptime_width| @field( - Instruction.Mnemonic, - @tagName(comptime_tag) ++ @tagName(comptime_width), - ), - }, - else => unreachable, - }; - return emit.encode(mnemonic, .{ .prefix = switch (data.repeat) { - inline else => |comptime_repeat| @field(Instruction.Prefix, @tagName(comptime_repeat)), - } }); - }, - else => unreachable, - } -} - -fn mirCmpxchgBytes(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - const data = emit.mir.instructions.items(.data)[inst]; - - var op1: Instruction.Operand = .none; - switch (ops) { - .m_sib, .lock_m_sib => { - const sib = emit.mir.extraData(Mir.MemorySib, data.payload).data; - op1 = .{ .mem = Mir.MemorySib.decode(sib) }; - }, - .m_rip, .lock_m_rip => { - const rip = emit.mir.extraData(Mir.MemoryRip, data.payload).data; - op1 = .{ .mem = Mir.MemoryRip.decode(rip) }; - }, - else => unreachable, - } - - const mnemonic: Instruction.Mnemonic = switch (op1.mem.bitSize()) { - 64 => .cmpxchg8b, - 128 => .cmpxchg16b, - else => unreachable, - }; - - return emit.encode(mnemonic, .{ - .prefix = switch (ops) { - .m_sib, .m_rip => .none, - .lock_m_sib, .lock_m_rip => .lock, - else => unreachable, - }, - .op1 = op1, - }); -} - -fn mirMovMoffs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - const payload = emit.mir.instructions.items(.data)[inst].payload; - const moffs = emit.mir.extraData(Mir.MemoryMoffs, payload).data; - const seg = @intToEnum(Register, moffs.seg); - const offset = moffs.decodeOffset(); - switch (ops) { - .rax_moffs => { - try emit.encode(.mov, .{ - .op1 = .{ .reg = .rax }, - .op2 = .{ .mem = Memory.moffs(seg, offset) }, - }); - }, - .moffs_rax, .lock_moffs_rax => { - try emit.encode(.mov, .{ - .prefix = switch (ops) { - .moffs_rax => .none, - .lock_moffs_rax => .lock, - else => unreachable, - }, - .op1 = .{ .mem = Memory.moffs(seg, offset) }, - .op2 = .{ .reg = .rax }, - }); - }, - else => unreachable, - } -} - -fn mirMovsx(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - const data = emit.mir.instructions.items(.data)[inst]; - - var op1: Instruction.Operand = .none; - var op2: Instruction.Operand = .none; - switch (ops) { - .rr => { - op1 = .{ .reg = data.rr.r1 }; - op2 = .{ .reg = data.rr.r2 }; - }, - .rm_sib => { - const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data; - op1 = .{ .reg = data.rx.r }; - op2 = .{ .mem = Mir.MemorySib.decode(msib) }; - }, - .rm_rip => { - const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data; - op1 = .{ .reg = data.rx.r }; - op2 = .{ .mem = Mir.MemoryRip.decode(mrip) }; - }, - else => unreachable, // TODO - } - - const mnemonic: Instruction.Mnemonic = switch (op1.bitSize()) { - 32, 64 => if (op2.bitSize() == 32) .movsxd else .movsx, - else => .movsx, - }; - - return emit.encode(mnemonic, .{ - .op1 = op1, - .op2 = op2, - }); -} - -fn mnemonicFromConditionCode(comptime basename: []const u8, cc: bits.Condition) Instruction.Mnemonic { - return switch (cc) { - inline else => |comptime_cc| @field(Instruction.Mnemonic, basename ++ @tagName(comptime_cc)), - }; -} - -fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - switch (ops) { - .rr_cc => { - const data = emit.mir.instructions.items(.data)[inst].rr_cc; - const mnemonic = mnemonicFromConditionCode("cmov", data.cc); - return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r1 }, - .op2 = .{ .reg = data.r2 }, - }); - }, - .rm_sib_cc => { - const data = emit.mir.instructions.items(.data)[inst].rx_cc; - const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data; - const mnemonic = mnemonicFromConditionCode("cmov", data.cc); - return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r }, - .op2 = .{ .mem = Mir.MemorySib.decode(extra) }, - }); - }, - .rm_rip_cc => { - const data = emit.mir.instructions.items(.data)[inst].rx_cc; - const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data; - const mnemonic = mnemonicFromConditionCode("cmov", data.cc); - return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r }, - .op2 = .{ .mem = Mir.MemoryRip.decode(extra) }, - }); - }, - else => unreachable, - } -} - -fn mirSetcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - switch (ops) { - .r_cc => { - const data = emit.mir.instructions.items(.data)[inst].r_cc; - const mnemonic = mnemonicFromConditionCode("set", data.cc); - return emit.encode(mnemonic, .{ - .op1 = .{ .reg = data.r }, - }); - }, - .m_sib_cc => { - const data = emit.mir.instructions.items(.data)[inst].x_cc; - const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data; - const mnemonic = mnemonicFromConditionCode("set", data.cc); - return emit.encode(mnemonic, .{ - .op1 = .{ .mem = Mir.MemorySib.decode(extra) }, - }); - }, - .m_rip_cc => { - const data = emit.mir.instructions.items(.data)[inst].x_cc; - const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data; - const mnemonic = mnemonicFromConditionCode("set", data.cc); - return emit.encode(mnemonic, .{ - .op1 = .{ .mem = Mir.MemoryRip.decode(extra) }, - }); - }, - else => unreachable, // TODO - } -} - -fn mirJcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - switch (ops) { - .inst_cc => { - const data = emit.mir.instructions.items(.data)[inst].inst_cc; - const mnemonic = mnemonicFromConditionCode("j", data.cc); - const source = emit.code.items.len; - try emit.encode(mnemonic, .{ - .op1 = .{ .imm = Immediate.s(0) }, - }); - try emit.relocs.append(emit.bin_file.allocator, .{ - .source = source, - .target = data.inst, - .offset = emit.code.items.len - 4, - .length = 6, - }); - }, - else => unreachable, // TODO - } -} - -fn mirJmpReloc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const target = emit.mir.instructions.items(.data)[inst].inst; - const source = emit.code.items.len; - try emit.encode(.jmp, .{ - .op1 = .{ .imm = Immediate.s(0) }, - }); - try emit.relocs.append(emit.bin_file.allocator, .{ - .source = source, - .target = target, - .offset = emit.code.items.len - 4, - .length = 5, - }); -} - -fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const relocation = emit.mir.instructions.items(.data)[inst].relocation; - - const offset = blk: { - try emit.encode(.call, .{ - .op1 = .{ .imm = Immediate.s(0) }, - }); - break :blk @intCast(u32, emit.code.items.len) - 4; - }; - - if (emit.bin_file.cast(link.File.MachO)) |macho_file| { - // Add relocation to the decl. - const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; - const target = macho_file.getGlobalByIndex(relocation.sym_index); - try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ - .type = @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), - .target = target, - .offset = offset, - .addend = 0, - .pcrel = true, - .length = 2, - }); - } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { - // Add relocation to the decl. - const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; - const target = coff_file.getGlobalByIndex(relocation.sym_index); - try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ - .type = .direct, - .target = target, - .offset = offset, - .addend = 0, - .pcrel = true, - .length = 2, - }); - } else { - return emit.fail("TODO implement call_extern for linking backends different than MachO and COFF", .{}); - } -} - -fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { - const payload = emit.mir.instructions.items(.data)[inst].payload; - const save_reg_list = emit.mir.extraData(Mir.SaveRegisterList, payload).data; - const base = @intToEnum(Register, save_reg_list.base_reg); - var disp: i32 = -@intCast(i32, save_reg_list.stack_end); - const reg_list = Mir.RegisterList.fromInt(save_reg_list.register_list); - const callee_preserved_regs = abi.getCalleePreservedRegs(emit.target.*); - for (callee_preserved_regs) |reg| { - if (reg_list.isSet(callee_preserved_regs, reg)) { - const op1: Instruction.Operand = .{ .mem = Memory.sib(.qword, .{ - .base = base, - .disp = disp, - }) }; - const op2: Instruction.Operand = .{ .reg = reg }; - switch (tag) { - .push => try emit.encode(.mov, .{ - .op1 = op1, - .op2 = op2, - }), - .pop => try emit.encode(.mov, .{ - .op1 = op2, - .op2 = op1, - }), - else => unreachable, - } - disp += 8; - } - } -} - -fn mirLeaLinker(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const ops = emit.mir.instructions.items(.ops)[inst]; - const payload = emit.mir.instructions.items(.data)[inst].payload; - const metadata = emit.mir.extraData(Mir.LeaRegisterReloc, payload).data; - const reg = @intToEnum(Register, metadata.reg); - - try emit.encode(.lea, .{ - .op1 = .{ .reg = reg }, - .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, - }); - - const end_offset = emit.code.items.len; - - if (emit.bin_file.cast(link.File.MachO)) |macho_file| { - const reloc_type = switch (ops) { - .got_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_GOT), - .direct_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), - else => unreachable, - }; - const atom_index = macho_file.getAtomIndexForSymbol(.{ - .sym_index = metadata.atom_index, - .file = null, - }).?; - try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ - .type = reloc_type, - .target = .{ .sym_index = metadata.sym_index, .file = null }, - .offset = @intCast(u32, end_offset - 4), - .addend = 0, - .pcrel = true, - .length = 2, - }); - } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { - const atom_index = coff_file.getAtomIndexForSymbol(.{ - .sym_index = metadata.atom_index, - .file = null, - }).?; - try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ - .type = switch (ops) { - .got_reloc => .got, - .direct_reloc => .direct, - .import_reloc => .import, - else => unreachable, - }, - .target = switch (ops) { - .got_reloc, .direct_reloc => .{ .sym_index = metadata.sym_index, .file = null }, - .import_reloc => coff_file.getGlobalByIndex(metadata.sym_index), - else => unreachable, - }, - .offset = @intCast(u32, end_offset - 4), - .addend = 0, - .pcrel = true, - .length = 2, - }); - } else { - return emit.fail("TODO implement lea reg, [rip + reloc] for linking backends different than MachO", .{}); - } -} - -fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - const payload = emit.mir.instructions.items(.data)[inst].payload; - const dbg_line_column = emit.mir.extraData(Mir.DbgLineColumn, payload).data; - log.debug("mirDbgLine", .{}); - try emit.dbgAdvancePCAndLine(dbg_line_column.line, dbg_line_column.column); -} - -fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void { +fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void { const delta_line = @intCast(i32, line) - @intCast(i32, emit.prev_di_line); const delta_pc: usize = emit.code.items.len - emit.prev_di_pc; log.debug(" (advance pc={d} and line={d})", .{ delta_line, delta_pc }); @@ -756,7 +209,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void { .plan9 => |dbg_out| { if (delta_pc <= 0) return; // only do this when the pc changes // we have already checked the target in the linker to make sure it is compatable - const quant = @import("../../link/Plan9/aout.zig").getPCQuant(emit.target.cpu.arch) catch unreachable; + const quant = @import("../../link/Plan9/aout.zig").getPCQuant(emit.lower.target.cpu.arch) catch unreachable; // increasing the line number try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line); @@ -792,34 +245,12 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void { } } -fn mirDbgPrologueEnd(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - _ = inst; - switch (emit.debug_output) { - .dwarf => |dw| { - try dw.setPrologueEnd(); - log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{ - emit.prev_di_line, - emit.prev_di_column, - }); - try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column); - }, - .plan9 => {}, - .none => {}, - } -} +const link = @import("../../link.zig"); +const log = std.log.scoped(.emit); +const mem = std.mem; +const std = @import("std"); -fn mirDbgEpilogueBegin(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { - _ = inst; - switch (emit.debug_output) { - .dwarf => |dw| { - try dw.setEpilogueBegin(); - log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{ - emit.prev_di_line, - emit.prev_di_column, - }); - try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column); - }, - .plan9 => {}, - .none => {}, - } -} +const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; +const Emit = @This(); +const Lower = @import("Lower.zig"); +const Mir = @import("Mir.zig"); diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index de669a9f8d..1361570405 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -7,30 +7,32 @@ const math = std.math; const bits = @import("bits.zig"); const encoder = @import("encoder.zig"); const Instruction = encoder.Instruction; +const Operand = Instruction.Operand; +const Prefix = Instruction.Prefix; const Register = bits.Register; const Rex = encoder.Rex; const LegacyPrefixes = encoder.LegacyPrefixes; -const table = @import("encodings.zig").table; - mnemonic: Mnemonic, -op_en: OpEn, -op1: Op, -op2: Op, -op3: Op, -op4: Op, -opc_len: u3, -opc: [7]u8, -modrm_ext: u3, -mode: Mode, +data: Data, -pub fn findByMnemonic(mnemonic: Mnemonic, args: Instruction.Init) !?Encoding { - const input_op1 = Op.fromOperand(args.op1); - const input_op2 = Op.fromOperand(args.op2); - const input_op3 = Op.fromOperand(args.op3); - const input_op4 = Op.fromOperand(args.op4); +const Data = struct { + op_en: OpEn, + ops: [4]Op, + opc_len: u3, + opc: [7]u8, + modrm_ext: u3, + mode: Mode, +}; + +pub fn findByMnemonic( + prefix: Instruction.Prefix, + mnemonic: Mnemonic, + ops: []const Instruction.Operand, +) !?Encoding { + var input_ops = [1]Op{.none} ** 4; + for (input_ops[0..ops.len], ops) |*input_op, op| input_op.* = Op.fromOperand(op); - const ops = &[_]Instruction.Operand{ args.op1, args.op2, args.op3, args.op4 }; const rex_required = for (ops) |op| switch (op) { .reg => |r| switch (r) { .spl, .bpl, .sil, .dil => break true, @@ -60,88 +62,29 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: Instruction.Init) !?Encoding { if ((rex_required or rex_extended) and rex_invalid) return error.CannotEncode; - // TODO work out what is the maximum number of variants we can actually find in one swoop. - var candidates: [10]Encoding = undefined; - var count: usize = 0; - for (table) |entry| { - var enc = Encoding{ - .mnemonic = entry[0], - .op_en = entry[1], - .op1 = entry[2], - .op2 = entry[3], - .op3 = entry[4], - .op4 = entry[5], - .opc_len = @intCast(u3, entry[6].len), - .opc = undefined, - .modrm_ext = entry[7], - .mode = entry[8], - }; - std.mem.copy(u8, &enc.opc, entry[6]); - if (enc.mnemonic == mnemonic and - input_op1.isSubset(enc.op1, enc.mode) and - input_op2.isSubset(enc.op2, enc.mode) and - input_op3.isSubset(enc.op3, enc.mode) and - input_op4.isSubset(enc.op4, enc.mode)) - { - if (rex_required) { - switch (enc.mode) { - .rex, .long => { - candidates[count] = enc; - count += 1; - }, - else => {}, - } - } else { - if (enc.mode != .rex) { - candidates[count] = enc; - count += 1; - } - } + var shortest_enc: ?Encoding = null; + var shortest_len: ?usize = null; + next: for (mnemonic_to_encodings_map[@enumToInt(mnemonic)]) |data| { + switch (data.mode) { + .rex => if (!rex_required) continue, + .long => {}, + else => if (rex_required) continue, } + for (input_ops, data.ops) |input_op, data_op| + if (!input_op.isSubset(data_op, data.mode)) continue :next; + + const enc = Encoding{ .mnemonic = mnemonic, .data = data }; + if (shortest_enc) |previous_shortest_enc| { + const len = estimateInstructionLength(prefix, enc, ops); + const previous_shortest_len = shortest_len orelse + estimateInstructionLength(prefix, previous_shortest_enc, ops); + if (len < previous_shortest_len) { + shortest_enc = enc; + shortest_len = len; + } else shortest_len = previous_shortest_len; + } else shortest_enc = enc; } - - if (count == 0) return null; - if (count == 1) return candidates[0]; - - const EncodingLength = struct { - fn estimate(encoding: Encoding, params: Instruction.Init) usize { - var inst = Instruction{ - .op1 = params.op1, - .op2 = params.op2, - .op3 = params.op3, - .op4 = params.op4, - .prefix = params.prefix, - .encoding = encoding, - }; - var cwriter = std.io.countingWriter(std.io.null_writer); - inst.encode(cwriter.writer()) catch unreachable; // Not allowed to fail here unless OOM. - return @intCast(usize, cwriter.bytes_written); - } - }; - - var shortest_encoding: ?struct { - index: usize, - len: usize, - } = null; - var i: usize = 0; - while (i < count) : (i += 1) { - const candidate = candidates[i]; - switch (candidate.mode) { - .long, .rex => if (rex_invalid) return error.CannotEncode, - else => {}, - } - - const len = EncodingLength.estimate(candidate, args); - const current = shortest_encoding orelse { - shortest_encoding = .{ .index = i, .len = len }; - continue; - }; - if (len < current.len) { - shortest_encoding = .{ .index = i, .len = len }; - } - } - - return candidates[shortest_encoding.?.index]; + return shortest_enc; } /// Returns first matching encoding by opcode. @@ -149,57 +92,45 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct { legacy: LegacyPrefixes, rex: Rex, }, modrm_ext: ?u3) ?Encoding { - for (table) |entry| { - const enc = Encoding{ - .mnemonic = entry[0], - .op_en = entry[1], - .op1 = entry[2], - .op2 = entry[3], - .op3 = entry[4], - .op4 = entry[5], - .opc_len = entry[6], - .opc = .{ entry[7], entry[8], entry[9] }, - .modrm_ext = entry[10], - .mode = entry[11], - }; - const match = match: { - if (modrm_ext) |ext| { - break :match ext == enc.modrm_ext and std.mem.eql(u8, enc.opcode(), opc); + for (mnemonic_to_encodings_map, 0..) |encs, mnemonic_int| for (encs) |data| { + const enc = Encoding{ .mnemonic = @intToEnum(Mnemonic, mnemonic_int), .data = data }; + if (modrm_ext) |ext| if (ext != data.modrm_ext) continue; + if (!std.mem.eql(u8, opc, enc.opcode())) continue; + if (prefixes.rex.w) { + switch (data.mode) { + .short, .fpu, .sse, .sse2, .sse4_1, .none => continue, + .long, .rex => {}, } - break :match std.mem.eql(u8, enc.opcode(), opc); - }; - if (match) { - if (prefixes.rex.w) { - switch (enc.mode) { - .fpu, .sse, .sse2, .sse4_1, .none => {}, - .long, .rex => return enc, - } - } else if (prefixes.rex.present and !prefixes.rex.isSet()) { - if (enc.mode == .rex) return enc; - } else if (prefixes.legacy.prefix_66) { - switch (enc.operandBitSize()) { - 16 => return enc, + } else if (prefixes.rex.present and !prefixes.rex.isSet()) { + switch (data.mode) { + .rex => {}, + else => continue, + } + } else if (prefixes.legacy.prefix_66) { + switch (enc.operandBitSize()) { + 16 => {}, + else => continue, + } + } else { + switch (data.mode) { + .none => switch (enc.operandBitSize()) { + 16 => continue, else => {}, - } - } else { - if (enc.mode == .none) { - switch (enc.operandBitSize()) { - 16 => {}, - else => return enc, - } - } + }, + else => continue, } } - } + return enc; + }; return null; } pub fn opcode(encoding: *const Encoding) []const u8 { - return encoding.opc[0..encoding.opc_len]; + return encoding.data.opc[0..encoding.data.opc_len]; } pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 { - const prefix = encoding.opc[0]; + const prefix = encoding.data.opc[0]; return switch (prefix) { 0x66, 0xf2, 0xf3 => prefix, else => null, @@ -207,27 +138,27 @@ pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 { } pub fn modRmExt(encoding: Encoding) u3 { - return switch (encoding.op_en) { - .m, .mi, .m1, .mc => encoding.modrm_ext, + return switch (encoding.data.op_en) { + .m, .mi, .m1, .mc => encoding.data.modrm_ext, else => unreachable, }; } pub fn operandBitSize(encoding: Encoding) u64 { - switch (encoding.mode) { + switch (encoding.data.mode) { .short => return 16, .long => return 64, else => {}, } - const bit_size: u64 = switch (encoding.op_en) { - .np => switch (encoding.op1) { + const bit_size: u64 = switch (encoding.data.op_en) { + .np => switch (encoding.data.ops[0]) { .o16 => 16, .o32 => 32, .o64 => 64, else => 32, }, - .td => encoding.op2.bitSize(), - else => encoding.op1.bitSize(), + .td => encoding.data.ops[1].bitSize(), + else => encoding.data.ops[0].bitSize(), }; return bit_size; } @@ -240,7 +171,7 @@ pub fn format( ) !void { _ = options; _ = fmt; - switch (encoding.mode) { + switch (encoding.data.mode) { .long => try writer.writeAll("REX.W + "), else => {}, } @@ -249,10 +180,10 @@ pub fn format( try writer.print("{x:0>2} ", .{byte}); } - switch (encoding.op_en) { + switch (encoding.data.op_en) { .np, .fd, .td, .i, .zi, .d => {}, .o, .oi => { - const tag = switch (encoding.op1) { + const tag = switch (encoding.data.ops[0]) { .r8 => "rb", .r16 => "rw", .r32 => "rd", @@ -265,12 +196,12 @@ pub fn format( .mr, .rm, .rmi, .mri, .mrc => try writer.writeAll("/r "), } - switch (encoding.op_en) { + switch (encoding.data.op_en) { .i, .d, .zi, .oi, .mi, .rmi, .mri => { - const op = switch (encoding.op_en) { - .i, .d => encoding.op1, - .zi, .oi, .mi => encoding.op2, - .rmi, .mri => encoding.op3, + const op = switch (encoding.data.op_en) { + .i, .d => encoding.data.ops[0], + .zi, .oi, .mi => encoding.data.ops[1], + .rmi, .mri => encoding.data.ops[2], else => unreachable, }; const tag = switch (op) { @@ -290,13 +221,12 @@ pub fn format( try writer.print("{s} ", .{@tagName(encoding.mnemonic)}); - const ops = &[_]Op{ encoding.op1, encoding.op2, encoding.op3, encoding.op4 }; - for (ops) |op| switch (op) { + for (encoding.data.ops) |op| switch (op) { .none, .o16, .o32, .o64 => break, else => try writer.print("{s} ", .{@tagName(op)}), }; - const op_en = switch (encoding.op_en) { + const op_en = switch (encoding.data.op_en) { .zi => .i, else => |op_en| op_en, }; @@ -604,3 +534,53 @@ pub const Mode = enum { sse2, sse4_1, }; + +fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Operand) usize { + var inst = Instruction{ + .prefix = prefix, + .encoding = encoding, + .ops = [1]Operand{.none} ** 4, + }; + std.mem.copy(Operand, &inst.ops, ops); + + var cwriter = std.io.countingWriter(std.io.null_writer); + inst.encode(cwriter.writer()) catch unreachable; // Not allowed to fail here unless OOM. + return @intCast(usize, cwriter.bytes_written); +} + +const mnemonic_to_encodings_map = init: { + @setEvalBranchQuota(100_000); + const encodings = @import("encodings.zig"); + var entries = encodings.table; + std.sort.sort(encodings.Entry, &entries, {}, struct { + fn lessThan(_: void, lhs: encodings.Entry, rhs: encodings.Entry) bool { + return @enumToInt(lhs[0]) < @enumToInt(rhs[0]); + } + }.lessThan); + var data_storage: [entries.len]Data = undefined; + var mnemonic_map: [@typeInfo(Mnemonic).Enum.fields.len][]const Data = undefined; + var mnemonic_int = 0; + var mnemonic_start = 0; + for (&data_storage, entries, 0..) |*data, entry, data_index| { + data.* = .{ + .op_en = entry[1], + .ops = undefined, + .opc_len = entry[3].len, + .opc = undefined, + .modrm_ext = entry[4], + .mode = entry[5], + }; + std.mem.copy(Op, &data.ops, entry[2]); + std.mem.copy(u8, &data.opc, entry[3]); + + while (mnemonic_int < @enumToInt(entry[0])) : (mnemonic_int += 1) { + mnemonic_map[mnemonic_int] = data_storage[mnemonic_start..data_index]; + mnemonic_start = data_index; + } + } + while (mnemonic_int < mnemonic_map.len) : (mnemonic_int += 1) { + mnemonic_map[mnemonic_int] = data_storage[mnemonic_start..]; + mnemonic_start = data_storage.len; + } + break :init mnemonic_map; +}; diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig new file mode 100644 index 0000000000..f4d9db57e8 --- /dev/null +++ b/src/arch/x86_64/Lower.zig @@ -0,0 +1,465 @@ +//! This file contains the functionality for lowering x86_64 MIR to Instructions + +allocator: Allocator, +mir: Mir, +target: *const std.Target, +err_msg: ?*ErrorMsg = null, +src_loc: Module.SrcLoc, +result: [ + std.mem.max(usize, &.{ + abi.Win64.callee_preserved_regs.len, + abi.SysV.callee_preserved_regs.len, + }) +]Instruction = undefined, +result_len: usize = undefined, + +pub const Error = error{ + OutOfMemory, + LowerFail, + InvalidInstruction, + CannotEncode, +}; + +/// The returned slice is overwritten by the next call to lowerMir. +pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction { + lower.result = undefined; + errdefer lower.result = undefined; + lower.result_len = 0; + defer lower.result_len = undefined; + + switch (inst.tag) { + .adc, + .add, + .@"and", + .bsf, + .bsr, + .bswap, + .bt, + .btc, + .btr, + .bts, + .call, + .cbw, + .cwde, + .cdqe, + .cwd, + .cdq, + .cqo, + .cmp, + .cmpxchg, + .div, + .fisttp, + .fld, + .idiv, + .imul, + .int3, + .jmp, + .lea, + .lfence, + .lzcnt, + .mfence, + .mov, + .movbe, + .movzx, + .mul, + .neg, + .nop, + .not, + .@"or", + .pop, + .popcnt, + .push, + .rcl, + .rcr, + .ret, + .rol, + .ror, + .sal, + .sar, + .sbb, + .sfence, + .shl, + .shld, + .shr, + .shrd, + .sub, + .syscall, + .@"test", + .tzcnt, + .ud2, + .xadd, + .xchg, + .xor, + + .addss, + .cmpss, + .divss, + .maxss, + .minss, + .movss, + .mulss, + .roundss, + .subss, + .ucomiss, + .addsd, + .cmpsd, + .divsd, + .maxsd, + .minsd, + .movsd, + .mulsd, + .roundsd, + .subsd, + .ucomisd, + => try lower.mirGeneric(inst), + + .cmps, + .lods, + .movs, + .scas, + .stos, + => try lower.mirString(inst), + + .cmpxchgb => try lower.mirCmpxchgBytes(inst), + + .jmp_reloc => try lower.emit(.none, .jmp, &.{.{ .imm = Immediate.s(0) }}), + + .call_extern => try lower.emit(.none, .call, &.{.{ .imm = Immediate.s(0) }}), + + .lea_linker => try lower.mirLeaLinker(inst), + + .mov_moffs => try lower.mirMovMoffs(inst), + + .movsx => try lower.mirMovsx(inst), + .cmovcc => try lower.mirCmovcc(inst), + .setcc => try lower.mirSetcc(inst), + .jcc => try lower.emit(.none, mnem_cc(.j, inst.data.inst_cc.cc), &.{.{ .imm = Immediate.s(0) }}), + + .push_regs, .pop_regs => try lower.mirPushPopRegisterList(inst), + + .dbg_line, + .dbg_prologue_end, + .dbg_epilogue_begin, + .dead, + => {}, + } + + return lower.result[0..lower.result_len]; +} + +pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { + @setCold(true); + assert(lower.err_msg == null); + lower.err_msg = try ErrorMsg.create(lower.allocator, lower.src_loc, format, args); + return error.LowerFail; +} + +fn mnem_cc(comptime base: @Type(.EnumLiteral), cc: bits.Condition) Mnemonic { + return switch (cc) { + inline else => |c| @field(Mnemonic, @tagName(base) ++ @tagName(c)), + }; +} + +fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { + return switch (ops) { + .rri_s, + .ri_s, + .i_s, + .mi_sib_s, + .mi_rip_s, + .lock_mi_sib_s, + .lock_mi_rip_s, + => Immediate.s(@bitCast(i32, i)), + + .rri_u, + .ri_u, + .i_u, + .mi_sib_u, + .mi_rip_u, + .lock_mi_sib_u, + .lock_mi_rip_u, + .mri_sib, + .mri_rip, + => Immediate.u(i), + + .ri64 => Immediate.u(lower.mir.extraData(Mir.Imm64, i).data.decode()), + + else => unreachable, + }; +} + +fn mem(lower: Lower, ops: Mir.Inst.Ops, payload: u32) Memory { + return switch (ops) { + .rm_sib, + .rm_sib_cc, + .m_sib, + .m_sib_cc, + .mi_sib_u, + .mi_sib_s, + .mr_sib, + .mrr_sib, + .mri_sib, + .lock_m_sib, + .lock_mi_sib_u, + .lock_mi_sib_s, + .lock_mr_sib, + => lower.mir.extraData(Mir.MemorySib, payload).data.decode(), + + .rm_rip, + .rm_rip_cc, + .m_rip, + .m_rip_cc, + .mi_rip_u, + .mi_rip_s, + .mr_rip, + .mrr_rip, + .mri_rip, + .lock_m_rip, + .lock_mi_rip_u, + .lock_mi_rip_s, + .lock_mr_rip, + => lower.mir.extraData(Mir.MemoryRip, payload).data.decode(), + + .rax_moffs, + .moffs_rax, + .lock_moffs_rax, + => lower.mir.extraData(Mir.MemoryMoffs, payload).data.decode(), + + else => unreachable, + }; +} + +fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void { + lower.result[lower.result_len] = try Instruction.new(prefix, mnemonic, ops); + lower.result_len += 1; +} + +fn mirGeneric(lower: *Lower, inst: Mir.Inst) Error!void { + try lower.emit(switch (inst.ops) { + else => .none, + .lock_m_sib, + .lock_m_rip, + .lock_mi_sib_u, + .lock_mi_rip_u, + .lock_mi_sib_s, + .lock_mi_rip_s, + .lock_mr_sib, + .lock_mr_rip, + .lock_moffs_rax, + => .lock, + }, switch (inst.tag) { + inline else => |tag| if (@hasField(Mnemonic, @tagName(tag))) + @field(Mnemonic, @tagName(tag)) + else + unreachable, + }, switch (inst.ops) { + .none => &.{}, + .i_s, .i_u => &.{ + .{ .imm = lower.imm(inst.ops, inst.data.i) }, + }, + .r => &.{ + .{ .reg = inst.data.r }, + }, + .rr => &.{ + .{ .reg = inst.data.rr.r1 }, + .{ .reg = inst.data.rr.r2 }, + }, + .rrr => &.{ + .{ .reg = inst.data.rrr.r1 }, + .{ .reg = inst.data.rrr.r2 }, + .{ .reg = inst.data.rrr.r3 }, + }, + .ri_s, .ri_u => &.{ + .{ .reg = inst.data.ri.r }, + .{ .imm = lower.imm(inst.ops, inst.data.ri.i) }, + }, + .ri64 => &.{ + .{ .reg = inst.data.rx.r }, + .{ .imm = lower.imm(inst.ops, inst.data.rx.payload) }, + }, + .rri_s, .rri_u => &.{ + .{ .reg = inst.data.rri.r1 }, + .{ .reg = inst.data.rri.r2 }, + .{ .imm = lower.imm(inst.ops, inst.data.rri.i) }, + }, + .m_sib, .lock_m_sib, .m_rip, .lock_m_rip => &.{ + .{ .mem = lower.mem(inst.ops, inst.data.payload) }, + }, + .mi_sib_s, + .lock_mi_sib_s, + .mi_sib_u, + .lock_mi_sib_u, + .mi_rip_u, + .lock_mi_rip_u, + .mi_rip_s, + .lock_mi_rip_s, + => &.{ + .{ .mem = lower.mem(inst.ops, inst.data.ix.payload) }, + .{ .imm = lower.imm(inst.ops, inst.data.ix.i) }, + }, + .rm_sib, .rm_rip => &.{ + .{ .reg = inst.data.rx.r }, + .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, + }, + .mr_sib, .lock_mr_sib, .mr_rip, .lock_mr_rip => &.{ + .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, + .{ .reg = inst.data.rx.r }, + }, + .mrr_sib, .mrr_rip => &.{ + .{ .mem = lower.mem(inst.ops, inst.data.rrx.payload) }, + .{ .reg = inst.data.rrx.r1 }, + .{ .reg = inst.data.rrx.r2 }, + }, + .mri_sib, .mri_rip => &.{ + .{ .mem = lower.mem(inst.ops, inst.data.rix.payload) }, + .{ .reg = inst.data.rix.r }, + .{ .imm = lower.imm(inst.ops, inst.data.rix.i) }, + }, + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + }); +} + +fn mirString(lower: *Lower, inst: Mir.Inst) Error!void { + switch (inst.ops) { + .string => try lower.emit(switch (inst.data.string.repeat) { + inline else => |repeat| @field(Prefix, @tagName(repeat)), + }, switch (inst.tag) { + inline .cmps, .lods, .movs, .scas, .stos => |tag| switch (inst.data.string.width) { + inline else => |width| @field(Mnemonic, @tagName(tag) ++ @tagName(width)), + }, + else => unreachable, + }, &.{}), + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + } +} + +fn mirCmpxchgBytes(lower: *Lower, inst: Mir.Inst) Error!void { + const ops: [1]Operand = switch (inst.ops) { + .m_sib, .lock_m_sib, .m_rip, .lock_m_rip => .{ + .{ .mem = lower.mem(inst.ops, inst.data.payload) }, + }, + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + }; + try lower.emit(switch (inst.ops) { + .m_sib, .m_rip => .none, + .lock_m_sib, .lock_m_rip => .lock, + else => unreachable, + }, switch (@divExact(ops[0].bitSize(), 8)) { + 8 => .cmpxchg8b, + 16 => .cmpxchg16b, + else => return lower.fail("invalid operand for {s}", .{@tagName(inst.tag)}), + }, &ops); +} + +fn mirMovMoffs(lower: *Lower, inst: Mir.Inst) Error!void { + try lower.emit(switch (inst.ops) { + .rax_moffs, .moffs_rax => .none, + .lock_moffs_rax => .lock, + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + }, .mov, switch (inst.ops) { + .rax_moffs => &.{ + .{ .reg = .rax }, + .{ .mem = lower.mem(inst.ops, inst.data.payload) }, + }, + .moffs_rax, .lock_moffs_rax => &.{ + .{ .mem = lower.mem(inst.ops, inst.data.payload) }, + .{ .reg = .rax }, + }, + else => unreachable, + }); +} + +fn mirMovsx(lower: *Lower, inst: Mir.Inst) Error!void { + const ops: [2]Operand = switch (inst.ops) { + .rr => .{ + .{ .reg = inst.data.rr.r1 }, + .{ .reg = inst.data.rr.r2 }, + }, + .rm_sib, .rm_rip => .{ + .{ .reg = inst.data.rx.r }, + .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, + }, + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + }; + try lower.emit(.none, switch (ops[0].bitSize()) { + 32, 64 => switch (ops[1].bitSize()) { + 32 => .movsxd, + else => .movsx, + }, + else => .movsx, + }, &ops); +} + +fn mirCmovcc(lower: *Lower, inst: Mir.Inst) Error!void { + switch (inst.ops) { + .rr_cc => try lower.emit(.none, mnem_cc(.cmov, inst.data.rr_cc.cc), &.{ + .{ .reg = inst.data.rr_cc.r1 }, + .{ .reg = inst.data.rr_cc.r2 }, + }), + .rm_sib_cc, .rm_rip_cc => try lower.emit(.none, mnem_cc(.cmov, inst.data.rx_cc.cc), &.{ + .{ .reg = inst.data.rx_cc.r }, + .{ .mem = lower.mem(inst.ops, inst.data.rx_cc.payload) }, + }), + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + } +} + +fn mirSetcc(lower: *Lower, inst: Mir.Inst) Error!void { + switch (inst.ops) { + .r_cc => try lower.emit(.none, mnem_cc(.set, inst.data.r_cc.cc), &.{ + .{ .reg = inst.data.r_cc.r }, + }), + .m_sib_cc, .m_rip_cc => try lower.emit(.none, mnem_cc(.set, inst.data.x_cc.cc), &.{ + .{ .mem = lower.mem(inst.ops, inst.data.x_cc.payload) }, + }), + else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), + } +} + +fn mirPushPopRegisterList(lower: *Lower, inst: Mir.Inst) Error!void { + const save_reg_list = lower.mir.extraData(Mir.SaveRegisterList, inst.data.payload).data; + const base = @intToEnum(Register, save_reg_list.base_reg); + var disp: i32 = -@intCast(i32, save_reg_list.stack_end); + const reg_list = Mir.RegisterList.fromInt(save_reg_list.register_list); + const callee_preserved_regs = abi.getCalleePreservedRegs(lower.target.*); + for (callee_preserved_regs) |callee_preserved_reg| { + if (!reg_list.isSet(callee_preserved_regs, callee_preserved_reg)) continue; + const reg_op = Operand{ .reg = callee_preserved_reg }; + const mem_op = Operand{ .mem = Memory.sib(.qword, .{ .base = base, .disp = disp }) }; + try lower.emit(.none, .mov, switch (inst.tag) { + .push_regs => &.{ mem_op, reg_op }, + .pop_regs => &.{ reg_op, mem_op }, + else => unreachable, + }); + disp += 8; + } +} + +fn mirLeaLinker(lower: *Lower, inst: Mir.Inst) Error!void { + const metadata = lower.mir.extraData(Mir.LeaRegisterReloc, inst.data.payload).data; + const reg = @intToEnum(Register, metadata.reg); + try lower.emit(.none, .lea, &.{ + .{ .reg = reg }, + .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, + }); +} + +const abi = @import("abi.zig"); +const assert = std.debug.assert; +const bits = @import("bits.zig"); +const encoder = @import("encoder.zig"); +const std = @import("std"); + +const Air = @import("../../Air.zig"); +const Allocator = std.mem.Allocator; +const ErrorMsg = Module.ErrorMsg; +const Immediate = bits.Immediate; +const Instruction = encoder.Instruction; +const Lower = @This(); +const Memory = bits.Memory; +const Mir = @import("Mir.zig"); +const Mnemonic = Instruction.Mnemonic; +const Module = @import("../../Module.zig"); +const Operand = Instruction.Operand; +const Prefix = Instruction.Prefix; +const Register = bits.Register; diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index a6a4115814..0ceee6bac1 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -655,16 +655,19 @@ pub const MemoryMoffs = struct { msb: u32, lsb: u32, - pub fn encodeOffset(moffs: *MemoryMoffs, v: u64) void { - moffs.msb = @truncate(u32, v >> 32); - moffs.lsb = @truncate(u32, v); + pub fn encode(seg: Register, offset: u64) MemoryMoffs { + return .{ + .seg = @enumToInt(seg), + .msb = @truncate(u32, offset >> 32), + .lsb = @truncate(u32, offset >> 0), + }; } - pub fn decodeOffset(moffs: *const MemoryMoffs) u64 { - var res: u64 = 0; - res |= (@intCast(u64, moffs.msb) << 32); - res |= @intCast(u64, moffs.lsb); - return res; + pub fn decode(moffs: MemoryMoffs) Memory { + return .{ .moffs = .{ + .seg = @intToEnum(Register, moffs.seg), + .offset = @as(u64, moffs.msb) << 32 | @as(u64, moffs.lsb) << 0, + } }; } }; diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index 76ad26a9a0..b2a6b31749 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -515,7 +515,7 @@ pub const Memory = union(enum) { return switch (mem) { .rip => |r| r.ptr_size.bitSize(), .sib => |s| s.ptr_size.bitSize(), - .moffs => unreachable, + .moffs => 64, }; } }; diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 05f66062ac..e7e231c063 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -11,12 +11,9 @@ const Memory = bits.Memory; const Register = bits.Register; pub const Instruction = struct { - op1: Operand = .none, - op2: Operand = .none, - op3: Operand = .none, - op4: Operand = .none, prefix: Prefix = .none, encoding: Encoding, + ops: [4]Operand = .{.none} ** 4, pub const Mnemonic = Encoding.Mnemonic; @@ -107,102 +104,87 @@ pub const Instruction = struct { } }; - pub const Init = struct { - prefix: Prefix = .none, - op1: Operand = .none, - op2: Operand = .none, - op3: Operand = .none, - op4: Operand = .none, - }; - - pub fn new(mnemonic: Mnemonic, args: Init) !Instruction { - const encoding = (try Encoding.findByMnemonic(mnemonic, args)) orelse { + pub fn new(prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) !Instruction { + const encoding = (try Encoding.findByMnemonic(prefix, mnemonic, ops)) orelse { log.err("no encoding found for: {s} {s} {s} {s} {s} {s}", .{ - @tagName(args.prefix), + @tagName(prefix), @tagName(mnemonic), - @tagName(Encoding.Op.fromOperand(args.op1)), - @tagName(Encoding.Op.fromOperand(args.op2)), - @tagName(Encoding.Op.fromOperand(args.op3)), - @tagName(Encoding.Op.fromOperand(args.op4)), + @tagName(if (ops.len > 0) Encoding.Op.fromOperand(ops[0]) else .none), + @tagName(if (ops.len > 1) Encoding.Op.fromOperand(ops[1]) else .none), + @tagName(if (ops.len > 2) Encoding.Op.fromOperand(ops[2]) else .none), + @tagName(if (ops.len > 3) Encoding.Op.fromOperand(ops[3]) else .none), }); return error.InvalidInstruction; }; log.debug("selected encoding: {}", .{encoding}); - return .{ - .prefix = args.prefix, - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, + + var inst = Instruction{ + .prefix = prefix, .encoding = encoding, + .ops = [1]Operand{.none} ** 4, }; + std.mem.copy(Operand, &inst.ops, ops); + return inst; } pub fn fmtPrint(inst: Instruction, writer: anytype) !void { if (inst.prefix != .none) try writer.print("{s} ", .{@tagName(inst.prefix)}); try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)}); - const ops = [_]struct { Operand, Encoding.Op }{ - .{ inst.op1, inst.encoding.op1 }, - .{ inst.op2, inst.encoding.op2 }, - .{ inst.op3, inst.encoding.op3 }, - .{ inst.op4, inst.encoding.op4 }, - }; - for (&ops, 0..) |op, i| { - if (op[0] == .none) break; - if (i > 0) { - try writer.writeByte(','); - } + for (inst.ops, inst.encodings.ops, 0..) |op, enc, i| { + if (op == .none) break; + if (i > 0) try writer.writeByte(','); try writer.writeByte(' '); - try op[0].fmtPrint(op[1], writer); + try op.fmtPrint(enc, writer); } } pub fn encode(inst: Instruction, writer: anytype) !void { const encoder = Encoder(@TypeOf(writer)){ .writer = writer }; - const encoding = inst.encoding; + const enc = inst.encoding; + const data = enc.data; try inst.encodeLegacyPrefixes(encoder); try inst.encodeMandatoryPrefix(encoder); try inst.encodeRexPrefix(encoder); try inst.encodeOpcode(encoder); - switch (encoding.op_en) { + switch (data.op_en) { .np, .o => {}, - .i, .d => try encodeImm(inst.op1.imm, encoding.op1, encoder), - .zi, .oi => try encodeImm(inst.op2.imm, encoding.op2, encoder), - .fd => try encoder.imm64(inst.op2.mem.moffs.offset), - .td => try encoder.imm64(inst.op1.mem.moffs.offset), + .i, .d => try encodeImm(inst.ops[0].imm, data.ops[0], encoder), + .zi, .oi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder), + .fd => try encoder.imm64(inst.ops[1].mem.moffs.offset), + .td => try encoder.imm64(inst.ops[0].mem.moffs.offset), else => { - const mem_op = switch (encoding.op_en) { - .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.op1, - .rm, .rmi => inst.op2, + const mem_op = switch (data.op_en) { + .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.ops[0], + .rm, .rmi => inst.ops[1], else => unreachable, }; switch (mem_op) { .reg => |reg| { - const rm = switch (encoding.op_en) { - .m, .mi, .m1, .mc => encoding.modRmExt(), - .mr, .mri, .mrc => inst.op2.reg.lowEnc(), - .rm, .rmi => inst.op1.reg.lowEnc(), + const rm = switch (data.op_en) { + .m, .mi, .m1, .mc => enc.modRmExt(), + .mr, .mri, .mrc => inst.ops[1].reg.lowEnc(), + .rm, .rmi => inst.ops[0].reg.lowEnc(), else => unreachable, }; try encoder.modRm_direct(rm, reg.lowEnc()); }, .mem => |mem| { - const op = switch (encoding.op_en) { + const op = switch (data.op_en) { .m, .mi, .m1, .mc => .none, - .mr, .mri, .mrc => inst.op2, - .rm, .rmi => inst.op1, + .mr, .mri, .mrc => inst.ops[1], + .rm, .rmi => inst.ops[0], else => unreachable, }; - try encodeMemory(encoding, mem, op, encoder); + try encodeMemory(enc, mem, op, encoder); }, else => unreachable, } - switch (encoding.op_en) { - .mi => try encodeImm(inst.op2.imm, encoding.op2, encoder), - .rmi, .mri => try encodeImm(inst.op3.imm, encoding.op3, encoder), + switch (data.op_en) { + .mi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder), + .rmi, .mri => try encodeImm(inst.ops[2].imm, data.ops[2], encoder), else => {}, } }, @@ -214,15 +196,16 @@ pub const Instruction = struct { const first = @boolToInt(inst.encoding.mandatoryPrefix() != null); const final = opcode.len - 1; for (opcode[first..final]) |byte| try encoder.opcode_1byte(byte); - switch (inst.encoding.op_en) { - .o, .oi => try encoder.opcode_withReg(opcode[final], inst.op1.reg.lowEnc()), + switch (inst.encoding.data.op_en) { + .o, .oi => try encoder.opcode_withReg(opcode[final], inst.ops[0].reg.lowEnc()), else => try encoder.opcode_1byte(opcode[final]), } } fn encodeLegacyPrefixes(inst: Instruction, encoder: anytype) !void { const enc = inst.encoding; - const op_en = enc.op_en; + const data = enc.data; + const op_en = data.op_en; var legacy = LegacyPrefixes{}; @@ -233,7 +216,7 @@ pub const Instruction = struct { .rep, .repe, .repz => legacy.prefix_f3 = true, } - if (enc.mode == .none) { + if (data.mode == .none) { const bit_size = enc.operandBitSize(); if (bit_size == 16) { legacy.set16BitOverride(); @@ -242,17 +225,17 @@ pub const Instruction = struct { const segment_override: ?Register = switch (op_en) { .i, .zi, .o, .oi, .d, .np => null, - .fd => inst.op2.mem.base().?, - .td => inst.op1.mem.base().?, - .rm, .rmi => if (inst.op2.isSegmentRegister()) blk: { - break :blk switch (inst.op2) { + .fd => inst.ops[1].mem.base().?, + .td => inst.ops[0].mem.base().?, + .rm, .rmi => if (inst.ops[1].isSegmentRegister()) blk: { + break :blk switch (inst.ops[1]) { .reg => |r| r, .mem => |m| m.base().?, else => unreachable, }; } else null, - .m, .mi, .m1, .mc, .mr, .mri, .mrc => if (inst.op1.isSegmentRegister()) blk: { - break :blk switch (inst.op1) { + .m, .mi, .m1, .mc, .mr, .mri, .mrc => if (inst.ops[0].isSegmentRegister()) blk: { + break :blk switch (inst.ops[0]) { .reg => |r| r, .mem => |m| m.base().?, else => unreachable, @@ -267,19 +250,19 @@ pub const Instruction = struct { } fn encodeRexPrefix(inst: Instruction, encoder: anytype) !void { - const op_en = inst.encoding.op_en; + const op_en = inst.encoding.data.op_en; var rex = Rex{}; - rex.present = inst.encoding.mode == .rex; - rex.w = inst.encoding.mode == .long; + rex.present = inst.encoding.data.mode == .rex; + rex.w = inst.encoding.data.mode == .long; switch (op_en) { .np, .i, .zi, .fd, .td, .d => {}, - .o, .oi => rex.b = inst.op1.reg.isExtended(), + .o, .oi => rex.b = inst.ops[0].reg.isExtended(), .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc => { const r_op = switch (op_en) { - .rm, .rmi => inst.op1, - .mr, .mri, .mrc => inst.op2, + .rm, .rmi => inst.ops[0], + .mr, .mri, .mrc => inst.ops[1], else => null, }; if (r_op) |op| { @@ -287,8 +270,8 @@ pub const Instruction = struct { } const b_x_op = switch (op_en) { - .rm, .rmi => inst.op2, - .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.op1, + .rm, .rmi => inst.ops[1], + .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.ops[0], else => unreachable, }; switch (b_x_op) { @@ -827,16 +810,14 @@ const TestEncode = struct { buffer: [32]u8 = undefined, index: usize = 0, - fn encode(enc: *TestEncode, mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { + fn encode( + enc: *TestEncode, + mnemonic: Instruction.Mnemonic, + ops: []const Instruction.Operand, + ) !void { var stream = std.io.fixedBufferStream(&enc.buffer); var count_writer = std.io.countingWriter(stream.writer()); - const inst = try Instruction.new(mnemonic, .{ - .prefix = args.prefix, - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - }); + const inst = try Instruction.new(.none, mnemonic, ops); try inst.encode(count_writer.writer()); enc.index = count_writer.bytes_written; } @@ -850,9 +831,9 @@ test "encode" { var buf = std.ArrayList(u8).init(testing.allocator); defer buf.deinit(); - const inst = try Instruction.new(.mov, .{ - .op1 = .{ .reg = .rbx }, - .op2 = .{ .imm = Immediate.u(4) }, + const inst = try Instruction.new(.none, .mov, &.{ + .{ .reg = .rbx }, + .{ .imm = Immediate.u(4) }, }); try inst.encode(buf.writer()); try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items); @@ -861,61 +842,94 @@ test "encode" { test "lower I encoding" { var enc = TestEncode{}; - try enc.encode(.push, .{ .op1 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.push, &.{ + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10"); - try enc.encode(.push, .{ .op1 = .{ .imm = Immediate.u(0x1000) } }); + try enc.encode(.push, &.{ + .{ .imm = Immediate.u(0x1000) }, + }); try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000"); - try enc.encode(.push, .{ .op1 = .{ .imm = Immediate.u(0x10000000) } }); + try enc.encode(.push, &.{ + .{ .imm = Immediate.u(0x10000000) }, + }); try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000"); - try enc.encode(.adc, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10000000) } }); + try enc.encode(.adc, &.{ + .{ .reg = .rax }, + .{ .imm = Immediate.u(0x10000000) }, + }); try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000"); - try enc.encode(.add, .{ .op1 = .{ .reg = .al }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.add, &.{ + .{ .reg = .al }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10"); - try enc.encode(.add, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.add, &.{ + .{ .reg = .rax }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); - try enc.encode(.sbb, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.sbb, &.{ + .{ .reg = .ax }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10"); - try enc.encode(.xor, .{ .op1 = .{ .reg = .al }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.xor, &.{ + .{ .reg = .al }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10"); } test "lower MI encoding" { var enc = TestEncode{}; - try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r12 }, + .{ .imm = Immediate.u(0x1000) }, + }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); - try enc.encode(.mov, .{ - .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) }, - .op2 = .{ .imm = Immediate.u(0x10) }, + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) }, + .{ .imm = Immediate.u(0x10) }, }); try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r12 }, + .{ .imm = Immediate.u(0x1000) }, + }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r12 }, + .{ .imm = Immediate.u(0x1000) }, + }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10"); - try enc.encode(.mov, .{ - .op1 = .{ .mem = Memory.sib(.dword, .{ .base = .r11 }) }, - .op2 = .{ .imm = Immediate.u(0x10) }, + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .r11 }) }, + .{ .imm = Immediate.u(0x10) }, }); try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10"); - try enc.encode(.mov, .{ - .op1 = .{ .mem = Memory.rip(.qword, 0x10) }, - .op2 = .{ .imm = Immediate.u(0x10) }, + try enc.encode(.mov, &.{ + .{ .mem = Memory.rip(.qword, 0x10) }, + .{ .imm = Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00", @@ -923,99 +937,108 @@ test "lower MI encoding" { "mov QWORD PTR [rip + 0x10], 0x10", ); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .disp = -8, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -8 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.word, .{ - .base = .rbp, - .disp = -2, - }) }, .op2 = .{ .imm = Immediate.s(-16) } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -2 }) }, + .{ .imm = Immediate.s(-16) }, + }); try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.byte, .{ - .base = .rbp, - .disp = -1, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.byte, .{ .base = .rbp, .disp = -1 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .ds, - .disp = 0x10000000, - .scale_index = .{ - .scale = 2, - .index = .rcx, - }, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.qword, .{ + .base = .ds, + .disp = 0x10000000, + .scale_index = .{ .scale = 2, .index = .rcx }, + }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings( "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rcx*2 + 0x10000000], 0x10", ); - try enc.encode(.adc, .{ .op1 = .{ .mem = Memory.sib(.byte, .{ - .base = .rbp, - .disp = -0x10, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.adc, &.{ + .{ .mem = Memory.sib(.byte, .{ .base = .rbp, .disp = -0x10 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10"); - try enc.encode(.adc, .{ .op1 = .{ .mem = Memory.rip(.qword, 0) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.adc, &.{ + .{ .mem = Memory.rip(.qword, 0) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10"); - try enc.encode(.adc, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.adc, &.{ + .{ .reg = .rax }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10"); - try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .rdx, - .disp = -8, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.add, &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .rdx, .disp = -8 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10"); - try enc.encode(.add, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.add, &.{ + .{ .reg = .rax }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); - try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .disp = -0x10, - }) }, .op2 = .{ .imm = Immediate.s(-0x10) } }); + try enc.encode(.add, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -0x10 }) }, + .{ .imm = Immediate.s(-0x10) }, + }); try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10"); - try enc.encode(.@"and", .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .ds, - .disp = 0x10000000, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.@"and", &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .ds, .disp = 0x10000000 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings( "\x83\x24\x25\x00\x00\x00\x10\x10", enc.code(), "and DWORD PTR ds:0x10000000, 0x10", ); - try enc.encode(.@"and", .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .es, - .disp = 0x10000000, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.@"and", &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .es, .disp = 0x10000000 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings( "\x26\x83\x24\x25\x00\x00\x00\x10\x10", enc.code(), "and DWORD PTR es:0x10000000, 0x10", ); - try enc.encode(.@"and", .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .r12, - .disp = 0x10000000, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.@"and", &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .r12, .disp = 0x10000000 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings( "\x41\x83\xA4\x24\x00\x00\x00\x10\x10", enc.code(), "and DWORD PTR [r12 + 0x10000000], 0x10", ); - try enc.encode(.sub, .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .r11, - .disp = 0x10000000, - }) }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.sub, &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .r11, .disp = 0x10000000 }) }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings( "\x41\x83\xAB\x00\x00\x00\x10\x10", enc.code(), @@ -1026,185 +1049,227 @@ test "lower MI encoding" { test "lower RM encoding" { var enc = TestEncode{}; - try enc.encode(.mov, .{ - .op1 = .{ .reg = .rax }, - .op2 = .{ .mem = Memory.sib(.qword, .{ .base = .r11 }) }, + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.sib(.qword, .{ .base = .r11 }) }, }); try expectEqualHexStrings("\x49\x8b\x03", enc.code(), "mov rax, QWORD PTR [r11]"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .rbx }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .ds, - .disp = 0x10, - }) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rbx }, + .{ .mem = Memory.sib(.qword, .{ .base = .ds, .disp = 0x10 }) }, + }); try expectEqualHexStrings("\x48\x8B\x1C\x25\x10\x00\x00\x00", enc.code(), "mov rbx, QWORD PTR ds:0x10"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .disp = -4, - }) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -4 }) }, + }); try expectEqualHexStrings("\x48\x8B\x45\xFC", enc.code(), "mov rax, QWORD PTR [rbp - 4]"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .scale_index = .{ - .scale = 1, - .index = .rcx, - }, - .disp = -8, - }) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.sib(.qword, .{ + .base = .rbp, + .scale_index = .{ .scale = 1, .index = .rcx }, + .disp = -8, + }) }, + }); try expectEqualHexStrings("\x48\x8B\x44\x0D\xF8", enc.code(), "mov rax, QWORD PTR [rbp + rcx*1 - 8]"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.sib(.dword, .{ - .base = .rbp, - .scale_index = .{ - .scale = 4, - .index = .rdx, - }, - .disp = -4, - }) } }); + try enc.encode(.mov, &.{ + .{ .reg = .eax }, + .{ .mem = Memory.sib(.dword, .{ + .base = .rbp, + .scale_index = .{ .scale = 4, .index = .rdx }, + .disp = -4, + }) }, + }); try expectEqualHexStrings("\x8B\x44\x95\xFC", enc.code(), "mov eax, dword ptr [rbp + rdx*4 - 4]"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .scale_index = .{ - .scale = 8, - .index = .rcx, - }, - .disp = -8, - }) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.sib(.qword, .{ + .base = .rbp, + .scale_index = .{ .scale = 8, .index = .rcx }, + .disp = -8, + }) }, + }); try expectEqualHexStrings("\x48\x8B\x44\xCD\xF8", enc.code(), "mov rax, QWORD PTR [rbp + rcx*8 - 8]"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r8b }, .op2 = .{ .mem = Memory.sib(.byte, .{ - .base = .rsi, - .scale_index = .{ - .scale = 1, - .index = .rcx, - }, - .disp = -24, - }) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r8b }, + .{ .mem = Memory.sib(.byte, .{ + .base = .rsi, + .scale_index = .{ .scale = 1, .index = .rcx }, + .disp = -24, + }) }, + }); try expectEqualHexStrings("\x44\x8A\x44\x0E\xE8", enc.code(), "mov r8b, BYTE PTR [rsi + rcx*1 - 24]"); // TODO this mnemonic needs cleanup as some prefixes are obsolete. - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .cs } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .reg = .cs }, + }); try expectEqualHexStrings("\x48\x8C\xC8", enc.code(), "mov rax, cs"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .disp = -16, - }) }, .op2 = .{ .reg = .fs } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -16 }) }, + .{ .reg = .fs }, + }); try expectEqualHexStrings("\x48\x8C\x65\xF0", enc.code(), "mov QWORD PTR [rbp - 16], fs"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r12w }, .op2 = .{ .reg = .cs } }); + try enc.encode(.mov, &.{ + .{ .reg = .r12w }, + .{ .reg = .cs }, + }); try expectEqualHexStrings("\x66\x41\x8C\xCC", enc.code(), "mov r12w, cs"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.word, .{ - .base = .rbp, - .disp = -16, - }) }, .op2 = .{ .reg = .fs } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -16 }) }, + .{ .reg = .fs }, + }); try expectEqualHexStrings("\x66\x8C\x65\xF0", enc.code(), "mov WORD PTR [rbp - 16], fs"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .reg = .bx } }); + try enc.encode(.movsx, &.{ + .{ .reg = .eax }, + .{ .reg = .bx }, + }); try expectEqualHexStrings("\x0F\xBF\xC3", enc.code(), "movsx eax, bx"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .reg = .bl } }); + try enc.encode(.movsx, &.{ + .{ .reg = .eax }, + .{ .reg = .bl }, + }); try expectEqualHexStrings("\x0F\xBE\xC3", enc.code(), "movsx eax, bl"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .reg = .bl } }); + try enc.encode(.movsx, &.{ + .{ .reg = .ax }, + .{ .reg = .bl }, + }); try expectEqualHexStrings("\x66\x0F\xBE\xC3", enc.code(), "movsx ax, bl"); - try enc.encode(.movsx, .{ - .op1 = .{ .reg = .eax }, - .op2 = .{ .mem = Memory.sib(.word, .{ .base = .rbp }) }, + try enc.encode(.movsx, &.{ + .{ .reg = .eax }, + .{ .mem = Memory.sib(.word, .{ .base = .rbp }) }, }); try expectEqualHexStrings("\x0F\xBF\x45\x00", enc.code(), "movsx eax, BYTE PTR [rbp]"); - try enc.encode(.movsx, .{ - .op1 = .{ .reg = .eax }, - .op2 = .{ .mem = Memory.sib(.byte, .{ .scale_index = .{ .index = .rax, .scale = 2 } }) }, + try enc.encode(.movsx, &.{ + .{ .reg = .eax }, + .{ .mem = Memory.sib(.byte, .{ .scale_index = .{ .index = .rax, .scale = 2 } }) }, }); try expectEqualHexStrings("\x0F\xBE\x04\x45\x00\x00\x00\x00", enc.code(), "movsx eax, BYTE PTR [rax * 2]"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.rip(.byte, 0x10) } }); + try enc.encode(.movsx, &.{ + .{ .reg = .ax }, + .{ .mem = Memory.rip(.byte, 0x10) }, + }); try expectEqualHexStrings("\x66\x0F\xBE\x05\x10\x00\x00\x00", enc.code(), "movsx ax, BYTE PTR [rip + 0x10]"); - try enc.encode(.movsx, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .bx } }); + try enc.encode(.movsx, &.{ + .{ .reg = .rax }, + .{ .reg = .bx }, + }); try expectEqualHexStrings("\x48\x0F\xBF\xC3", enc.code(), "movsx rax, bx"); - try enc.encode(.movsxd, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .ebx } }); + try enc.encode(.movsxd, &.{ + .{ .reg = .rax }, + .{ .reg = .ebx }, + }); try expectEqualHexStrings("\x48\x63\xC3", enc.code(), "movsxd rax, ebx"); - try enc.encode(.lea, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.rip(.qword, 0x10) } }); + try enc.encode(.lea, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.rip(.qword, 0x10) }, + }); try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", enc.code(), "lea rax, QWORD PTR [rip + 0x10]"); - try enc.encode(.lea, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.rip(.dword, 0x10) } }); + try enc.encode(.lea, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.rip(.dword, 0x10) }, + }); try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", enc.code(), "lea rax, DWORD PTR [rip + 0x10]"); - try enc.encode(.lea, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.rip(.dword, 0x10) } }); + try enc.encode(.lea, &.{ + .{ .reg = .eax }, + .{ .mem = Memory.rip(.dword, 0x10) }, + }); try expectEqualHexStrings("\x8D\x05\x10\x00\x00\x00", enc.code(), "lea eax, DWORD PTR [rip + 0x10]"); - try enc.encode(.lea, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.rip(.word, 0x10) } }); + try enc.encode(.lea, &.{ + .{ .reg = .eax }, + .{ .mem = Memory.rip(.word, 0x10) }, + }); try expectEqualHexStrings("\x8D\x05\x10\x00\x00\x00", enc.code(), "lea eax, WORD PTR [rip + 0x10]"); - try enc.encode(.lea, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.rip(.byte, 0x10) } }); + try enc.encode(.lea, &.{ + .{ .reg = .ax }, + .{ .mem = Memory.rip(.byte, 0x10) }, + }); try expectEqualHexStrings("\x66\x8D\x05\x10\x00\x00\x00", enc.code(), "lea ax, BYTE PTR [rip + 0x10]"); - try enc.encode(.lea, .{ - .op1 = .{ .reg = .rsi }, - .op2 = .{ .mem = Memory.sib(.qword, .{ + try enc.encode(.lea, &.{ + .{ .reg = .rsi }, + .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .scale_index = .{ .scale = 1, .index = .rcx }, }) }, }); try expectEqualHexStrings("\x48\x8D\x74\x0D\x00", enc.code(), "lea rsi, QWORD PTR [rbp + rcx*1 + 0]"); - try enc.encode(.add, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .ds, - .disp = 0x10000000, - }) } }); + try enc.encode(.add, &.{ + .{ .reg = .r11 }, + .{ .mem = Memory.sib(.qword, .{ .base = .ds, .disp = 0x10000000 }) }, + }); try expectEqualHexStrings("\x4C\x03\x1C\x25\x00\x00\x00\x10", enc.code(), "add r11, QWORD PTR ds:0x10000000"); - try enc.encode(.add, .{ .op1 = .{ .reg = .r12b }, .op2 = .{ .mem = Memory.sib(.byte, .{ - .base = .ds, - .disp = 0x10000000, - }) } }); + try enc.encode(.add, &.{ + .{ .reg = .r12b }, + .{ .mem = Memory.sib(.byte, .{ .base = .ds, .disp = 0x10000000 }) }, + }); try expectEqualHexStrings("\x44\x02\x24\x25\x00\x00\x00\x10", enc.code(), "add r11b, BYTE PTR ds:0x10000000"); - try enc.encode(.add, .{ .op1 = .{ .reg = .r12b }, .op2 = .{ .mem = Memory.sib(.byte, .{ - .base = .fs, - .disp = 0x10000000, - }) } }); + try enc.encode(.add, &.{ + .{ .reg = .r12b }, + .{ .mem = Memory.sib(.byte, .{ .base = .fs, .disp = 0x10000000 }) }, + }); try expectEqualHexStrings("\x64\x44\x02\x24\x25\x00\x00\x00\x10", enc.code(), "add r11b, BYTE PTR fs:0x10000000"); - try enc.encode(.sub, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .r13, - .disp = 0x10000000, - }) } }); + try enc.encode(.sub, &.{ + .{ .reg = .r11 }, + .{ .mem = Memory.sib(.qword, .{ .base = .r13, .disp = 0x10000000 }) }, + }); try expectEqualHexStrings("\x4D\x2B\x9D\x00\x00\x00\x10", enc.code(), "sub r11, QWORD PTR [r13 + 0x10000000]"); - try enc.encode(.sub, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{ - .base = .r12, - .disp = 0x10000000, - }) } }); + try enc.encode(.sub, &.{ + .{ .reg = .r11 }, + .{ .mem = Memory.sib(.qword, .{ .base = .r12, .disp = 0x10000000 }) }, + }); try expectEqualHexStrings("\x4D\x2B\x9C\x24\x00\x00\x00\x10", enc.code(), "sub r11, QWORD PTR [r12 + 0x10000000]"); - try enc.encode(.imul, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .reg = .r12 } }); + try enc.encode(.imul, &.{ + .{ .reg = .r11 }, + .{ .reg = .r12 }, + }); try expectEqualHexStrings("\x4D\x0F\xAF\xDC", enc.code(), "mov r11, r12"); } test "lower RMI encoding" { var enc = TestEncode{}; - try enc.encode(.imul, .{ - .op1 = .{ .reg = .r11 }, - .op2 = .{ .reg = .r12 }, - .op3 = .{ .imm = Immediate.s(-2) }, + try enc.encode(.imul, &.{ + .{ .reg = .r11 }, + .{ .reg = .r12 }, + .{ .imm = Immediate.s(-2) }, }); try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2"); - try enc.encode(.imul, .{ - .op1 = .{ .reg = .r11 }, - .op2 = .{ .mem = Memory.rip(.qword, -16) }, - .op3 = .{ .imm = Immediate.s(-1024) }, + try enc.encode(.imul, &.{ + .{ .reg = .r11 }, + .{ .mem = Memory.rip(.qword, -16) }, + .{ .imm = Immediate.s(-1024) }, }); try expectEqualHexStrings( "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF", @@ -1212,13 +1277,10 @@ test "lower RMI encoding" { "imul r11, QWORD PTR [rip - 16], -1024", ); - try enc.encode(.imul, .{ - .op1 = .{ .reg = .bx }, - .op2 = .{ .mem = Memory.sib(.word, .{ - .base = .rbp, - .disp = -16, - }) }, - .op3 = .{ .imm = Immediate.s(-1024) }, + try enc.encode(.imul, &.{ + .{ .reg = .bx }, + .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -16 }) }, + .{ .imm = Immediate.s(-1024) }, }); try expectEqualHexStrings( "\x66\x69\x5D\xF0\x00\xFC", @@ -1226,13 +1288,10 @@ test "lower RMI encoding" { "imul bx, WORD PTR [rbp - 16], -1024", ); - try enc.encode(.imul, .{ - .op1 = .{ .reg = .bx }, - .op2 = .{ .mem = Memory.sib(.word, .{ - .base = .rbp, - .disp = -16, - }) }, - .op3 = .{ .imm = Immediate.u(1024) }, + try enc.encode(.imul, &.{ + .{ .reg = .bx }, + .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -16 }) }, + .{ .imm = Immediate.u(1024) }, }); try expectEqualHexStrings( "\x66\x69\x5D\xF0\x00\x04", @@ -1244,238 +1303,343 @@ test "lower RMI encoding" { test "lower MR encoding" { var enc = TestEncode{}; - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .rbx } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .reg = .rbx }, + }); try expectEqualHexStrings("\x48\x89\xD8", enc.code(), "mov rax, rbx"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .rbp, - .disp = -4, - }) }, .op2 = .{ .reg = .r11 } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -4 }) }, + .{ .reg = .r11 }, + }); try expectEqualHexStrings("\x4c\x89\x5d\xfc", enc.code(), "mov QWORD PTR [rbp - 4], r11"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.rip(.qword, 0x10) }, .op2 = .{ .reg = .r12 } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.rip(.qword, 0x10) }, + .{ .reg = .r12 }, + }); try expectEqualHexStrings("\x4C\x89\x25\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rip + 0x10], r12"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .r11, - .scale_index = .{ - .scale = 2, - .index = .r12, - }, - .disp = 0x10, - }) }, .op2 = .{ .reg = .r13 } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.qword, .{ + .base = .r11, + .scale_index = .{ .scale = 2, .index = .r12 }, + .disp = 0x10, + }) }, + .{ .reg = .r13 }, + }); try expectEqualHexStrings("\x4F\x89\x6C\x63\x10", enc.code(), "mov QWORD PTR [r11 + 2 * r12 + 0x10], r13"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.rip(.word, -0x10) }, .op2 = .{ .reg = .r12w } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.rip(.word, -0x10) }, + .{ .reg = .r12w }, + }); try expectEqualHexStrings("\x66\x44\x89\x25\xF0\xFF\xFF\xFF", enc.code(), "mov WORD PTR [rip - 0x10], r12w"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.byte, .{ - .base = .r11, - .scale_index = .{ - .scale = 2, - .index = .r12, - }, - .disp = 0x10, - }) }, .op2 = .{ .reg = .r13b } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.sib(.byte, .{ + .base = .r11, + .scale_index = .{ .scale = 2, .index = .r12 }, + .disp = 0x10, + }) }, + .{ .reg = .r13b }, + }); try expectEqualHexStrings("\x47\x88\x6C\x63\x10", enc.code(), "mov BYTE PTR [r11 + 2 * r12 + 0x10], r13b"); - try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.byte, .{ - .base = .ds, - .disp = 0x10000000, - }) }, .op2 = .{ .reg = .r12b } }); + try enc.encode(.add, &.{ + .{ .mem = Memory.sib(.byte, .{ .base = .ds, .disp = 0x10000000 }) }, + .{ .reg = .r12b }, + }); try expectEqualHexStrings("\x44\x00\x24\x25\x00\x00\x00\x10", enc.code(), "add BYTE PTR ds:0x10000000, r12b"); - try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .ds, - .disp = 0x10000000, - }) }, .op2 = .{ .reg = .r12d } }); + try enc.encode(.add, &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .ds, .disp = 0x10000000 }) }, + .{ .reg = .r12d }, + }); try expectEqualHexStrings("\x44\x01\x24\x25\x00\x00\x00\x10", enc.code(), "add DWORD PTR [ds:0x10000000], r12d"); - try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.dword, .{ - .base = .gs, - .disp = 0x10000000, - }) }, .op2 = .{ .reg = .r12d } }); + try enc.encode(.add, &.{ + .{ .mem = Memory.sib(.dword, .{ .base = .gs, .disp = 0x10000000 }) }, + .{ .reg = .r12d }, + }); try expectEqualHexStrings("\x65\x44\x01\x24\x25\x00\x00\x00\x10", enc.code(), "add DWORD PTR [gs:0x10000000], r12d"); - try enc.encode(.sub, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ - .base = .r11, - .disp = 0x10000000, - }) }, .op2 = .{ .reg = .r12 } }); + try enc.encode(.sub, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .r11, .disp = 0x10000000 }) }, + .{ .reg = .r12 }, + }); try expectEqualHexStrings("\x4D\x29\xA3\x00\x00\x00\x10", enc.code(), "sub QWORD PTR [r11 + 0x10000000], r12"); } test "lower M encoding" { var enc = TestEncode{}; - try enc.encode(.call, .{ .op1 = .{ .reg = .r12 } }); + try enc.encode(.call, &.{ + .{ .reg = .r12 }, + }); try expectEqualHexStrings("\x41\xFF\xD4", enc.code(), "call r12"); - try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .r12 }) } }); + try enc.encode(.call, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .r12 }) }, + }); try expectEqualHexStrings("\x41\xFF\x14\x24", enc.code(), "call QWORD PTR [r12]"); - try enc.encode(.call, .{ - .op1 = .{ .mem = Memory.sib(.qword, .{ + try enc.encode(.call, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = null, .scale_index = .{ .index = .r11, .scale = 2 }, }) }, }); try expectEqualHexStrings("\x42\xFF\x14\x5D\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r11 * 2]"); - try enc.encode(.call, .{ - .op1 = .{ .mem = Memory.sib(.qword, .{ + try enc.encode(.call, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = null, .scale_index = .{ .index = .r12, .scale = 2 }, }) }, }); try expectEqualHexStrings("\x42\xFF\x14\x65\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r12 * 2]"); - try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .gs }) } }); + try enc.encode(.call, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .gs }) }, + }); try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0"); - try enc.encode(.call, .{ .op1 = .{ .imm = Immediate.s(0) } }); + try enc.encode(.call, &.{ + .{ .imm = Immediate.s(0) }, + }); try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0"); - try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .rbp }) } }); + try enc.encode(.push, &.{ + .{ .mem = Memory.sib(.qword, .{ .base = .rbp }) }, + }); try expectEqualHexStrings("\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]"); - try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.word, .{ .base = .rbp }) } }); + try enc.encode(.push, &.{ + .{ .mem = Memory.sib(.word, .{ .base = .rbp }) }, + }); try expectEqualHexStrings("\x66\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]"); - try enc.encode(.pop, .{ .op1 = .{ .mem = Memory.rip(.qword, 0) } }); + try enc.encode(.pop, &.{ + .{ .mem = Memory.rip(.qword, 0) }, + }); try expectEqualHexStrings("\x8F\x05\x00\x00\x00\x00", enc.code(), "pop QWORD PTR [rip]"); - try enc.encode(.pop, .{ .op1 = .{ .mem = Memory.rip(.word, 0) } }); + try enc.encode(.pop, &.{ + .{ .mem = Memory.rip(.word, 0) }, + }); try expectEqualHexStrings("\x66\x8F\x05\x00\x00\x00\x00", enc.code(), "pop WORD PTR [rbp]"); - try enc.encode(.imul, .{ .op1 = .{ .reg = .rax } }); + try enc.encode(.imul, &.{ + .{ .reg = .rax }, + }); try expectEqualHexStrings("\x48\xF7\xE8", enc.code(), "imul rax"); - try enc.encode(.imul, .{ .op1 = .{ .reg = .r12 } }); + try enc.encode(.imul, &.{ + .{ .reg = .r12 }, + }); try expectEqualHexStrings("\x49\xF7\xEC", enc.code(), "imul r12"); } test "lower O encoding" { var enc = TestEncode{}; - try enc.encode(.push, .{ .op1 = .{ .reg = .rax } }); + try enc.encode(.push, &.{ + .{ .reg = .rax }, + }); try expectEqualHexStrings("\x50", enc.code(), "push rax"); - try enc.encode(.push, .{ .op1 = .{ .reg = .r12w } }); + try enc.encode(.push, &.{ + .{ .reg = .r12w }, + }); try expectEqualHexStrings("\x66\x41\x54", enc.code(), "push r12w"); - try enc.encode(.pop, .{ .op1 = .{ .reg = .r12 } }); + try enc.encode(.pop, &.{ + .{ .reg = .r12 }, + }); try expectEqualHexStrings("\x41\x5c", enc.code(), "pop r12"); } test "lower OI encoding" { var enc = TestEncode{}; - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x1000000000000000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .imm = Immediate.u(0x1000000000000000) }, + }); try expectEqualHexStrings( "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10", enc.code(), "movabs rax, 0x1000000000000000", ); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .imm = Immediate.u(0x1000000000000000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r11 }, + .{ .imm = Immediate.u(0x1000000000000000) }, + }); try expectEqualHexStrings( "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10", enc.code(), "movabs r11, 0x1000000000000000", ); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r11d }, .op2 = .{ .imm = Immediate.u(0x10000000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r11d }, + .{ .imm = Immediate.u(0x10000000) }, + }); try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r11w }, .op2 = .{ .imm = Immediate.u(0x1000) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r11w }, + .{ .imm = Immediate.u(0x1000) }, + }); try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .r11b }, .op2 = .{ .imm = Immediate.u(0x10) } }); + try enc.encode(.mov, &.{ + .{ .reg = .r11b }, + .{ .imm = Immediate.u(0x10) }, + }); try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10"); } test "lower FD/TD encoding" { var enc = TestEncode{}; - try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.moffs(.cs, 0x10) } }); + try enc.encode(.mov, &.{ + .{ .reg = .rax }, + .{ .mem = Memory.moffs(.cs, 0x10) }, + }); try expectEqualHexStrings("\x2E\x48\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs rax, cs:0x10"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.moffs(.fs, 0x10) } }); + try enc.encode(.mov, &.{ + .{ .reg = .eax }, + .{ .mem = Memory.moffs(.fs, 0x10) }, + }); try expectEqualHexStrings("\x64\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs eax, fs:0x10"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.moffs(.gs, 0x10) } }); + try enc.encode(.mov, &.{ + .{ .reg = .ax }, + .{ .mem = Memory.moffs(.gs, 0x10) }, + }); try expectEqualHexStrings("\x65\x66\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs ax, gs:0x10"); - try enc.encode(.mov, .{ .op1 = .{ .reg = .al }, .op2 = .{ .mem = Memory.moffs(.ds, 0x10) } }); + try enc.encode(.mov, &.{ + .{ .reg = .al }, + .{ .mem = Memory.moffs(.ds, 0x10) }, + }); try expectEqualHexStrings("\xA0\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs al, ds:0x10"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.cs, 0x10) }, .op2 = .{ .reg = .rax } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.moffs(.cs, 0x10) }, + .{ .reg = .rax }, + }); try expectEqualHexStrings("\x2E\x48\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs cs:0x10, rax"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.fs, 0x10) }, .op2 = .{ .reg = .eax } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.moffs(.fs, 0x10) }, + .{ .reg = .eax }, + }); try expectEqualHexStrings("\x64\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs fs:0x10, eax"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.gs, 0x10) }, .op2 = .{ .reg = .ax } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.moffs(.gs, 0x10) }, + .{ .reg = .ax }, + }); try expectEqualHexStrings("\x65\x66\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs gs:0x10, ax"); - try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.ds, 0x10) }, .op2 = .{ .reg = .al } }); + try enc.encode(.mov, &.{ + .{ .mem = Memory.moffs(.ds, 0x10) }, + .{ .reg = .al }, + }); try expectEqualHexStrings("\xA2\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs ds:0x10, al"); } test "lower NP encoding" { var enc = TestEncode{}; - try enc.encode(.int3, .{}); + try enc.encode(.int3, &.{}); try expectEqualHexStrings("\xCC", enc.code(), "int3"); - try enc.encode(.nop, .{}); + try enc.encode(.nop, &.{}); try expectEqualHexStrings("\x90", enc.code(), "nop"); - try enc.encode(.ret, .{}); + try enc.encode(.ret, &.{}); try expectEqualHexStrings("\xC3", enc.code(), "ret"); - try enc.encode(.syscall, .{}); + try enc.encode(.syscall, &.{}); try expectEqualHexStrings("\x0f\x05", enc.code(), "syscall"); } -fn invalidInstruction(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { - const err = Instruction.new(mnemonic, args); +fn invalidInstruction(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void { + const err = Instruction.new(.none, mnemonic, ops); try testing.expectError(error.InvalidInstruction, err); } test "invalid instruction" { - try invalidInstruction(.call, .{ .op1 = .{ .reg = .eax } }); - try invalidInstruction(.call, .{ .op1 = .{ .reg = .ax } }); - try invalidInstruction(.call, .{ .op1 = .{ .reg = .al } }); - try invalidInstruction(.call, .{ .op1 = .{ .mem = Memory.rip(.dword, 0) } }); - try invalidInstruction(.call, .{ .op1 = .{ .mem = Memory.rip(.word, 0) } }); - try invalidInstruction(.call, .{ .op1 = .{ .mem = Memory.rip(.byte, 0) } }); - try invalidInstruction(.mov, .{ .op1 = .{ .mem = Memory.rip(.word, 0x10) }, .op2 = .{ .reg = .r12 } }); - try invalidInstruction(.lea, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .rbx } }); - try invalidInstruction(.lea, .{ .op1 = .{ .reg = .al }, .op2 = .{ .mem = Memory.rip(.byte, 0) } }); - try invalidInstruction(.pop, .{ .op1 = .{ .reg = .r12b } }); - try invalidInstruction(.pop, .{ .op1 = .{ .reg = .r12d } }); - try invalidInstruction(.push, .{ .op1 = .{ .reg = .r12b } }); - try invalidInstruction(.push, .{ .op1 = .{ .reg = .r12d } }); - try invalidInstruction(.push, .{ .op1 = .{ .imm = Immediate.u(0x1000000000000000) } }); + try invalidInstruction(.call, &.{ + .{ .reg = .eax }, + }); + try invalidInstruction(.call, &.{ + .{ .reg = .ax }, + }); + try invalidInstruction(.call, &.{ + .{ .reg = .al }, + }); + try invalidInstruction(.call, &.{ + .{ .mem = Memory.rip(.dword, 0) }, + }); + try invalidInstruction(.call, &.{ + .{ .mem = Memory.rip(.word, 0) }, + }); + try invalidInstruction(.call, &.{ + .{ .mem = Memory.rip(.byte, 0) }, + }); + try invalidInstruction(.mov, &.{ + .{ .mem = Memory.rip(.word, 0x10) }, + .{ .reg = .r12 }, + }); + try invalidInstruction(.lea, &.{ + .{ .reg = .rax }, + .{ .reg = .rbx }, + }); + try invalidInstruction(.lea, &.{ + .{ .reg = .al }, + .{ .mem = Memory.rip(.byte, 0) }, + }); + try invalidInstruction(.pop, &.{ + .{ .reg = .r12b }, + }); + try invalidInstruction(.pop, &.{ + .{ .reg = .r12d }, + }); + try invalidInstruction(.push, &.{ + .{ .reg = .r12b }, + }); + try invalidInstruction(.push, &.{ + .{ .reg = .r12d }, + }); + try invalidInstruction(.push, &.{ + .{ .imm = Immediate.u(0x1000000000000000) }, + }); } -fn cannotEncode(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { - try testing.expectError(error.CannotEncode, Instruction.new(mnemonic, args)); +fn cannotEncode(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void { + try testing.expectError(error.CannotEncode, Instruction.new(.none, mnemonic, ops)); } test "cannot encode" { - try cannotEncode(.@"test", .{ - .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) }, - .op2 = .{ .reg = .ah }, + try cannotEncode(.@"test", &.{ + .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) }, + .{ .reg = .ah }, }); - try cannotEncode(.@"test", .{ - .op1 = .{ .reg = .r11b }, - .op2 = .{ .reg = .bh }, + try cannotEncode(.@"test", &.{ + .{ .reg = .r11b }, + .{ .reg = .bh }, }); - try cannotEncode(.mov, .{ - .op1 = .{ .reg = .sil }, - .op2 = .{ .reg = .ah }, + try cannotEncode(.mov, &.{ + .{ .reg = .sil }, + .{ .reg = .ah }, }); } @@ -1645,12 +1809,7 @@ const Assembler = struct { pub fn assemble(as: *Assembler, writer: anytype) !void { while (try as.next()) |parsed_inst| { - const inst = try Instruction.new(parsed_inst.mnemonic, .{ - .op1 = parsed_inst.ops[0], - .op2 = parsed_inst.ops[1], - .op3 = parsed_inst.ops[2], - .op4 = parsed_inst.ops[3], - }); + const inst = try Instruction.new(.none, parsed_inst.mnemonic, &parsed_inst.ops); try inst.encode(writer); } } diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 9683ef991a..05933b68bb 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -6,869 +6,874 @@ const Mode = Encoding.Mode; const modrm_ext = u3; -const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, []const u8, modrm_ext, Mode }; +pub const Entry = struct { Mnemonic, OpEn, []const Op, []const u8, modrm_ext, Mode }; // TODO move this into a .zon file when Zig is capable of importing .zon files // zig fmt: off -pub const table = &[_]Entry{ +pub const table = [_]Entry{ // General-purpose - .{ .adc, .zi, .al, .imm8, .none, .none, &.{ 0x14 }, 0, .none }, - .{ .adc, .zi, .ax, .imm16, .none, .none, &.{ 0x15 }, 0, .none }, - .{ .adc, .zi, .eax, .imm32, .none, .none, &.{ 0x15 }, 0, .none }, - .{ .adc, .zi, .rax, .imm32s, .none, .none, &.{ 0x15 }, 0, .long }, - .{ .adc, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 2, .none }, - .{ .adc, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 2, .rex }, - .{ .adc, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 2, .none }, - .{ .adc, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 2, .none }, - .{ .adc, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 2, .long }, - .{ .adc, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 2, .none }, - .{ .adc, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 2, .none }, - .{ .adc, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 2, .long }, - .{ .adc, .mr, .rm8, .r8, .none, .none, &.{ 0x10 }, 0, .none }, - .{ .adc, .mr, .rm8, .r8, .none, .none, &.{ 0x10 }, 0, .rex }, - .{ .adc, .mr, .rm16, .r16, .none, .none, &.{ 0x11 }, 0, .none }, - .{ .adc, .mr, .rm32, .r32, .none, .none, &.{ 0x11 }, 0, .none }, - .{ .adc, .mr, .rm64, .r64, .none, .none, &.{ 0x11 }, 0, .long }, - .{ .adc, .rm, .r8, .rm8, .none, .none, &.{ 0x12 }, 0, .none }, - .{ .adc, .rm, .r8, .rm8, .none, .none, &.{ 0x12 }, 0, .rex }, - .{ .adc, .rm, .r16, .rm16, .none, .none, &.{ 0x13 }, 0, .none }, - .{ .adc, .rm, .r32, .rm32, .none, .none, &.{ 0x13 }, 0, .none }, - .{ .adc, .rm, .r64, .rm64, .none, .none, &.{ 0x13 }, 0, .long }, + .{ .adc, .zi, &.{ .al, .imm8 }, &.{ 0x14 }, 0, .none }, + .{ .adc, .zi, &.{ .ax, .imm16 }, &.{ 0x15 }, 0, .none }, + .{ .adc, .zi, &.{ .eax, .imm32 }, &.{ 0x15 }, 0, .none }, + .{ .adc, .zi, &.{ .rax, .imm32s }, &.{ 0x15 }, 0, .long }, + .{ .adc, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 2, .none }, + .{ .adc, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 2, .rex }, + .{ .adc, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 2, .none }, + .{ .adc, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 2, .none }, + .{ .adc, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 2, .long }, + .{ .adc, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 2, .none }, + .{ .adc, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 2, .none }, + .{ .adc, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 2, .long }, + .{ .adc, .mr, &.{ .rm8, .r8 }, &.{ 0x10 }, 0, .none }, + .{ .adc, .mr, &.{ .rm8, .r8 }, &.{ 0x10 }, 0, .rex }, + .{ .adc, .mr, &.{ .rm16, .r16 }, &.{ 0x11 }, 0, .none }, + .{ .adc, .mr, &.{ .rm32, .r32 }, &.{ 0x11 }, 0, .none }, + .{ .adc, .mr, &.{ .rm64, .r64 }, &.{ 0x11 }, 0, .long }, + .{ .adc, .rm, &.{ .r8, .rm8 }, &.{ 0x12 }, 0, .none }, + .{ .adc, .rm, &.{ .r8, .rm8 }, &.{ 0x12 }, 0, .rex }, + .{ .adc, .rm, &.{ .r16, .rm16 }, &.{ 0x13 }, 0, .none }, + .{ .adc, .rm, &.{ .r32, .rm32 }, &.{ 0x13 }, 0, .none }, + .{ .adc, .rm, &.{ .r64, .rm64 }, &.{ 0x13 }, 0, .long }, - .{ .add, .zi, .al, .imm8, .none, .none, &.{ 0x04 }, 0, .none }, - .{ .add, .zi, .ax, .imm16, .none, .none, &.{ 0x05 }, 0, .none }, - .{ .add, .zi, .eax, .imm32, .none, .none, &.{ 0x05 }, 0, .none }, - .{ .add, .zi, .rax, .imm32s, .none, .none, &.{ 0x05 }, 0, .long }, - .{ .add, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 0, .none }, - .{ .add, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 0, .rex }, - .{ .add, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 0, .none }, - .{ .add, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 0, .none }, - .{ .add, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 0, .long }, - .{ .add, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 0, .none }, - .{ .add, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 0, .none }, - .{ .add, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 0, .long }, - .{ .add, .mr, .rm8, .r8, .none, .none, &.{ 0x00 }, 0, .none }, - .{ .add, .mr, .rm8, .r8, .none, .none, &.{ 0x00 }, 0, .rex }, - .{ .add, .mr, .rm16, .r16, .none, .none, &.{ 0x01 }, 0, .none }, - .{ .add, .mr, .rm32, .r32, .none, .none, &.{ 0x01 }, 0, .none }, - .{ .add, .mr, .rm64, .r64, .none, .none, &.{ 0x01 }, 0, .long }, - .{ .add, .rm, .r8, .rm8, .none, .none, &.{ 0x02 }, 0, .none }, - .{ .add, .rm, .r8, .rm8, .none, .none, &.{ 0x02 }, 0, .rex }, - .{ .add, .rm, .r16, .rm16, .none, .none, &.{ 0x03 }, 0, .none }, - .{ .add, .rm, .r32, .rm32, .none, .none, &.{ 0x03 }, 0, .none }, - .{ .add, .rm, .r64, .rm64, .none, .none, &.{ 0x03 }, 0, .long }, + .{ .add, .zi, &.{ .al, .imm8 }, &.{ 0x04 }, 0, .none }, + .{ .add, .zi, &.{ .ax, .imm16 }, &.{ 0x05 }, 0, .none }, + .{ .add, .zi, &.{ .eax, .imm32 }, &.{ 0x05 }, 0, .none }, + .{ .add, .zi, &.{ .rax, .imm32s }, &.{ 0x05 }, 0, .long }, + .{ .add, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 0, .none }, + .{ .add, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 0, .rex }, + .{ .add, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 0, .none }, + .{ .add, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 0, .none }, + .{ .add, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 0, .long }, + .{ .add, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 0, .none }, + .{ .add, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 0, .none }, + .{ .add, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 0, .long }, + .{ .add, .mr, &.{ .rm8, .r8 }, &.{ 0x00 }, 0, .none }, + .{ .add, .mr, &.{ .rm8, .r8 }, &.{ 0x00 }, 0, .rex }, + .{ .add, .mr, &.{ .rm16, .r16 }, &.{ 0x01 }, 0, .none }, + .{ .add, .mr, &.{ .rm32, .r32 }, &.{ 0x01 }, 0, .none }, + .{ .add, .mr, &.{ .rm64, .r64 }, &.{ 0x01 }, 0, .long }, + .{ .add, .rm, &.{ .r8, .rm8 }, &.{ 0x02 }, 0, .none }, + .{ .add, .rm, &.{ .r8, .rm8 }, &.{ 0x02 }, 0, .rex }, + .{ .add, .rm, &.{ .r16, .rm16 }, &.{ 0x03 }, 0, .none }, + .{ .add, .rm, &.{ .r32, .rm32 }, &.{ 0x03 }, 0, .none }, + .{ .add, .rm, &.{ .r64, .rm64 }, &.{ 0x03 }, 0, .long }, - .{ .@"and", .zi, .al, .imm8, .none, .none, &.{ 0x24 }, 0, .none }, - .{ .@"and", .zi, .ax, .imm16, .none, .none, &.{ 0x25 }, 0, .none }, - .{ .@"and", .zi, .eax, .imm32, .none, .none, &.{ 0x25 }, 0, .none }, - .{ .@"and", .zi, .rax, .imm32s, .none, .none, &.{ 0x25 }, 0, .long }, - .{ .@"and", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 4, .none }, - .{ .@"and", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 4, .rex }, - .{ .@"and", .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 4, .none }, - .{ .@"and", .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 4, .none }, - .{ .@"and", .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 4, .long }, - .{ .@"and", .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 4, .none }, - .{ .@"and", .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 4, .none }, - .{ .@"and", .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 4, .long }, - .{ .@"and", .mr, .rm8, .r8, .none, .none, &.{ 0x20 }, 0, .none }, - .{ .@"and", .mr, .rm8, .r8, .none, .none, &.{ 0x20 }, 0, .rex }, - .{ .@"and", .mr, .rm16, .r16, .none, .none, &.{ 0x21 }, 0, .none }, - .{ .@"and", .mr, .rm32, .r32, .none, .none, &.{ 0x21 }, 0, .none }, - .{ .@"and", .mr, .rm64, .r64, .none, .none, &.{ 0x21 }, 0, .long }, - .{ .@"and", .rm, .r8, .rm8, .none, .none, &.{ 0x22 }, 0, .none }, - .{ .@"and", .rm, .r8, .rm8, .none, .none, &.{ 0x22 }, 0, .rex }, - .{ .@"and", .rm, .r16, .rm16, .none, .none, &.{ 0x23 }, 0, .none }, - .{ .@"and", .rm, .r32, .rm32, .none, .none, &.{ 0x23 }, 0, .none }, - .{ .@"and", .rm, .r64, .rm64, .none, .none, &.{ 0x23 }, 0, .long }, + .{ .@"and", .zi, &.{ .al, .imm8 }, &.{ 0x24 }, 0, .none }, + .{ .@"and", .zi, &.{ .ax, .imm16 }, &.{ 0x25 }, 0, .none }, + .{ .@"and", .zi, &.{ .eax, .imm32 }, &.{ 0x25 }, 0, .none }, + .{ .@"and", .zi, &.{ .rax, .imm32s }, &.{ 0x25 }, 0, .long }, + .{ .@"and", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 4, .none }, + .{ .@"and", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 4, .rex }, + .{ .@"and", .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 4, .none }, + .{ .@"and", .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 4, .none }, + .{ .@"and", .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 4, .long }, + .{ .@"and", .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 4, .none }, + .{ .@"and", .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 4, .none }, + .{ .@"and", .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 4, .long }, + .{ .@"and", .mr, &.{ .rm8, .r8 }, &.{ 0x20 }, 0, .none }, + .{ .@"and", .mr, &.{ .rm8, .r8 }, &.{ 0x20 }, 0, .rex }, + .{ .@"and", .mr, &.{ .rm16, .r16 }, &.{ 0x21 }, 0, .none }, + .{ .@"and", .mr, &.{ .rm32, .r32 }, &.{ 0x21 }, 0, .none }, + .{ .@"and", .mr, &.{ .rm64, .r64 }, &.{ 0x21 }, 0, .long }, + .{ .@"and", .rm, &.{ .r8, .rm8 }, &.{ 0x22 }, 0, .none }, + .{ .@"and", .rm, &.{ .r8, .rm8 }, &.{ 0x22 }, 0, .rex }, + .{ .@"and", .rm, &.{ .r16, .rm16 }, &.{ 0x23 }, 0, .none }, + .{ .@"and", .rm, &.{ .r32, .rm32 }, &.{ 0x23 }, 0, .none }, + .{ .@"and", .rm, &.{ .r64, .rm64 }, &.{ 0x23 }, 0, .long }, - .{ .bsf, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xbc }, 0, .none }, - .{ .bsf, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbc }, 0, .none }, - .{ .bsf, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbc }, 0, .long }, + .{ .bsf, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0xbc }, 0, .none }, + .{ .bsf, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xbc }, 0, .none }, + .{ .bsf, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0xbc }, 0, .long }, - .{ .bsr, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xbd }, 0, .none }, - .{ .bsr, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbd }, 0, .none }, - .{ .bsr, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbd }, 0, .long }, + .{ .bsr, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0xbd }, 0, .none }, + .{ .bsr, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xbd }, 0, .none }, + .{ .bsr, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0xbd }, 0, .long }, - .{ .bswap, .o, .r32, .none, .none, .none, &.{ 0x0f, 0xc8 }, 0, .none }, - .{ .bswap, .o, .r64, .none, .none, .none, &.{ 0x0f, 0xc8 }, 0, .long }, + .{ .bswap, .o, &.{ .r32 }, &.{ 0x0f, 0xc8 }, 0, .none }, + .{ .bswap, .o, &.{ .r64 }, &.{ 0x0f, 0xc8 }, 0, .long }, - .{ .bt, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none }, - .{ .bt, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none }, - .{ .bt, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xa3 }, 0, .long }, - .{ .bt, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .none }, - .{ .bt, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .none }, - .{ .bt, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .long }, + .{ .bt, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xa3 }, 0, .none }, + .{ .bt, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xa3 }, 0, .none }, + .{ .bt, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xa3 }, 0, .long }, + .{ .bt, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 4, .none }, + .{ .bt, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 4, .none }, + .{ .bt, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 4, .long }, - .{ .btc, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xbb }, 0, .none }, - .{ .btc, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xbb }, 0, .none }, - .{ .btc, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xbb }, 0, .long }, - .{ .btc, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .none }, - .{ .btc, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .none }, - .{ .btc, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .long }, + .{ .btc, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xbb }, 0, .none }, + .{ .btc, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xbb }, 0, .none }, + .{ .btc, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xbb }, 0, .long }, + .{ .btc, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 7, .none }, + .{ .btc, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 7, .none }, + .{ .btc, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 7, .long }, - .{ .btr, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb3 }, 0, .none }, - .{ .btr, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb3 }, 0, .none }, - .{ .btr, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb3 }, 0, .long }, - .{ .btr, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .none }, - .{ .btr, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .none }, - .{ .btr, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .long }, + .{ .btr, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xb3 }, 0, .none }, + .{ .btr, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xb3 }, 0, .none }, + .{ .btr, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xb3 }, 0, .long }, + .{ .btr, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 6, .none }, + .{ .btr, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 6, .none }, + .{ .btr, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 6, .long }, - .{ .bts, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xab }, 0, .none }, - .{ .bts, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xab }, 0, .none }, - .{ .bts, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xab }, 0, .long }, - .{ .bts, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .none }, - .{ .bts, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .none }, - .{ .bts, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .long }, + .{ .bts, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xab }, 0, .none }, + .{ .bts, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xab }, 0, .none }, + .{ .bts, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xab }, 0, .long }, + .{ .bts, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 5, .none }, + .{ .bts, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 5, .none }, + .{ .bts, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 5, .long }, // This is M encoding according to Intel, but D makes more sense here. - .{ .call, .d, .rel32, .none, .none, .none, &.{ 0xe8 }, 0, .none }, - .{ .call, .m, .rm64, .none, .none, .none, &.{ 0xff }, 2, .none }, + .{ .call, .d, &.{ .rel32 }, &.{ 0xe8 }, 0, .none }, + .{ .call, .m, &.{ .rm64 }, &.{ 0xff }, 2, .none }, - .{ .cbw, .np, .o16, .none, .none, .none, &.{ 0x98 }, 0, .none }, - .{ .cwde, .np, .o32, .none, .none, .none, &.{ 0x98 }, 0, .none }, - .{ .cdqe, .np, .o64, .none, .none, .none, &.{ 0x98 }, 0, .long }, + .{ .cbw, .np, &.{ .o16 }, &.{ 0x98 }, 0, .none }, + .{ .cwde, .np, &.{ .o32 }, &.{ 0x98 }, 0, .none }, + .{ .cdqe, .np, &.{ .o64 }, &.{ 0x98 }, 0, .long }, - .{ .cwd, .np, .o16, .none, .none, .none, &.{ 0x99 }, 0, .none }, - .{ .cdq, .np, .o32, .none, .none, .none, &.{ 0x99 }, 0, .none }, - .{ .cqo, .np, .o64, .none, .none, .none, &.{ 0x99 }, 0, .long }, + .{ .cwd, .np, &.{ .o16 }, &.{ 0x99 }, 0, .none }, + .{ .cdq, .np, &.{ .o32 }, &.{ 0x99 }, 0, .none }, + .{ .cqo, .np, &.{ .o64 }, &.{ 0x99 }, 0, .long }, - .{ .cmova, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, - .{ .cmova, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, - .{ .cmova, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x47 }, 0, .long }, - .{ .cmovae, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, - .{ .cmovae, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, - .{ .cmovae, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long }, - .{ .cmovb, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, - .{ .cmovb, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, - .{ .cmovb, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long }, - .{ .cmovbe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, - .{ .cmovbe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, - .{ .cmovbe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x46 }, 0, .long }, - .{ .cmovc, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, - .{ .cmovc, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, - .{ .cmovc, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long }, - .{ .cmove, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, - .{ .cmove, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, - .{ .cmove, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x44 }, 0, .long }, - .{ .cmovg, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, - .{ .cmovg, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, - .{ .cmovg, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4f }, 0, .long }, - .{ .cmovge, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, - .{ .cmovge, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, - .{ .cmovge, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4d }, 0, .long }, - .{ .cmovl, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, - .{ .cmovl, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, - .{ .cmovl, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4c }, 0, .long }, - .{ .cmovle, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, - .{ .cmovle, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, - .{ .cmovle, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4e }, 0, .long }, - .{ .cmovna, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, - .{ .cmovna, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x46 }, 0, .none }, - .{ .cmovna, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x46 }, 0, .long }, - .{ .cmovnae, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, - .{ .cmovnae, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none }, - .{ .cmovnae, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long }, - .{ .cmovnb, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, - .{ .cmovnb, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, - .{ .cmovnb, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long }, - .{ .cmovnbe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, - .{ .cmovnbe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x47 }, 0, .none }, - .{ .cmovnbe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x47 }, 0, .long }, - .{ .cmovnc, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, - .{ .cmovnc, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none }, - .{ .cmovnc, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long }, - .{ .cmovne, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, - .{ .cmovne, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, - .{ .cmovne, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x45 }, 0, .long }, - .{ .cmovng, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, - .{ .cmovng, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4e }, 0, .none }, - .{ .cmovng, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4e }, 0, .long }, - .{ .cmovnge, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, - .{ .cmovnge, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4c }, 0, .none }, - .{ .cmovnge, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4c }, 0, .long }, - .{ .cmovnl, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, - .{ .cmovnl, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4d }, 0, .none }, - .{ .cmovnl, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4d }, 0, .long }, - .{ .cmovnle, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, - .{ .cmovnle, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4f }, 0, .none }, - .{ .cmovnle, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4f }, 0, .long }, - .{ .cmovno, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x41 }, 0, .none }, - .{ .cmovno, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x41 }, 0, .none }, - .{ .cmovno, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x41 }, 0, .long }, - .{ .cmovnp, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, - .{ .cmovnp, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, - .{ .cmovnp, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4b }, 0, .long }, - .{ .cmovns, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x49 }, 0, .none }, - .{ .cmovns, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x49 }, 0, .none }, - .{ .cmovns, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x49 }, 0, .long }, - .{ .cmovnz, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, - .{ .cmovnz, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x45 }, 0, .none }, - .{ .cmovnz, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x45 }, 0, .long }, - .{ .cmovo, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x40 }, 0, .none }, - .{ .cmovo, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x40 }, 0, .none }, - .{ .cmovo, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x40 }, 0, .long }, - .{ .cmovp, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, - .{ .cmovp, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, - .{ .cmovp, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4a }, 0, .long }, - .{ .cmovpe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, - .{ .cmovpe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4a }, 0, .none }, - .{ .cmovpe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4a }, 0, .long }, - .{ .cmovpo, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, - .{ .cmovpo, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4b }, 0, .none }, - .{ .cmovpo, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4b }, 0, .long }, - .{ .cmovs, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x48 }, 0, .none }, - .{ .cmovs, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x48 }, 0, .none }, - .{ .cmovs, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x48 }, 0, .long }, - .{ .cmovz, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, - .{ .cmovz, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x44 }, 0, .none }, - .{ .cmovz, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x44 }, 0, .long }, + .{ .cmova, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmova, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmova, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x47 }, 0, .long }, + .{ .cmovae, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovae, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovae, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x43 }, 0, .long }, + .{ .cmovb, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovb, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovb, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x42 }, 0, .long }, + .{ .cmovbe, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovbe, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovbe, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x46 }, 0, .long }, + .{ .cmovc, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovc, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovc, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x42 }, 0, .long }, + .{ .cmove, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmove, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmove, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x44 }, 0, .long }, + .{ .cmovg, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovg, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovg, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4f }, 0, .long }, + .{ .cmovge, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovge, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovge, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4d }, 0, .long }, + .{ .cmovl, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovl, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovl, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4c }, 0, .long }, + .{ .cmovle, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovle, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovle, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4e }, 0, .long }, + .{ .cmovna, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovna, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x46 }, 0, .none }, + .{ .cmovna, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x46 }, 0, .long }, + .{ .cmovnae, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovnae, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x42 }, 0, .none }, + .{ .cmovnae, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x42 }, 0, .long }, + .{ .cmovnb, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnb, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnb, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x43 }, 0, .long }, + .{ .cmovnbe, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmovnbe, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none }, + .{ .cmovnbe, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x47 }, 0, .long }, + .{ .cmovnc, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnc, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x43 }, 0, .none }, + .{ .cmovnc, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x43 }, 0, .long }, + .{ .cmovne, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovne, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovne, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x45 }, 0, .long }, + .{ .cmovng, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovng, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4e }, 0, .none }, + .{ .cmovng, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4e }, 0, .long }, + .{ .cmovnge, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovnge, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4c }, 0, .none }, + .{ .cmovnge, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4c }, 0, .long }, + .{ .cmovnl, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovnl, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4d }, 0, .none }, + .{ .cmovnl, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4d }, 0, .long }, + .{ .cmovnle, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovnle, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4f }, 0, .none }, + .{ .cmovnle, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4f }, 0, .long }, + .{ .cmovno, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x41 }, 0, .none }, + .{ .cmovno, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x41 }, 0, .none }, + .{ .cmovno, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x41 }, 0, .long }, + .{ .cmovnp, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovnp, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovnp, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4b }, 0, .long }, + .{ .cmovns, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x49 }, 0, .none }, + .{ .cmovns, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x49 }, 0, .none }, + .{ .cmovns, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x49 }, 0, .long }, + .{ .cmovnz, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovnz, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x45 }, 0, .none }, + .{ .cmovnz, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x45 }, 0, .long }, + .{ .cmovo, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x40 }, 0, .none }, + .{ .cmovo, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x40 }, 0, .none }, + .{ .cmovo, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x40 }, 0, .long }, + .{ .cmovp, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovp, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovp, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4a }, 0, .long }, + .{ .cmovpe, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovpe, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4a }, 0, .none }, + .{ .cmovpe, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4a }, 0, .long }, + .{ .cmovpo, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovpo, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4b }, 0, .none }, + .{ .cmovpo, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4b }, 0, .long }, + .{ .cmovs, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x48 }, 0, .none }, + .{ .cmovs, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x48 }, 0, .none }, + .{ .cmovs, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x48 }, 0, .long }, + .{ .cmovz, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmovz, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x44 }, 0, .none }, + .{ .cmovz, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x44 }, 0, .long }, - .{ .cmp, .zi, .al, .imm8, .none, .none, &.{ 0x3c }, 0, .none }, - .{ .cmp, .zi, .ax, .imm16, .none, .none, &.{ 0x3d }, 0, .none }, - .{ .cmp, .zi, .eax, .imm32, .none, .none, &.{ 0x3d }, 0, .none }, - .{ .cmp, .zi, .rax, .imm32s, .none, .none, &.{ 0x3d }, 0, .long }, - .{ .cmp, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 7, .none }, - .{ .cmp, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 7, .rex }, - .{ .cmp, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 7, .none }, - .{ .cmp, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 7, .none }, - .{ .cmp, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 7, .long }, - .{ .cmp, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 7, .none }, - .{ .cmp, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 7, .none }, - .{ .cmp, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 7, .long }, - .{ .cmp, .mr, .rm8, .r8, .none, .none, &.{ 0x38 }, 0, .none }, - .{ .cmp, .mr, .rm8, .r8, .none, .none, &.{ 0x38 }, 0, .rex }, - .{ .cmp, .mr, .rm16, .r16, .none, .none, &.{ 0x39 }, 0, .none }, - .{ .cmp, .mr, .rm32, .r32, .none, .none, &.{ 0x39 }, 0, .none }, - .{ .cmp, .mr, .rm64, .r64, .none, .none, &.{ 0x39 }, 0, .long }, - .{ .cmp, .rm, .r8, .rm8, .none, .none, &.{ 0x3a }, 0, .none }, - .{ .cmp, .rm, .r8, .rm8, .none, .none, &.{ 0x3a }, 0, .rex }, - .{ .cmp, .rm, .r16, .rm16, .none, .none, &.{ 0x3b }, 0, .none }, - .{ .cmp, .rm, .r32, .rm32, .none, .none, &.{ 0x3b }, 0, .none }, - .{ .cmp, .rm, .r64, .rm64, .none, .none, &.{ 0x3b }, 0, .long }, + .{ .cmp, .zi, &.{ .al, .imm8 }, &.{ 0x3c }, 0, .none }, + .{ .cmp, .zi, &.{ .ax, .imm16 }, &.{ 0x3d }, 0, .none }, + .{ .cmp, .zi, &.{ .eax, .imm32 }, &.{ 0x3d }, 0, .none }, + .{ .cmp, .zi, &.{ .rax, .imm32s }, &.{ 0x3d }, 0, .long }, + .{ .cmp, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 7, .none }, + .{ .cmp, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 7, .rex }, + .{ .cmp, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 7, .none }, + .{ .cmp, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 7, .none }, + .{ .cmp, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 7, .long }, + .{ .cmp, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 7, .none }, + .{ .cmp, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 7, .none }, + .{ .cmp, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 7, .long }, + .{ .cmp, .mr, &.{ .rm8, .r8 }, &.{ 0x38 }, 0, .none }, + .{ .cmp, .mr, &.{ .rm8, .r8 }, &.{ 0x38 }, 0, .rex }, + .{ .cmp, .mr, &.{ .rm16, .r16 }, &.{ 0x39 }, 0, .none }, + .{ .cmp, .mr, &.{ .rm32, .r32 }, &.{ 0x39 }, 0, .none }, + .{ .cmp, .mr, &.{ .rm64, .r64 }, &.{ 0x39 }, 0, .long }, + .{ .cmp, .rm, &.{ .r8, .rm8 }, &.{ 0x3a }, 0, .none }, + .{ .cmp, .rm, &.{ .r8, .rm8 }, &.{ 0x3a }, 0, .rex }, + .{ .cmp, .rm, &.{ .r16, .rm16 }, &.{ 0x3b }, 0, .none }, + .{ .cmp, .rm, &.{ .r32, .rm32 }, &.{ 0x3b }, 0, .none }, + .{ .cmp, .rm, &.{ .r64, .rm64 }, &.{ 0x3b }, 0, .long }, - .{ .cmps, .np, .m8, .m8, .none, .none, &.{ 0xa6 }, 0, .none }, - .{ .cmps, .np, .m16, .m16, .none, .none, &.{ 0xa7 }, 0, .none }, - .{ .cmps, .np, .m32, .m32, .none, .none, &.{ 0xa7 }, 0, .none }, - .{ .cmps, .np, .m64, .m64, .none, .none, &.{ 0xa7 }, 0, .long }, - .{ .cmpsb, .np, .none, .none, .none, .none, &.{ 0xa6 }, 0, .none }, - .{ .cmpsw, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .short }, - .{ .cmpsd, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .none }, - .{ .cmpsq, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .long }, + .{ .cmps, .np, &.{ .m8, .m8 }, &.{ 0xa6 }, 0, .none }, + .{ .cmps, .np, &.{ .m16, .m16 }, &.{ 0xa7 }, 0, .none }, + .{ .cmps, .np, &.{ .m32, .m32 }, &.{ 0xa7 }, 0, .none }, + .{ .cmps, .np, &.{ .m64, .m64 }, &.{ 0xa7 }, 0, .long }, - .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .none }, - .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .rex }, - .{ .cmpxchg, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb1 }, 0, .none }, - .{ .cmpxchg, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb1 }, 0, .none }, - .{ .cmpxchg, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb1 }, 0, .long }, + .{ .cmpsb, .np, &.{}, &.{ 0xa6 }, 0, .none }, + .{ .cmpsw, .np, &.{}, &.{ 0xa7 }, 0, .short }, + .{ .cmpsd, .np, &.{}, &.{ 0xa7 }, 0, .none }, + .{ .cmpsq, .np, &.{}, &.{ 0xa7 }, 0, .long }, - .{ .cmpxchg8b , .m, .m64, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .none }, - .{ .cmpxchg16b, .m, .m128, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .long }, + .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .none }, + .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .rex }, + .{ .cmpxchg, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xb1 }, 0, .none }, + .{ .cmpxchg, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xb1 }, 0, .none }, + .{ .cmpxchg, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xb1 }, 0, .long }, - .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .none }, - .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .rex }, - .{ .div, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 6, .none }, - .{ .div, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 6, .none }, - .{ .div, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 6, .long }, + .{ .cmpxchg8b , .m, &.{ .m64 }, &.{ 0x0f, 0xc7 }, 1, .none }, + .{ .cmpxchg16b, .m, &.{ .m128 }, &.{ 0x0f, 0xc7 }, 1, .long }, - .{ .fisttp, .m, .m16, .none, .none, .none, &.{ 0xdf }, 1, .fpu }, - .{ .fisttp, .m, .m32, .none, .none, .none, &.{ 0xdb }, 1, .fpu }, - .{ .fisttp, .m, .m64, .none, .none, .none, &.{ 0xdd }, 1, .fpu }, + .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .none }, + .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .rex }, + .{ .div, .m, &.{ .rm16 }, &.{ 0xf7 }, 6, .none }, + .{ .div, .m, &.{ .rm32 }, &.{ 0xf7 }, 6, .none }, + .{ .div, .m, &.{ .rm64 }, &.{ 0xf7 }, 6, .long }, - .{ .fld, .m, .m32, .none, .none, .none, &.{ 0xd9 }, 0, .fpu }, - .{ .fld, .m, .m64, .none, .none, .none, &.{ 0xdd }, 0, .fpu }, - .{ .fld, .m, .m80, .none, .none, .none, &.{ 0xdb }, 5, .fpu }, + .{ .fisttp, .m, &.{ .m16 }, &.{ 0xdf }, 1, .fpu }, + .{ .fisttp, .m, &.{ .m32 }, &.{ 0xdb }, 1, .fpu }, + .{ .fisttp, .m, &.{ .m64 }, &.{ 0xdd }, 1, .fpu }, - .{ .idiv, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 7, .none }, - .{ .idiv, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 7, .rex }, - .{ .idiv, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 7, .none }, - .{ .idiv, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 7, .none }, - .{ .idiv, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 7, .long }, + .{ .fld, .m, &.{ .m32 }, &.{ 0xd9 }, 0, .fpu }, + .{ .fld, .m, &.{ .m64 }, &.{ 0xdd }, 0, .fpu }, + .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .fpu }, - .{ .imul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 5, .none }, - .{ .imul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 5, .rex }, - .{ .imul, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 5, .none }, - .{ .imul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 5, .none }, - .{ .imul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 5, .long }, - .{ .imul, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xaf }, 0, .none }, - .{ .imul, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xaf }, 0, .none }, - .{ .imul, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xaf }, 0, .long }, - .{ .imul, .rmi, .r16, .rm16, .imm8s, .none, &.{ 0x6b }, 0, .none }, - .{ .imul, .rmi, .r32, .rm32, .imm8s, .none, &.{ 0x6b }, 0, .none }, - .{ .imul, .rmi, .r64, .rm64, .imm8s, .none, &.{ 0x6b }, 0, .long }, - .{ .imul, .rmi, .r16, .rm16, .imm16, .none, &.{ 0x69 }, 0, .none }, - .{ .imul, .rmi, .r32, .rm32, .imm32, .none, &.{ 0x69 }, 0, .none }, - .{ .imul, .rmi, .r64, .rm64, .imm32, .none, &.{ 0x69 }, 0, .long }, + .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .none }, + .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .rex }, + .{ .idiv, .m, &.{ .rm16 }, &.{ 0xf7 }, 7, .none }, + .{ .idiv, .m, &.{ .rm32 }, &.{ 0xf7 }, 7, .none }, + .{ .idiv, .m, &.{ .rm64 }, &.{ 0xf7 }, 7, .long }, - .{ .int3, .np, .none, .none, .none, .none, &.{ 0xcc }, 0, .none }, + .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .none }, + .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .rex }, + .{ .imul, .m, &.{ .rm16, }, &.{ 0xf7 }, 5, .none }, + .{ .imul, .m, &.{ .rm32, }, &.{ 0xf7 }, 5, .none }, + .{ .imul, .m, &.{ .rm64, }, &.{ 0xf7 }, 5, .long }, + .{ .imul, .rm, &.{ .r16, .rm16, }, &.{ 0x0f, 0xaf }, 0, .none }, + .{ .imul, .rm, &.{ .r32, .rm32, }, &.{ 0x0f, 0xaf }, 0, .none }, + .{ .imul, .rm, &.{ .r64, .rm64, }, &.{ 0x0f, 0xaf }, 0, .long }, + .{ .imul, .rmi, &.{ .r16, .rm16, .imm8s }, &.{ 0x6b }, 0, .none }, + .{ .imul, .rmi, &.{ .r32, .rm32, .imm8s }, &.{ 0x6b }, 0, .none }, + .{ .imul, .rmi, &.{ .r64, .rm64, .imm8s }, &.{ 0x6b }, 0, .long }, + .{ .imul, .rmi, &.{ .r16, .rm16, .imm16 }, &.{ 0x69 }, 0, .none }, + .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none }, + .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long }, - .{ .ja, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x87 }, 0, .none }, - .{ .jae, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none }, - .{ .jb, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none }, - .{ .jbe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x86 }, 0, .none }, - .{ .jc, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none }, - .{ .jrcxz, .d, .rel32, .none, .none, .none, &.{ 0xe3 }, 0, .none }, - .{ .je, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x84 }, 0, .none }, - .{ .jg, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8f }, 0, .none }, - .{ .jge, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8d }, 0, .none }, - .{ .jl, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8c }, 0, .none }, - .{ .jle, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8e }, 0, .none }, - .{ .jna, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x86 }, 0, .none }, - .{ .jnae, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none }, - .{ .jnb, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none }, - .{ .jnbe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x87 }, 0, .none }, - .{ .jnc, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none }, - .{ .jne, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x85 }, 0, .none }, - .{ .jng, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8e }, 0, .none }, - .{ .jnge, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8c }, 0, .none }, - .{ .jnl, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8d }, 0, .none }, - .{ .jnle, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8f }, 0, .none }, - .{ .jno, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x81 }, 0, .none }, - .{ .jnp, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8b }, 0, .none }, - .{ .jns, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x89 }, 0, .none }, - .{ .jnz, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x85 }, 0, .none }, - .{ .jo, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x80 }, 0, .none }, - .{ .jp, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8a }, 0, .none }, - .{ .jpe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8a }, 0, .none }, - .{ .jpo, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8b }, 0, .none }, - .{ .js, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x88 }, 0, .none }, - .{ .jz, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x84 }, 0, .none }, + .{ .int3, .np, &.{}, &.{ 0xcc }, 0, .none }, - .{ .jmp, .d, .rel32, .none, .none, .none, &.{ 0xe9 }, 0, .none }, - .{ .jmp, .m, .rm64, .none, .none, .none, &.{ 0xff }, 4, .none }, + .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none }, + .{ .jae, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none }, + .{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none }, + .{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none }, + .{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none }, + .{ .jrcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none }, + .{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none }, + .{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none }, + .{ .jge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none }, + .{ .jl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none }, + .{ .jle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none }, + .{ .jna, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none }, + .{ .jnae, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none }, + .{ .jnb, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none }, + .{ .jnbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none }, + .{ .jnc, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none }, + .{ .jne, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none }, + .{ .jng, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none }, + .{ .jnge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none }, + .{ .jnl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none }, + .{ .jnle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none }, + .{ .jno, .d, &.{ .rel32 }, &.{ 0x0f, 0x81 }, 0, .none }, + .{ .jnp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none }, + .{ .jns, .d, &.{ .rel32 }, &.{ 0x0f, 0x89 }, 0, .none }, + .{ .jnz, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none }, + .{ .jo, .d, &.{ .rel32 }, &.{ 0x0f, 0x80 }, 0, .none }, + .{ .jp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none }, + .{ .jpe, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none }, + .{ .jpo, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none }, + .{ .js, .d, &.{ .rel32 }, &.{ 0x0f, 0x88 }, 0, .none }, + .{ .jz, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none }, - .{ .lea, .rm, .r16, .m, .none, .none, &.{ 0x8d }, 0, .none }, - .{ .lea, .rm, .r32, .m, .none, .none, &.{ 0x8d }, 0, .none }, - .{ .lea, .rm, .r64, .m, .none, .none, &.{ 0x8d }, 0, .long }, + .{ .jmp, .d, &.{ .rel32 }, &.{ 0xe9 }, 0, .none }, + .{ .jmp, .m, &.{ .rm64 }, &.{ 0xff }, 4, .none }, - .{ .lfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xe8 }, 0, .none }, + .{ .lea, .rm, &.{ .r16, .m }, &.{ 0x8d }, 0, .none }, + .{ .lea, .rm, &.{ .r32, .m }, &.{ 0x8d }, 0, .none }, + .{ .lea, .rm, &.{ .r64, .m }, &.{ 0x8d }, 0, .long }, - .{ .lods, .np, .m8, .none, .none, .none, &.{ 0xac }, 0, .none }, - .{ .lods, .np, .m16, .none, .none, .none, &.{ 0xad }, 0, .none }, - .{ .lods, .np, .m32, .none, .none, .none, &.{ 0xad }, 0, .none }, - .{ .lods, .np, .m64, .none, .none, .none, &.{ 0xad }, 0, .long }, - .{ .lodsb, .np, .none, .none, .none, .none, &.{ 0xac }, 0, .none }, - .{ .lodsw, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .short }, - .{ .lodsd, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .none }, - .{ .lodsq, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .long }, + .{ .lfence, .np, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none }, - .{ .lzcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, - .{ .lzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, - .{ .lzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .long }, + .{ .lods, .np, &.{ .m8 }, &.{ 0xac }, 0, .none }, + .{ .lods, .np, &.{ .m16 }, &.{ 0xad }, 0, .none }, + .{ .lods, .np, &.{ .m32 }, &.{ 0xad }, 0, .none }, + .{ .lods, .np, &.{ .m64 }, &.{ 0xad }, 0, .long }, - .{ .mfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xf0 }, 0, .none }, + .{ .lodsb, .np, &.{}, &.{ 0xac }, 0, .none }, + .{ .lodsw, .np, &.{}, &.{ 0xad }, 0, .short }, + .{ .lodsd, .np, &.{}, &.{ 0xad }, 0, .none }, + .{ .lodsq, .np, &.{}, &.{ 0xad }, 0, .long }, - .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .none }, - .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .rex }, - .{ .mov, .mr, .rm16, .r16, .none, .none, &.{ 0x89 }, 0, .none }, - .{ .mov, .mr, .rm32, .r32, .none, .none, &.{ 0x89 }, 0, .none }, - .{ .mov, .mr, .rm64, .r64, .none, .none, &.{ 0x89 }, 0, .long }, - .{ .mov, .rm, .r8, .rm8, .none, .none, &.{ 0x8a }, 0, .none }, - .{ .mov, .rm, .r8, .rm8, .none, .none, &.{ 0x8a }, 0, .rex }, - .{ .mov, .rm, .r16, .rm16, .none, .none, &.{ 0x8b }, 0, .none }, - .{ .mov, .rm, .r32, .rm32, .none, .none, &.{ 0x8b }, 0, .none }, - .{ .mov, .rm, .r64, .rm64, .none, .none, &.{ 0x8b }, 0, .long }, - .{ .mov, .mr, .rm16, .sreg, .none, .none, &.{ 0x8c }, 0, .none }, - .{ .mov, .mr, .rm64, .sreg, .none, .none, &.{ 0x8c }, 0, .long }, - .{ .mov, .rm, .sreg, .rm16, .none, .none, &.{ 0x8e }, 0, .none }, - .{ .mov, .rm, .sreg, .rm64, .none, .none, &.{ 0x8e }, 0, .long }, - .{ .mov, .fd, .al, .moffs, .none, .none, &.{ 0xa0 }, 0, .none }, - .{ .mov, .fd, .ax, .moffs, .none, .none, &.{ 0xa1 }, 0, .none }, - .{ .mov, .fd, .eax, .moffs, .none, .none, &.{ 0xa1 }, 0, .none }, - .{ .mov, .fd, .rax, .moffs, .none, .none, &.{ 0xa1 }, 0, .long }, - .{ .mov, .td, .moffs, .al, .none, .none, &.{ 0xa2 }, 0, .none }, - .{ .mov, .td, .moffs, .ax, .none, .none, &.{ 0xa3 }, 0, .none }, - .{ .mov, .td, .moffs, .eax, .none, .none, &.{ 0xa3 }, 0, .none }, - .{ .mov, .td, .moffs, .rax, .none, .none, &.{ 0xa3 }, 0, .long }, - .{ .mov, .oi, .r8, .imm8, .none, .none, &.{ 0xb0 }, 0, .none }, - .{ .mov, .oi, .r8, .imm8, .none, .none, &.{ 0xb0 }, 0, .rex }, - .{ .mov, .oi, .r16, .imm16, .none, .none, &.{ 0xb8 }, 0, .none }, - .{ .mov, .oi, .r32, .imm32, .none, .none, &.{ 0xb8 }, 0, .none }, - .{ .mov, .oi, .r64, .imm64, .none, .none, &.{ 0xb8 }, 0, .long }, - .{ .mov, .mi, .rm8, .imm8, .none, .none, &.{ 0xc6 }, 0, .none }, - .{ .mov, .mi, .rm8, .imm8, .none, .none, &.{ 0xc6 }, 0, .rex }, - .{ .mov, .mi, .rm16, .imm16, .none, .none, &.{ 0xc7 }, 0, .none }, - .{ .mov, .mi, .rm32, .imm32, .none, .none, &.{ 0xc7 }, 0, .none }, - .{ .mov, .mi, .rm64, .imm32s, .none, .none, &.{ 0xc7 }, 0, .long }, + .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, + .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none }, + .{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long }, - .{ .movbe, .rm, .r16, .m16, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .none }, - .{ .movbe, .rm, .r32, .m32, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .none }, - .{ .movbe, .rm, .r64, .m64, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .long }, - .{ .movbe, .mr, .m16, .r16, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .none }, - .{ .movbe, .mr, .m32, .r32, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .none }, - .{ .movbe, .mr, .m64, .r64, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .long }, + .{ .mfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none }, - .{ .movs, .np, .m8, .m8, .none, .none, &.{ 0xa4 }, 0, .none }, - .{ .movs, .np, .m16, .m16, .none, .none, &.{ 0xa5 }, 0, .none }, - .{ .movs, .np, .m32, .m32, .none, .none, &.{ 0xa5 }, 0, .none }, - .{ .movs, .np, .m64, .m64, .none, .none, &.{ 0xa5 }, 0, .long }, - .{ .movsb, .np, .none, .none, .none, .none, &.{ 0xa4 }, 0, .none }, - .{ .movsw, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .short }, - .{ .movsd, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .none }, - .{ .movsq, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .long }, + .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .none }, + .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .rex }, + .{ .mov, .mr, &.{ .rm16, .r16 }, &.{ 0x89 }, 0, .none }, + .{ .mov, .mr, &.{ .rm32, .r32 }, &.{ 0x89 }, 0, .none }, + .{ .mov, .mr, &.{ .rm64, .r64 }, &.{ 0x89 }, 0, .long }, + .{ .mov, .rm, &.{ .r8, .rm8 }, &.{ 0x8a }, 0, .none }, + .{ .mov, .rm, &.{ .r8, .rm8 }, &.{ 0x8a }, 0, .rex }, + .{ .mov, .rm, &.{ .r16, .rm16 }, &.{ 0x8b }, 0, .none }, + .{ .mov, .rm, &.{ .r32, .rm32 }, &.{ 0x8b }, 0, .none }, + .{ .mov, .rm, &.{ .r64, .rm64 }, &.{ 0x8b }, 0, .long }, + .{ .mov, .mr, &.{ .rm16, .sreg }, &.{ 0x8c }, 0, .none }, + .{ .mov, .mr, &.{ .rm64, .sreg }, &.{ 0x8c }, 0, .long }, + .{ .mov, .rm, &.{ .sreg, .rm16 }, &.{ 0x8e }, 0, .none }, + .{ .mov, .rm, &.{ .sreg, .rm64 }, &.{ 0x8e }, 0, .long }, + .{ .mov, .fd, &.{ .al, .moffs }, &.{ 0xa0 }, 0, .none }, + .{ .mov, .fd, &.{ .ax, .moffs }, &.{ 0xa1 }, 0, .none }, + .{ .mov, .fd, &.{ .eax, .moffs }, &.{ 0xa1 }, 0, .none }, + .{ .mov, .fd, &.{ .rax, .moffs }, &.{ 0xa1 }, 0, .long }, + .{ .mov, .td, &.{ .moffs, .al }, &.{ 0xa2 }, 0, .none }, + .{ .mov, .td, &.{ .moffs, .ax }, &.{ 0xa3 }, 0, .none }, + .{ .mov, .td, &.{ .moffs, .eax }, &.{ 0xa3 }, 0, .none }, + .{ .mov, .td, &.{ .moffs, .rax }, &.{ 0xa3 }, 0, .long }, + .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .none }, + .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .rex }, + .{ .mov, .oi, &.{ .r16, .imm16 }, &.{ 0xb8 }, 0, .none }, + .{ .mov, .oi, &.{ .r32, .imm32 }, &.{ 0xb8 }, 0, .none }, + .{ .mov, .oi, &.{ .r64, .imm64 }, &.{ 0xb8 }, 0, .long }, + .{ .mov, .mi, &.{ .rm8, .imm8 }, &.{ 0xc6 }, 0, .none }, + .{ .mov, .mi, &.{ .rm8, .imm8 }, &.{ 0xc6 }, 0, .rex }, + .{ .mov, .mi, &.{ .rm16, .imm16 }, &.{ 0xc7 }, 0, .none }, + .{ .mov, .mi, &.{ .rm32, .imm32 }, &.{ 0xc7 }, 0, .none }, + .{ .mov, .mi, &.{ .rm64, .imm32s }, &.{ 0xc7 }, 0, .long }, - .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none }, - .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex }, - .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none }, - .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex }, - .{ .movsx, .rm, .r64, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .long }, - .{ .movsx, .rm, .r32, .rm16, .none, .none, &.{ 0x0f, 0xbf }, 0, .none }, - .{ .movsx, .rm, .r64, .rm16, .none, .none, &.{ 0x0f, 0xbf }, 0, .long }, + .{ .movbe, .rm, &.{ .r16, .m16 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none }, + .{ .movbe, .rm, &.{ .r32, .m32 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none }, + .{ .movbe, .rm, &.{ .r64, .m64 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .long }, + .{ .movbe, .mr, &.{ .m16, .r16 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none }, + .{ .movbe, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none }, + .{ .movbe, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .long }, + + .{ .movs, .np, &.{ .m8, .m8 }, &.{ 0xa4 }, 0, .none }, + .{ .movs, .np, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .none }, + .{ .movs, .np, &.{ .m32, .m32 }, &.{ 0xa5 }, 0, .none }, + .{ .movs, .np, &.{ .m64, .m64 }, &.{ 0xa5 }, 0, .long }, + + .{ .movsb, .np, &.{}, &.{ 0xa4 }, 0, .none }, + .{ .movsw, .np, &.{}, &.{ 0xa5 }, 0, .short }, + .{ .movsd, .np, &.{}, &.{ 0xa5 }, 0, .none }, + .{ .movsq, .np, &.{}, &.{ 0xa5 }, 0, .long }, + + .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .none }, + .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex }, + .{ .movsx, .rm, &.{ .r32, .rm8 }, &.{ 0x0f, 0xbe }, 0, .none }, + .{ .movsx, .rm, &.{ .r32, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex }, + .{ .movsx, .rm, &.{ .r64, .rm8 }, &.{ 0x0f, 0xbe }, 0, .long }, + .{ .movsx, .rm, &.{ .r32, .rm16 }, &.{ 0x0f, 0xbf }, 0, .none }, + .{ .movsx, .rm, &.{ .r64, .rm16 }, &.{ 0x0f, 0xbf }, 0, .long }, // This instruction is discouraged. - .{ .movsxd, .rm, .r32, .rm32, .none, .none, &.{ 0x63 }, 0, .none }, - .{ .movsxd, .rm, .r64, .rm32, .none, .none, &.{ 0x63 }, 0, .long }, + .{ .movsxd, .rm, &.{ .r32, .rm32 }, &.{ 0x63 }, 0, .none }, + .{ .movsxd, .rm, &.{ .r64, .rm32 }, &.{ 0x63 }, 0, .long }, - .{ .movzx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .none }, - .{ .movzx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .none }, - .{ .movzx, .rm, .r64, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .long }, - .{ .movzx, .rm, .r32, .rm16, .none, .none, &.{ 0x0f, 0xb7 }, 0, .none }, - .{ .movzx, .rm, .r64, .rm16, .none, .none, &.{ 0x0f, 0xb7 }, 0, .long }, + .{ .movzx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .none }, + .{ .movzx, .rm, &.{ .r32, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .none }, + .{ .movzx, .rm, &.{ .r64, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .long }, + .{ .movzx, .rm, &.{ .r32, .rm16 }, &.{ 0x0f, 0xb7 }, 0, .none }, + .{ .movzx, .rm, &.{ .r64, .rm16 }, &.{ 0x0f, 0xb7 }, 0, .long }, - .{ .mul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 4, .none }, - .{ .mul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 4, .rex }, - .{ .mul, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 4, .none }, - .{ .mul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 4, .none }, - .{ .mul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 4, .long }, + .{ .mul, .m, &.{ .rm8 }, &.{ 0xf6 }, 4, .none }, + .{ .mul, .m, &.{ .rm8 }, &.{ 0xf6 }, 4, .rex }, + .{ .mul, .m, &.{ .rm16 }, &.{ 0xf7 }, 4, .none }, + .{ .mul, .m, &.{ .rm32 }, &.{ 0xf7 }, 4, .none }, + .{ .mul, .m, &.{ .rm64 }, &.{ 0xf7 }, 4, .long }, - .{ .neg, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 3, .none }, - .{ .neg, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 3, .rex }, - .{ .neg, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 3, .none }, - .{ .neg, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 3, .none }, - .{ .neg, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 3, .long }, + .{ .neg, .m, &.{ .rm8 }, &.{ 0xf6 }, 3, .none }, + .{ .neg, .m, &.{ .rm8 }, &.{ 0xf6 }, 3, .rex }, + .{ .neg, .m, &.{ .rm16 }, &.{ 0xf7 }, 3, .none }, + .{ .neg, .m, &.{ .rm32 }, &.{ 0xf7 }, 3, .none }, + .{ .neg, .m, &.{ .rm64 }, &.{ 0xf7 }, 3, .long }, - .{ .nop, .np, .none, .none, .none, .none, &.{ 0x90 }, 0, .none }, + .{ .nop, .np, &.{}, &.{ 0x90 }, 0, .none }, - .{ .not, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 2, .none }, - .{ .not, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 2, .rex }, - .{ .not, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 2, .none }, - .{ .not, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 2, .none }, - .{ .not, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 2, .long }, + .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .none }, + .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .rex }, + .{ .not, .m, &.{ .rm16 }, &.{ 0xf7 }, 2, .none }, + .{ .not, .m, &.{ .rm32 }, &.{ 0xf7 }, 2, .none }, + .{ .not, .m, &.{ .rm64 }, &.{ 0xf7 }, 2, .long }, - .{ .@"or", .zi, .al, .imm8, .none, .none, &.{ 0x0c }, 0, .none }, - .{ .@"or", .zi, .ax, .imm16, .none, .none, &.{ 0x0d }, 0, .none }, - .{ .@"or", .zi, .eax, .imm32, .none, .none, &.{ 0x0d }, 0, .none }, - .{ .@"or", .zi, .rax, .imm32s, .none, .none, &.{ 0x0d }, 0, .long }, - .{ .@"or", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 1, .none }, - .{ .@"or", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 1, .rex }, - .{ .@"or", .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 1, .none }, - .{ .@"or", .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 1, .none }, - .{ .@"or", .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 1, .long }, - .{ .@"or", .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 1, .none }, - .{ .@"or", .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 1, .none }, - .{ .@"or", .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 1, .long }, - .{ .@"or", .mr, .rm8, .r8, .none, .none, &.{ 0x08 }, 0, .none }, - .{ .@"or", .mr, .rm8, .r8, .none, .none, &.{ 0x08 }, 0, .rex }, - .{ .@"or", .mr, .rm16, .r16, .none, .none, &.{ 0x09 }, 0, .none }, - .{ .@"or", .mr, .rm32, .r32, .none, .none, &.{ 0x09 }, 0, .none }, - .{ .@"or", .mr, .rm64, .r64, .none, .none, &.{ 0x09 }, 0, .long }, - .{ .@"or", .rm, .r8, .rm8, .none, .none, &.{ 0x0a }, 0, .none }, - .{ .@"or", .rm, .r8, .rm8, .none, .none, &.{ 0x0a }, 0, .rex }, - .{ .@"or", .rm, .r16, .rm16, .none, .none, &.{ 0x0b }, 0, .none }, - .{ .@"or", .rm, .r32, .rm32, .none, .none, &.{ 0x0b }, 0, .none }, - .{ .@"or", .rm, .r64, .rm64, .none, .none, &.{ 0x0b }, 0, .long }, + .{ .@"or", .zi, &.{ .al, .imm8 }, &.{ 0x0c }, 0, .none }, + .{ .@"or", .zi, &.{ .ax, .imm16 }, &.{ 0x0d }, 0, .none }, + .{ .@"or", .zi, &.{ .eax, .imm32 }, &.{ 0x0d }, 0, .none }, + .{ .@"or", .zi, &.{ .rax, .imm32s }, &.{ 0x0d }, 0, .long }, + .{ .@"or", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 1, .none }, + .{ .@"or", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 1, .rex }, + .{ .@"or", .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 1, .none }, + .{ .@"or", .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 1, .none }, + .{ .@"or", .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 1, .long }, + .{ .@"or", .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 1, .none }, + .{ .@"or", .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 1, .none }, + .{ .@"or", .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 1, .long }, + .{ .@"or", .mr, &.{ .rm8, .r8 }, &.{ 0x08 }, 0, .none }, + .{ .@"or", .mr, &.{ .rm8, .r8 }, &.{ 0x08 }, 0, .rex }, + .{ .@"or", .mr, &.{ .rm16, .r16 }, &.{ 0x09 }, 0, .none }, + .{ .@"or", .mr, &.{ .rm32, .r32 }, &.{ 0x09 }, 0, .none }, + .{ .@"or", .mr, &.{ .rm64, .r64 }, &.{ 0x09 }, 0, .long }, + .{ .@"or", .rm, &.{ .r8, .rm8 }, &.{ 0x0a }, 0, .none }, + .{ .@"or", .rm, &.{ .r8, .rm8 }, &.{ 0x0a }, 0, .rex }, + .{ .@"or", .rm, &.{ .r16, .rm16 }, &.{ 0x0b }, 0, .none }, + .{ .@"or", .rm, &.{ .r32, .rm32 }, &.{ 0x0b }, 0, .none }, + .{ .@"or", .rm, &.{ .r64, .rm64 }, &.{ 0x0b }, 0, .long }, - .{ .pop, .o, .r16, .none, .none, .none, &.{ 0x58 }, 0, .none }, - .{ .pop, .o, .r64, .none, .none, .none, &.{ 0x58 }, 0, .none }, - .{ .pop, .m, .rm16, .none, .none, .none, &.{ 0x8f }, 0, .none }, - .{ .pop, .m, .rm64, .none, .none, .none, &.{ 0x8f }, 0, .none }, + .{ .pop, .o, &.{ .r16 }, &.{ 0x58 }, 0, .none }, + .{ .pop, .o, &.{ .r64 }, &.{ 0x58 }, 0, .none }, + .{ .pop, .m, &.{ .rm16 }, &.{ 0x8f }, 0, .none }, + .{ .pop, .m, &.{ .rm64 }, &.{ 0x8f }, 0, .none }, - .{ .popcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none }, - .{ .popcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none }, - .{ .popcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long }, + .{ .popcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none }, + .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none }, + .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long }, - .{ .push, .o, .r16, .none, .none, .none, &.{ 0x50 }, 0, .none }, - .{ .push, .o, .r64, .none, .none, .none, &.{ 0x50 }, 0, .none }, - .{ .push, .m, .rm16, .none, .none, .none, &.{ 0xff }, 6, .none }, - .{ .push, .m, .rm64, .none, .none, .none, &.{ 0xff }, 6, .none }, - .{ .push, .i, .imm8, .none, .none, .none, &.{ 0x6a }, 0, .none }, - .{ .push, .i, .imm16, .none, .none, .none, &.{ 0x68 }, 0, .none }, - .{ .push, .i, .imm32, .none, .none, .none, &.{ 0x68 }, 0, .none }, + .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .none }, + .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none }, + .{ .push, .m, &.{ .rm16 }, &.{ 0xff }, 6, .none }, + .{ .push, .m, &.{ .rm64 }, &.{ 0xff }, 6, .none }, + .{ .push, .i, &.{ .imm8 }, &.{ 0x6a }, 0, .none }, + .{ .push, .i, &.{ .imm16 }, &.{ 0x68 }, 0, .none }, + .{ .push, .i, &.{ .imm32 }, &.{ 0x68 }, 0, .none }, - .{ .ret, .np, .none, .none, .none, .none, &.{ 0xc3 }, 0, .none }, + .{ .ret, .np, &.{}, &.{ 0xc3 }, 0, .none }, - .{ .rcl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 2, .none }, - .{ .rcl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 2, .rex }, - .{ .rcl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 2, .none }, - .{ .rcl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 2, .rex }, - .{ .rcl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 2, .none }, - .{ .rcl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 2, .rex }, - .{ .rcl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 2, .none }, - .{ .rcl, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 2, .none }, - .{ .rcl, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 2, .none }, - .{ .rcl, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 2, .none }, - .{ .rcl, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 2, .long }, - .{ .rcl, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 2, .none }, - .{ .rcl, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 2, .long }, - .{ .rcl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 2, .none }, - .{ .rcl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 2, .long }, + .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .none }, + .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .rex }, + .{ .rcl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 2, .none }, + .{ .rcl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 2, .rex }, + .{ .rcl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 2, .none }, + .{ .rcl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 2, .rex }, + .{ .rcl, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 2, .none }, + .{ .rcl, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 2, .none }, + .{ .rcl, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 2, .none }, + .{ .rcl, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 2, .none }, + .{ .rcl, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 2, .long }, + .{ .rcl, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 2, .none }, + .{ .rcl, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 2, .long }, + .{ .rcl, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 2, .none }, + .{ .rcl, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 2, .long }, - .{ .rcr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 3, .none }, - .{ .rcr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 3, .rex }, - .{ .rcr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 3, .none }, - .{ .rcr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 3, .rex }, - .{ .rcr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 3, .none }, - .{ .rcr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 3, .rex }, - .{ .rcr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 3, .none }, - .{ .rcr, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 3, .none }, - .{ .rcr, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 3, .none }, - .{ .rcr, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 3, .none }, - .{ .rcr, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 3, .long }, - .{ .rcr, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 3, .none }, - .{ .rcr, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 3, .long }, - .{ .rcr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 3, .none }, - .{ .rcr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 3, .long }, + .{ .rcr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 3, .none }, + .{ .rcr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 3, .rex }, + .{ .rcr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 3, .none }, + .{ .rcr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 3, .rex }, + .{ .rcr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 3, .none }, + .{ .rcr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 3, .rex }, + .{ .rcr, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 3, .none }, + .{ .rcr, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 3, .none }, + .{ .rcr, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 3, .none }, + .{ .rcr, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 3, .none }, + .{ .rcr, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 3, .long }, + .{ .rcr, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 3, .none }, + .{ .rcr, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 3, .long }, + .{ .rcr, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 3, .none }, + .{ .rcr, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 3, .long }, - .{ .rol, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 0, .none }, - .{ .rol, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 0, .rex }, - .{ .rol, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 0, .none }, - .{ .rol, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 0, .rex }, - .{ .rol, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 0, .none }, - .{ .rol, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 0, .rex }, - .{ .rol, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 0, .none }, - .{ .rol, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 0, .none }, - .{ .rol, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 0, .none }, - .{ .rol, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 0, .none }, - .{ .rol, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 0, .long }, - .{ .rol, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 0, .none }, - .{ .rol, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 0, .long }, - .{ .rol, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 0, .none }, - .{ .rol, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 0, .long }, + .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .none }, + .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .rex }, + .{ .rol, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 0, .none }, + .{ .rol, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 0, .rex }, + .{ .rol, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 0, .none }, + .{ .rol, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 0, .rex }, + .{ .rol, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 0, .none }, + .{ .rol, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 0, .none }, + .{ .rol, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 0, .none }, + .{ .rol, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 0, .none }, + .{ .rol, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 0, .long }, + .{ .rol, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 0, .none }, + .{ .rol, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 0, .long }, + .{ .rol, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 0, .none }, + .{ .rol, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 0, .long }, - .{ .ror, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 1, .none }, - .{ .ror, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 1, .rex }, - .{ .ror, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 1, .none }, - .{ .ror, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 1, .rex }, - .{ .ror, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 1, .none }, - .{ .ror, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 1, .rex }, - .{ .ror, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 1, .none }, - .{ .ror, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 1, .none }, - .{ .ror, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 1, .none }, - .{ .ror, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 1, .none }, - .{ .ror, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 1, .long }, - .{ .ror, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 1, .none }, - .{ .ror, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 1, .long }, - .{ .ror, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 1, .none }, - .{ .ror, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 1, .long }, + .{ .ror, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 1, .none }, + .{ .ror, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 1, .rex }, + .{ .ror, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 1, .none }, + .{ .ror, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 1, .rex }, + .{ .ror, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 1, .none }, + .{ .ror, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 1, .rex }, + .{ .ror, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 1, .none }, + .{ .ror, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 1, .none }, + .{ .ror, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 1, .none }, + .{ .ror, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 1, .none }, + .{ .ror, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 1, .long }, + .{ .ror, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 1, .none }, + .{ .ror, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 1, .long }, + .{ .ror, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 1, .none }, + .{ .ror, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 1, .long }, - .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none }, - .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex }, - .{ .sal, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, - .{ .sal, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, - .{ .sal, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 4, .long }, - .{ .sal, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .none }, - .{ .sal, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .rex }, - .{ .sal, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, - .{ .sal, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, - .{ .sal, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 4, .long }, - .{ .sal, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .none }, - .{ .sal, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .rex }, - .{ .sal, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, - .{ .sal, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, - .{ .sal, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long }, + .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none }, + .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex }, + .{ .sal, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .none }, + .{ .sal, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 4, .none }, + .{ .sal, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 4, .long }, + .{ .sal, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .none }, + .{ .sal, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .rex }, + .{ .sal, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 4, .none }, + .{ .sal, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 4, .none }, + .{ .sal, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 4, .long }, + .{ .sal, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .none }, + .{ .sal, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .rex }, + .{ .sal, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 4, .none }, + .{ .sal, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 4, .none }, + .{ .sal, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 4, .long }, - .{ .sar, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 7, .none }, - .{ .sar, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 7, .rex }, - .{ .sar, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 7, .none }, - .{ .sar, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 7, .none }, - .{ .sar, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 7, .long }, - .{ .sar, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 7, .none }, - .{ .sar, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 7, .rex }, - .{ .sar, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 7, .none }, - .{ .sar, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 7, .none }, - .{ .sar, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 7, .long }, - .{ .sar, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 7, .none }, - .{ .sar, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 7, .rex }, - .{ .sar, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 7, .none }, - .{ .sar, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 7, .none }, - .{ .sar, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 7, .long }, + .{ .sar, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 7, .none }, + .{ .sar, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 7, .rex }, + .{ .sar, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 7, .none }, + .{ .sar, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 7, .none }, + .{ .sar, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 7, .long }, + .{ .sar, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 7, .none }, + .{ .sar, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 7, .rex }, + .{ .sar, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 7, .none }, + .{ .sar, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 7, .none }, + .{ .sar, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 7, .long }, + .{ .sar, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 7, .none }, + .{ .sar, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 7, .rex }, + .{ .sar, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 7, .none }, + .{ .sar, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 7, .none }, + .{ .sar, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 7, .long }, - .{ .sbb, .zi, .al, .imm8, .none, .none, &.{ 0x1c }, 0, .none }, - .{ .sbb, .zi, .ax, .imm16, .none, .none, &.{ 0x1d }, 0, .none }, - .{ .sbb, .zi, .eax, .imm32, .none, .none, &.{ 0x1d }, 0, .none }, - .{ .sbb, .zi, .rax, .imm32s, .none, .none, &.{ 0x1d }, 0, .long }, - .{ .sbb, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 3, .none }, - .{ .sbb, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 3, .rex }, - .{ .sbb, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 3, .none }, - .{ .sbb, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 3, .none }, - .{ .sbb, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 3, .long }, - .{ .sbb, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 3, .none }, - .{ .sbb, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 3, .none }, - .{ .sbb, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 3, .long }, - .{ .sbb, .mr, .rm8, .r8, .none, .none, &.{ 0x18 }, 0, .none }, - .{ .sbb, .mr, .rm8, .r8, .none, .none, &.{ 0x18 }, 0, .rex }, - .{ .sbb, .mr, .rm16, .r16, .none, .none, &.{ 0x19 }, 0, .none }, - .{ .sbb, .mr, .rm32, .r32, .none, .none, &.{ 0x19 }, 0, .none }, - .{ .sbb, .mr, .rm64, .r64, .none, .none, &.{ 0x19 }, 0, .long }, - .{ .sbb, .rm, .r8, .rm8, .none, .none, &.{ 0x1a }, 0, .none }, - .{ .sbb, .rm, .r8, .rm8, .none, .none, &.{ 0x1a }, 0, .rex }, - .{ .sbb, .rm, .r16, .rm16, .none, .none, &.{ 0x1b }, 0, .none }, - .{ .sbb, .rm, .r32, .rm32, .none, .none, &.{ 0x1b }, 0, .none }, - .{ .sbb, .rm, .r64, .rm64, .none, .none, &.{ 0x1b }, 0, .long }, + .{ .sbb, .zi, &.{ .al, .imm8 }, &.{ 0x1c }, 0, .none }, + .{ .sbb, .zi, &.{ .ax, .imm16 }, &.{ 0x1d }, 0, .none }, + .{ .sbb, .zi, &.{ .eax, .imm32 }, &.{ 0x1d }, 0, .none }, + .{ .sbb, .zi, &.{ .rax, .imm32s }, &.{ 0x1d }, 0, .long }, + .{ .sbb, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 3, .none }, + .{ .sbb, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 3, .rex }, + .{ .sbb, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 3, .none }, + .{ .sbb, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 3, .none }, + .{ .sbb, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 3, .long }, + .{ .sbb, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 3, .none }, + .{ .sbb, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 3, .none }, + .{ .sbb, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 3, .long }, + .{ .sbb, .mr, &.{ .rm8, .r8 }, &.{ 0x18 }, 0, .none }, + .{ .sbb, .mr, &.{ .rm8, .r8 }, &.{ 0x18 }, 0, .rex }, + .{ .sbb, .mr, &.{ .rm16, .r16 }, &.{ 0x19 }, 0, .none }, + .{ .sbb, .mr, &.{ .rm32, .r32 }, &.{ 0x19 }, 0, .none }, + .{ .sbb, .mr, &.{ .rm64, .r64 }, &.{ 0x19 }, 0, .long }, + .{ .sbb, .rm, &.{ .r8, .rm8 }, &.{ 0x1a }, 0, .none }, + .{ .sbb, .rm, &.{ .r8, .rm8 }, &.{ 0x1a }, 0, .rex }, + .{ .sbb, .rm, &.{ .r16, .rm16 }, &.{ 0x1b }, 0, .none }, + .{ .sbb, .rm, &.{ .r32, .rm32 }, &.{ 0x1b }, 0, .none }, + .{ .sbb, .rm, &.{ .r64, .rm64 }, &.{ 0x1b }, 0, .long }, - .{ .scas, .np, .m8, .none, .none, .none, &.{ 0xae }, 0, .none }, - .{ .scas, .np, .m16, .none, .none, .none, &.{ 0xaf }, 0, .none }, - .{ .scas, .np, .m32, .none, .none, .none, &.{ 0xaf }, 0, .none }, - .{ .scas, .np, .m64, .none, .none, .none, &.{ 0xaf }, 0, .long }, - .{ .scasb, .np, .none, .none, .none, .none, &.{ 0xae }, 0, .none }, - .{ .scasw, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .short }, - .{ .scasd, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .none }, - .{ .scasq, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .long }, + .{ .scas, .np, &.{ .m8 }, &.{ 0xae }, 0, .none }, + .{ .scas, .np, &.{ .m16 }, &.{ 0xaf }, 0, .none }, + .{ .scas, .np, &.{ .m32 }, &.{ 0xaf }, 0, .none }, + .{ .scas, .np, &.{ .m64 }, &.{ 0xaf }, 0, .long }, - .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none }, - .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex }, - .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, - .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex }, - .{ .setb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none }, - .{ .setb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex }, - .{ .setbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .none }, - .{ .setbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .rex }, - .{ .setc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none }, - .{ .setc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex }, - .{ .sete, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none }, - .{ .sete, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex }, - .{ .setg, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .none }, - .{ .setg, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .rex }, - .{ .setge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .none }, - .{ .setge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .rex }, - .{ .setl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .none }, - .{ .setl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .rex }, - .{ .setle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .none }, - .{ .setle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .rex }, - .{ .setna, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .none }, - .{ .setna, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .rex }, - .{ .setnae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none }, - .{ .setnae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex }, - .{ .setnb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, - .{ .setnb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex }, - .{ .setnbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none }, - .{ .setnbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex }, - .{ .setnc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none }, - .{ .setnc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex }, - .{ .setne, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .none }, - .{ .setne, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .rex }, - .{ .setng, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .none }, - .{ .setng, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .rex }, - .{ .setnge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .none }, - .{ .setnge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .rex }, - .{ .setnl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .none }, - .{ .setnl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .rex }, - .{ .setnle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .none }, - .{ .setnle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .rex }, - .{ .setno, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x91 }, 0, .none }, - .{ .setno, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x91 }, 0, .rex }, - .{ .setnp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .none }, - .{ .setnp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .rex }, - .{ .setns, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x99 }, 0, .none }, - .{ .setns, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x99 }, 0, .rex }, - .{ .setnz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .none }, - .{ .setnz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .rex }, - .{ .seto, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x90 }, 0, .none }, - .{ .seto, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x90 }, 0, .rex }, - .{ .setp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .none }, - .{ .setp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .rex }, - .{ .setpe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .none }, - .{ .setpe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .rex }, - .{ .setpo, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .none }, - .{ .setpo, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .rex }, - .{ .sets, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x98 }, 0, .none }, - .{ .sets, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x98 }, 0, .rex }, - .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none }, - .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex }, + .{ .scasb, .np, &.{}, &.{ 0xae }, 0, .none }, + .{ .scasw, .np, &.{}, &.{ 0xaf }, 0, .short }, + .{ .scasd, .np, &.{}, &.{ 0xaf }, 0, .none }, + .{ .scasq, .np, &.{}, &.{ 0xaf }, 0, .long }, - .{ .sfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xf8 }, 0, .none }, + .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none }, + .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex }, + .{ .setae, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .none }, + .{ .setae, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .rex }, + .{ .setb, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .none }, + .{ .setb, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .rex }, + .{ .setbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .none }, + .{ .setbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .rex }, + .{ .setc, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .none }, + .{ .setc, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .rex }, + .{ .sete, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .none }, + .{ .sete, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .rex }, + .{ .setg, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .none }, + .{ .setg, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .rex }, + .{ .setge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .none }, + .{ .setge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .rex }, + .{ .setl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .none }, + .{ .setl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .rex }, + .{ .setle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .none }, + .{ .setle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .rex }, + .{ .setna, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .none }, + .{ .setna, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .rex }, + .{ .setnae, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .none }, + .{ .setnae, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .rex }, + .{ .setnb, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .none }, + .{ .setnb, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .rex }, + .{ .setnbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none }, + .{ .setnbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex }, + .{ .setnc, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .none }, + .{ .setnc, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .rex }, + .{ .setne, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .none }, + .{ .setne, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .rex }, + .{ .setng, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .none }, + .{ .setng, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .rex }, + .{ .setnge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .none }, + .{ .setnge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .rex }, + .{ .setnl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .none }, + .{ .setnl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .rex }, + .{ .setnle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .none }, + .{ .setnle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .rex }, + .{ .setno, .m, &.{ .rm8 }, &.{ 0x0f, 0x91 }, 0, .none }, + .{ .setno, .m, &.{ .rm8 }, &.{ 0x0f, 0x91 }, 0, .rex }, + .{ .setnp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .none }, + .{ .setnp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .rex }, + .{ .setns, .m, &.{ .rm8 }, &.{ 0x0f, 0x99 }, 0, .none }, + .{ .setns, .m, &.{ .rm8 }, &.{ 0x0f, 0x99 }, 0, .rex }, + .{ .setnz, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .none }, + .{ .setnz, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .rex }, + .{ .seto, .m, &.{ .rm8 }, &.{ 0x0f, 0x90 }, 0, .none }, + .{ .seto, .m, &.{ .rm8 }, &.{ 0x0f, 0x90 }, 0, .rex }, + .{ .setp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .none }, + .{ .setp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .rex }, + .{ .setpe, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .none }, + .{ .setpe, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .rex }, + .{ .setpo, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .none }, + .{ .setpo, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .rex }, + .{ .sets, .m, &.{ .rm8 }, &.{ 0x0f, 0x98 }, 0, .none }, + .{ .sets, .m, &.{ .rm8 }, &.{ 0x0f, 0x98 }, 0, .rex }, + .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .none }, + .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .rex }, - .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none }, - .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex }, - .{ .shl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, - .{ .shl, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 4, .none }, - .{ .shl, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 4, .long }, - .{ .shl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .none }, - .{ .shl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .rex }, - .{ .shl, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, - .{ .shl, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 4, .none }, - .{ .shl, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 4, .long }, - .{ .shl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .none }, - .{ .shl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .rex }, - .{ .shl, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, - .{ .shl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none }, - .{ .shl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long }, + .{ .sfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none }, - .{ .shld, .mri, .rm16, .r16, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .none }, - .{ .shld, .mrc, .rm16, .r16, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .none }, - .{ .shld, .mri, .rm32, .r32, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .none }, - .{ .shld, .mri, .rm64, .r64, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .long }, - .{ .shld, .mrc, .rm32, .r32, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .none }, - .{ .shld, .mrc, .rm64, .r64, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .long }, + .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none }, + .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex }, + .{ .shl, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .none }, + .{ .shl, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 4, .none }, + .{ .shl, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 4, .long }, + .{ .shl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .none }, + .{ .shl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .rex }, + .{ .shl, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 4, .none }, + .{ .shl, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 4, .none }, + .{ .shl, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 4, .long }, + .{ .shl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .none }, + .{ .shl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .rex }, + .{ .shl, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 4, .none }, + .{ .shl, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 4, .none }, + .{ .shl, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 4, .long }, - .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .none }, - .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .rex }, - .{ .shr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 5, .none }, - .{ .shr, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 5, .none }, - .{ .shr, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 5, .long }, - .{ .shr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 5, .none }, - .{ .shr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 5, .rex }, - .{ .shr, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 5, .none }, - .{ .shr, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 5, .none }, - .{ .shr, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 5, .long }, - .{ .shr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 5, .none }, - .{ .shr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 5, .rex }, - .{ .shr, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 5, .none }, - .{ .shr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 5, .none }, - .{ .shr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 5, .long }, + .{ .shld, .mri, &.{ .rm16, .r16, .imm8 }, &.{ 0x0f, 0xa4 }, 0, .none }, + .{ .shld, .mrc, &.{ .rm16, .r16, .cl }, &.{ 0x0f, 0xa5 }, 0, .none }, + .{ .shld, .mri, &.{ .rm32, .r32, .imm8 }, &.{ 0x0f, 0xa4 }, 0, .none }, + .{ .shld, .mri, &.{ .rm64, .r64, .imm8 }, &.{ 0x0f, 0xa4 }, 0, .long }, + .{ .shld, .mrc, &.{ .rm32, .r32, .cl }, &.{ 0x0f, 0xa5 }, 0, .none }, + .{ .shld, .mrc, &.{ .rm64, .r64, .cl }, &.{ 0x0f, 0xa5 }, 0, .long }, - .{ .shrd, .mri, .rm16, .r16, .imm8, .none, &.{ 0x0f, 0xac }, 0, .none }, - .{ .shrd, .mrc, .rm16, .r16, .cl, .none, &.{ 0x0f, 0xad }, 0, .none }, - .{ .shrd, .mri, .rm32, .r32, .imm8, .none, &.{ 0x0f, 0xac }, 0, .none }, - .{ .shrd, .mri, .rm64, .r64, .imm8, .none, &.{ 0x0f, 0xac }, 0, .long }, - .{ .shrd, .mrc, .rm32, .r32, .cl, .none, &.{ 0x0f, 0xad }, 0, .none }, - .{ .shrd, .mrc, .rm64, .r64, .cl, .none, &.{ 0x0f, 0xad }, 0, .long }, + .{ .shr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 5, .none }, + .{ .shr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 5, .rex }, + .{ .shr, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 5, .none }, + .{ .shr, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 5, .none }, + .{ .shr, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 5, .long }, + .{ .shr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 5, .none }, + .{ .shr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 5, .rex }, + .{ .shr, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 5, .none }, + .{ .shr, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 5, .none }, + .{ .shr, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 5, .long }, + .{ .shr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 5, .none }, + .{ .shr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 5, .rex }, + .{ .shr, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 5, .none }, + .{ .shr, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 5, .none }, + .{ .shr, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 5, .long }, - .{ .stos, .np, .m8, .none, .none, .none, &.{ 0xaa }, 0, .none }, - .{ .stos, .np, .m16, .none, .none, .none, &.{ 0xab }, 0, .none }, - .{ .stos, .np, .m32, .none, .none, .none, &.{ 0xab }, 0, .none }, - .{ .stos, .np, .m64, .none, .none, .none, &.{ 0xab }, 0, .long }, - .{ .stosb, .np, .none, .none, .none, .none, &.{ 0xaa }, 0, .none }, - .{ .stosw, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .short }, - .{ .stosd, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .none }, - .{ .stosq, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .long }, + .{ .shrd, .mri, &.{ .rm16, .r16, .imm8 }, &.{ 0x0f, 0xac }, 0, .none }, + .{ .shrd, .mrc, &.{ .rm16, .r16, .cl }, &.{ 0x0f, 0xad }, 0, .none }, + .{ .shrd, .mri, &.{ .rm32, .r32, .imm8 }, &.{ 0x0f, 0xac }, 0, .none }, + .{ .shrd, .mri, &.{ .rm64, .r64, .imm8 }, &.{ 0x0f, 0xac }, 0, .long }, + .{ .shrd, .mrc, &.{ .rm32, .r32, .cl }, &.{ 0x0f, 0xad }, 0, .none }, + .{ .shrd, .mrc, &.{ .rm64, .r64, .cl }, &.{ 0x0f, 0xad }, 0, .long }, - .{ .sub, .zi, .al, .imm8, .none, .none, &.{ 0x2c }, 0, .none }, - .{ .sub, .zi, .ax, .imm16, .none, .none, &.{ 0x2d }, 0, .none }, - .{ .sub, .zi, .eax, .imm32, .none, .none, &.{ 0x2d }, 0, .none }, - .{ .sub, .zi, .rax, .imm32s, .none, .none, &.{ 0x2d }, 0, .long }, - .{ .sub, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 5, .none }, - .{ .sub, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 5, .rex }, - .{ .sub, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 5, .none }, - .{ .sub, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 5, .none }, - .{ .sub, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 5, .long }, - .{ .sub, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 5, .none }, - .{ .sub, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 5, .none }, - .{ .sub, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 5, .long }, - .{ .sub, .mr, .rm8, .r8, .none, .none, &.{ 0x28 }, 0, .none }, - .{ .sub, .mr, .rm8, .r8, .none, .none, &.{ 0x28 }, 0, .rex }, - .{ .sub, .mr, .rm16, .r16, .none, .none, &.{ 0x29 }, 0, .none }, - .{ .sub, .mr, .rm32, .r32, .none, .none, &.{ 0x29 }, 0, .none }, - .{ .sub, .mr, .rm64, .r64, .none, .none, &.{ 0x29 }, 0, .long }, - .{ .sub, .rm, .r8, .rm8, .none, .none, &.{ 0x2a }, 0, .none }, - .{ .sub, .rm, .r8, .rm8, .none, .none, &.{ 0x2a }, 0, .rex }, - .{ .sub, .rm, .r16, .rm16, .none, .none, &.{ 0x2b }, 0, .none }, - .{ .sub, .rm, .r32, .rm32, .none, .none, &.{ 0x2b }, 0, .none }, - .{ .sub, .rm, .r64, .rm64, .none, .none, &.{ 0x2b }, 0, .long }, + .{ .stos, .np, &.{ .m8 }, &.{ 0xaa }, 0, .none }, + .{ .stos, .np, &.{ .m16 }, &.{ 0xab }, 0, .none }, + .{ .stos, .np, &.{ .m32 }, &.{ 0xab }, 0, .none }, + .{ .stos, .np, &.{ .m64 }, &.{ 0xab }, 0, .long }, - .{ .syscall, .np, .none, .none, .none, .none, &.{ 0x0f, 0x05 }, 0, .none } + .{ .stosb, .np, &.{}, &.{ 0xaa }, 0, .none }, + .{ .stosw, .np, &.{}, &.{ 0xab }, 0, .short }, + .{ .stosd, .np, &.{}, &.{ 0xab }, 0, .none }, + .{ .stosq, .np, &.{}, &.{ 0xab }, 0, .long }, + + .{ .sub, .zi, &.{ .al, .imm8 }, &.{ 0x2c }, 0, .none }, + .{ .sub, .zi, &.{ .ax, .imm16 }, &.{ 0x2d }, 0, .none }, + .{ .sub, .zi, &.{ .eax, .imm32 }, &.{ 0x2d }, 0, .none }, + .{ .sub, .zi, &.{ .rax, .imm32s }, &.{ 0x2d }, 0, .long }, + .{ .sub, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 5, .none }, + .{ .sub, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 5, .rex }, + .{ .sub, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 5, .none }, + .{ .sub, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 5, .none }, + .{ .sub, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 5, .long }, + .{ .sub, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 5, .none }, + .{ .sub, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 5, .none }, + .{ .sub, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 5, .long }, + .{ .sub, .mr, &.{ .rm8, .r8 }, &.{ 0x28 }, 0, .none }, + .{ .sub, .mr, &.{ .rm8, .r8 }, &.{ 0x28 }, 0, .rex }, + .{ .sub, .mr, &.{ .rm16, .r16 }, &.{ 0x29 }, 0, .none }, + .{ .sub, .mr, &.{ .rm32, .r32 }, &.{ 0x29 }, 0, .none }, + .{ .sub, .mr, &.{ .rm64, .r64 }, &.{ 0x29 }, 0, .long }, + .{ .sub, .rm, &.{ .r8, .rm8 }, &.{ 0x2a }, 0, .none }, + .{ .sub, .rm, &.{ .r8, .rm8 }, &.{ 0x2a }, 0, .rex }, + .{ .sub, .rm, &.{ .r16, .rm16 }, &.{ 0x2b }, 0, .none }, + .{ .sub, .rm, &.{ .r32, .rm32 }, &.{ 0x2b }, 0, .none }, + .{ .sub, .rm, &.{ .r64, .rm64 }, &.{ 0x2b }, 0, .long }, + + .{ .syscall, .np, &.{}, &.{ 0x0f, 0x05 }, 0, .none } , - .{ .@"test", .zi, .al, .imm8, .none, .none, &.{ 0xa8 }, 0, .none }, - .{ .@"test", .zi, .ax, .imm16, .none, .none, &.{ 0xa9 }, 0, .none }, - .{ .@"test", .zi, .eax, .imm32, .none, .none, &.{ 0xa9 }, 0, .none }, - .{ .@"test", .zi, .rax, .imm32s, .none, .none, &.{ 0xa9 }, 0, .long }, - .{ .@"test", .mi, .rm8, .imm8, .none, .none, &.{ 0xf6 }, 0, .none }, - .{ .@"test", .mi, .rm8, .imm8, .none, .none, &.{ 0xf6 }, 0, .rex }, - .{ .@"test", .mi, .rm16, .imm16, .none, .none, &.{ 0xf7 }, 0, .none }, - .{ .@"test", .mi, .rm32, .imm32, .none, .none, &.{ 0xf7 }, 0, .none }, - .{ .@"test", .mi, .rm64, .imm32s, .none, .none, &.{ 0xf7 }, 0, .long }, - .{ .@"test", .mr, .rm8, .r8, .none, .none, &.{ 0x84 }, 0, .none }, - .{ .@"test", .mr, .rm8, .r8, .none, .none, &.{ 0x84 }, 0, .rex }, - .{ .@"test", .mr, .rm16, .r16, .none, .none, &.{ 0x85 }, 0, .none }, - .{ .@"test", .mr, .rm32, .r32, .none, .none, &.{ 0x85 }, 0, .none }, - .{ .@"test", .mr, .rm64, .r64, .none, .none, &.{ 0x85 }, 0, .long }, + .{ .@"test", .zi, &.{ .al, .imm8 }, &.{ 0xa8 }, 0, .none }, + .{ .@"test", .zi, &.{ .ax, .imm16 }, &.{ 0xa9 }, 0, .none }, + .{ .@"test", .zi, &.{ .eax, .imm32 }, &.{ 0xa9 }, 0, .none }, + .{ .@"test", .zi, &.{ .rax, .imm32s }, &.{ 0xa9 }, 0, .long }, + .{ .@"test", .mi, &.{ .rm8, .imm8 }, &.{ 0xf6 }, 0, .none }, + .{ .@"test", .mi, &.{ .rm8, .imm8 }, &.{ 0xf6 }, 0, .rex }, + .{ .@"test", .mi, &.{ .rm16, .imm16 }, &.{ 0xf7 }, 0, .none }, + .{ .@"test", .mi, &.{ .rm32, .imm32 }, &.{ 0xf7 }, 0, .none }, + .{ .@"test", .mi, &.{ .rm64, .imm32s }, &.{ 0xf7 }, 0, .long }, + .{ .@"test", .mr, &.{ .rm8, .r8 }, &.{ 0x84 }, 0, .none }, + .{ .@"test", .mr, &.{ .rm8, .r8 }, &.{ 0x84 }, 0, .rex }, + .{ .@"test", .mr, &.{ .rm16, .r16 }, &.{ 0x85 }, 0, .none }, + .{ .@"test", .mr, &.{ .rm32, .r32 }, &.{ 0x85 }, 0, .none }, + .{ .@"test", .mr, &.{ .rm64, .r64 }, &.{ 0x85 }, 0, .long }, - .{ .tzcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .none }, - .{ .tzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .none }, - .{ .tzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .long }, + .{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none }, + .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none }, + .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long }, - .{ .ud2, .np, .none, .none, .none, .none, &.{ 0x0f, 0x0b }, 0, .none }, + .{ .ud2, .np, &.{}, &.{ 0x0f, 0x0b }, 0, .none }, - .{ .xadd, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xc0 }, 0, .none }, - .{ .xadd, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xc0 }, 0, .rex }, - .{ .xadd, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xc1 }, 0, .none }, - .{ .xadd, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xc1 }, 0, .none }, - .{ .xadd, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xc1 }, 0, .long }, + .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .none }, + .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .rex }, + .{ .xadd, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xc1 }, 0, .none }, + .{ .xadd, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xc1 }, 0, .none }, + .{ .xadd, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xc1 }, 0, .long }, - .{ .xchg, .o, .ax, .r16, .none, .none, &.{ 0x90 }, 0, .none }, - .{ .xchg, .o, .r16, .ax, .none, .none, &.{ 0x90 }, 0, .none }, - .{ .xchg, .o, .eax, .r32, .none, .none, &.{ 0x90 }, 0, .none }, - .{ .xchg, .o, .rax, .r64, .none, .none, &.{ 0x90 }, 0, .long }, - .{ .xchg, .o, .r32, .eax, .none, .none, &.{ 0x90 }, 0, .none }, - .{ .xchg, .o, .r64, .rax, .none, .none, &.{ 0x90 }, 0, .long }, - .{ .xchg, .mr, .rm8, .r8, .none, .none, &.{ 0x86 }, 0, .none }, - .{ .xchg, .mr, .rm8, .r8, .none, .none, &.{ 0x86 }, 0, .rex }, - .{ .xchg, .rm, .r8, .rm8, .none, .none, &.{ 0x86 }, 0, .none }, - .{ .xchg, .rm, .r8, .rm8, .none, .none, &.{ 0x86 }, 0, .rex }, - .{ .xchg, .mr, .rm16, .r16, .none, .none, &.{ 0x87 }, 0, .none }, - .{ .xchg, .rm, .r16, .rm16, .none, .none, &.{ 0x87 }, 0, .none }, - .{ .xchg, .mr, .rm32, .r32, .none, .none, &.{ 0x87 }, 0, .none }, - .{ .xchg, .mr, .rm64, .r64, .none, .none, &.{ 0x87 }, 0, .long }, - .{ .xchg, .rm, .r32, .rm32, .none, .none, &.{ 0x87 }, 0, .none }, - .{ .xchg, .rm, .r64, .rm64, .none, .none, &.{ 0x87 }, 0, .long }, + .{ .xchg, .o, &.{ .ax, .r16 }, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, &.{ .r16, .ax }, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, &.{ .eax, .r32 }, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, &.{ .rax, .r64 }, &.{ 0x90 }, 0, .long }, + .{ .xchg, .o, &.{ .r32, .eax }, &.{ 0x90 }, 0, .none }, + .{ .xchg, .o, &.{ .r64, .rax }, &.{ 0x90 }, 0, .long }, + .{ .xchg, .mr, &.{ .rm8, .r8 }, &.{ 0x86 }, 0, .none }, + .{ .xchg, .mr, &.{ .rm8, .r8 }, &.{ 0x86 }, 0, .rex }, + .{ .xchg, .rm, &.{ .r8, .rm8 }, &.{ 0x86 }, 0, .none }, + .{ .xchg, .rm, &.{ .r8, .rm8 }, &.{ 0x86 }, 0, .rex }, + .{ .xchg, .mr, &.{ .rm16, .r16 }, &.{ 0x87 }, 0, .none }, + .{ .xchg, .rm, &.{ .r16, .rm16 }, &.{ 0x87 }, 0, .none }, + .{ .xchg, .mr, &.{ .rm32, .r32 }, &.{ 0x87 }, 0, .none }, + .{ .xchg, .mr, &.{ .rm64, .r64 }, &.{ 0x87 }, 0, .long }, + .{ .xchg, .rm, &.{ .r32, .rm32 }, &.{ 0x87 }, 0, .none }, + .{ .xchg, .rm, &.{ .r64, .rm64 }, &.{ 0x87 }, 0, .long }, - .{ .xor, .zi, .al, .imm8, .none, .none, &.{ 0x34 }, 0, .none }, - .{ .xor, .zi, .ax, .imm16, .none, .none, &.{ 0x35 }, 0, .none }, - .{ .xor, .zi, .eax, .imm32, .none, .none, &.{ 0x35 }, 0, .none }, - .{ .xor, .zi, .rax, .imm32s, .none, .none, &.{ 0x35 }, 0, .long }, - .{ .xor, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 6, .none }, - .{ .xor, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 6, .rex }, - .{ .xor, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 6, .none }, - .{ .xor, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 6, .none }, - .{ .xor, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 6, .long }, - .{ .xor, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 6, .none }, - .{ .xor, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 6, .none }, - .{ .xor, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 6, .long }, - .{ .xor, .mr, .rm8, .r8, .none, .none, &.{ 0x30 }, 0, .none }, - .{ .xor, .mr, .rm8, .r8, .none, .none, &.{ 0x30 }, 0, .rex }, - .{ .xor, .mr, .rm16, .r16, .none, .none, &.{ 0x31 }, 0, .none }, - .{ .xor, .mr, .rm32, .r32, .none, .none, &.{ 0x31 }, 0, .none }, - .{ .xor, .mr, .rm64, .r64, .none, .none, &.{ 0x31 }, 0, .long }, - .{ .xor, .rm, .r8, .rm8, .none, .none, &.{ 0x32 }, 0, .none }, - .{ .xor, .rm, .r8, .rm8, .none, .none, &.{ 0x32 }, 0, .rex }, - .{ .xor, .rm, .r16, .rm16, .none, .none, &.{ 0x33 }, 0, .none }, - .{ .xor, .rm, .r32, .rm32, .none, .none, &.{ 0x33 }, 0, .none }, - .{ .xor, .rm, .r64, .rm64, .none, .none, &.{ 0x33 }, 0, .long }, + .{ .xor, .zi, &.{ .al, .imm8 }, &.{ 0x34 }, 0, .none }, + .{ .xor, .zi, &.{ .ax, .imm16 }, &.{ 0x35 }, 0, .none }, + .{ .xor, .zi, &.{ .eax, .imm32 }, &.{ 0x35 }, 0, .none }, + .{ .xor, .zi, &.{ .rax, .imm32s }, &.{ 0x35 }, 0, .long }, + .{ .xor, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 6, .none }, + .{ .xor, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 6, .rex }, + .{ .xor, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 6, .none }, + .{ .xor, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 6, .none }, + .{ .xor, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 6, .long }, + .{ .xor, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 6, .none }, + .{ .xor, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 6, .none }, + .{ .xor, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 6, .long }, + .{ .xor, .mr, &.{ .rm8, .r8 }, &.{ 0x30 }, 0, .none }, + .{ .xor, .mr, &.{ .rm8, .r8 }, &.{ 0x30 }, 0, .rex }, + .{ .xor, .mr, &.{ .rm16, .r16 }, &.{ 0x31 }, 0, .none }, + .{ .xor, .mr, &.{ .rm32, .r32 }, &.{ 0x31 }, 0, .none }, + .{ .xor, .mr, &.{ .rm64, .r64 }, &.{ 0x31 }, 0, .long }, + .{ .xor, .rm, &.{ .r8, .rm8 }, &.{ 0x32 }, 0, .none }, + .{ .xor, .rm, &.{ .r8, .rm8 }, &.{ 0x32 }, 0, .rex }, + .{ .xor, .rm, &.{ .r16, .rm16 }, &.{ 0x33 }, 0, .none }, + .{ .xor, .rm, &.{ .r32, .rm32 }, &.{ 0x33 }, 0, .none }, + .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long }, // SSE - .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x58 }, 0, .sse }, + .{ .addss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .sse }, - .{ .cmpss, .rmi, .xmm, .xmm_m32, .imm8, .none, &.{ 0xf3, 0x0f, 0xc2 }, 0, .sse }, + .{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .sse }, - .{ .divss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5e }, 0, .sse }, + .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .sse }, - .{ .maxss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5f }, 0, .sse }, + .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .sse }, - .{ .minss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5d }, 0, .sse }, + .{ .minss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .sse }, - .{ .movss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x10 }, 0, .sse }, - .{ .movss, .mr, .xmm_m32, .xmm, .none, .none, &.{ 0xf3, 0x0f, 0x11 }, 0, .sse }, + .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .sse }, + .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .sse }, - .{ .mulss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x59 }, 0, .sse }, + .{ .mulss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .sse }, - .{ .subss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5c }, 0, .sse }, + .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .sse }, - .{ .ucomiss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0x0f, 0x2e }, 0, .sse }, + .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .sse }, // SSE2 - .{ .addsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x58 }, 0, .sse2 }, + .{ .addsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .sse2 }, - .{ .cmpsd, .rmi, .xmm, .xmm_m64, .imm8, .none, &.{ 0xf2, 0x0f, 0xc2 }, 0, .sse2 }, + .{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .sse2 }, - .{ .divsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5e }, 0, .sse2 }, + .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .sse2 }, - .{ .maxsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5f }, 0, .sse2 }, + .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .sse2 }, - .{ .minsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5d }, 0, .sse2 }, + .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .sse2 }, - .{ .movq, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf3, 0x0f, 0x7e }, 0, .sse2 }, - .{ .movq, .mr, .xmm_m64, .xmm, .none, .none, &.{ 0x66, 0x0f, 0xd6 }, 0, .sse2 }, + .{ .movq, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0x7e }, 0, .sse2 }, + .{ .movq, .mr, &.{ .xmm_m64, .xmm }, &.{ 0x66, 0x0f, 0xd6 }, 0, .sse2 }, - .{ .mulsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x59 }, 0, .sse2 }, + .{ .mulsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .sse2 }, - .{ .subsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5c }, 0, .sse2 }, + .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .sse2 }, - .{ .movsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x10 }, 0, .sse2 }, - .{ .movsd, .mr, .xmm_m64, .xmm, .none, .none, &.{ 0xf2, 0x0f, 0x11 }, 0, .sse2 }, + .{ .movsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .sse2 }, + .{ .movsd, .mr, &.{ .xmm_m64, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .sse2 }, - .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0x66, 0x0f, 0x2e }, 0, .sse2 }, + .{ .ucomisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2e }, 0, .sse2 }, // SSE4.1 - .{ .roundss, .rmi, .xmm, .xmm_m32, .imm8, .none, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 }, - .{ .roundsd, .rmi, .xmm, .xmm_m64, .imm8, .none, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 }, + .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 }, + .{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 }, }; // zig fmt: on From 3a516433b0cf94e8aa67819acc49c03e0b72f296 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 03:10:03 -0400 Subject: [PATCH 125/216] x86_64: add live codegen debug --- src/arch/x86_64/CodeGen.zig | 69 ++++++++++++++++++++++++++++++- src/arch/x86_64/encoder.zig | 45 ++++++++++----------- src/print_air.zig | 81 ++++++++++++++++++++++--------------- 3 files changed, 138 insertions(+), 57 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 5ab0e64615..f93cc31b92 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -8,6 +8,7 @@ const link = @import("../../link.zig"); const log = std.log.scoped(.codegen); const math = std.math; const mem = std.mem; +const print_air = @import("../../print_air.zig"); const trace = @import("../../tracy.zig").trace; const Air = @import("../../Air.zig"); @@ -20,6 +21,7 @@ const ErrorMsg = Module.ErrorMsg; const Result = codegen.Result; const Emit = @import("Emit.zig"); const Liveness = @import("../../Liveness.zig"); +const Lower = @import("Lower.zig"); const Mir = @import("Mir.zig"); const Module = @import("../../Module.zig"); const Target = std.Target; @@ -44,6 +46,8 @@ const sse = abi.RegisterClass.sse; const InnerError = CodeGenError || error{OutOfRegisters}; +const debug_wip_mir = false; + gpa: Allocator, air: Air, liveness: Liveness, @@ -103,8 +107,12 @@ air_bookkeeping: @TypeOf(air_bookkeeping_init) = air_bookkeeping_init, /// For mir debug info, maps a mir index to a air index mir_to_air_map: if (builtin.mode == .Debug) std.AutoHashMap(Mir.Inst.Index, Air.Inst.Index) else void, +debug_wip_mir_inst: @TypeOf(debug_wip_mir_inst_init) = debug_wip_mir_inst_init, + const air_bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {}; +const debug_wip_mir_inst_init = if (debug_wip_mir) @as(Mir.Inst.Index, 0) else {}; + pub const MCValue = union(enum) { /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc. /// TODO Look into deleting this tag and using `dead` instead, since every use @@ -267,6 +275,12 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.ty; + if (debug_wip_mir) { + const stderr = std.io.getStdErr().writer(); + fn_owner_decl.renderFullyQualifiedName(mod, stderr) catch {}; + stderr.writeAll(":\n") catch {}; + } + var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); try branch_stack.ensureUnusedCapacity(2); // The outermost branch is used for constants only. @@ -683,6 +697,56 @@ fn asmMemoryRegisterImmediate( }); } +fn printWipMir(self: *Self, stream: anytype, air_inst: ?Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; + if (!debug_wip_mir) return; + + var lower = Lower{ + .allocator = self.gpa, + .mir = .{ + .instructions = self.mir_instructions.slice(), + .extra = self.mir_extra.items, + }, + .target = self.target, + .src_loc = self.src_loc, + }; + var mir_inst = self.debug_wip_mir_inst; + var mir_end = @intCast(Mir.Inst.Index, self.mir_instructions.len); + defer self.debug_wip_mir_inst = mir_end; + while (mir_inst < mir_end) : (mir_inst += 1) { + for (lower.lowerMir(lower.mir.instructions.get(mir_inst)) catch |err| switch (err) { + error.LowerFail => { + defer { + lower.err_msg.?.deinit(self.gpa); + lower.err_msg = null; + } + try stream.print("{s}\n", .{lower.err_msg.?.msg}); + continue; + }, + error.InvalidInstruction, error.CannotEncode => |e| { + try stream.writeAll(switch (e) { + error.InvalidInstruction => "CodeGen failed to find a viable instruction.\n", + error.CannotEncode => "CodeGen failed to encode the instruction.\n", + }); + continue; + }, + else => |e| return e, + }) |lower_inst| { + try stream.writeAll(" | "); + try lower_inst.fmtPrint(stream); + try stream.writeByte('\n'); + } + } + + if (air_inst) |inst| { + print_air.writeInst(stream, inst, mod, self.air, self.liveness); + } +} + +fn dumpWipMir(self: *Self, air_inst: ?Air.Inst.Index) void { + self.printWipMir(std.io.getStdErr().writer(), air_inst) catch return; +} + fn gen(self: *Self) InnerError!void { const cc = self.fn_type.fnCallingConvention(); if (cc != .Naked) { @@ -836,6 +900,8 @@ fn gen(self: *Self) InnerError!void { .ops = undefined, .data = .{ .payload = payload }, }); + + self.dumpWipMir(null); } fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { @@ -845,8 +911,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { const old_air_bookkeeping = self.air_bookkeeping; try self.ensureProcessDeathCapacity(Liveness.bpi); if (builtin.mode == .Debug) { - try self.mir_to_air_map.put(@intCast(u32, self.mir_instructions.len), inst); + try self.mir_to_air_map.put(@intCast(Mir.Inst.Index, self.mir_instructions.len), inst); } + self.dumpWipMir(inst); switch (air_tags[inst]) { // zig fmt: off diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index e7e231c063..663dad8727 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -54,18 +54,17 @@ pub const Instruction = struct { }; } - pub fn fmtPrint(op: Operand, enc_op: Encoding.Op, writer: anytype) !void { + pub fn fmtPrint(op: Operand, enc_op: Encoding.Op, writer: anytype) @TypeOf(writer).Error!void { switch (op) { .none => {}, .reg => |reg| try writer.writeAll(@tagName(reg)), .mem => |mem| switch (mem) { .rip => |rip| { try writer.print("{s} ptr [rip", .{@tagName(rip.ptr_size)}); - if (rip.disp != 0) { - const sign_bit = if (sign(rip.disp) < 0) "-" else "+"; - const disp_abs = try std.math.absInt(rip.disp); - try writer.print(" {s} 0x{x}", .{ sign_bit, disp_abs }); - } + if (rip.disp != 0) try writer.print(" {c} 0x{x}", .{ + @as(u8, if (rip.disp < 0) '-' else '+'), + std.math.absCast(rip.disp), + }); try writer.writeByte(']'); }, .sib => |sib| { @@ -77,27 +76,31 @@ pub const Instruction = struct { try writer.writeByte('['); + var any = false; if (sib.base) |base| { try writer.print("{s}", .{@tagName(base)}); + any = true; } if (sib.scale_index) |si| { - if (sib.base != null) { - try writer.writeAll(" + "); - } + if (any) try writer.writeAll(" + "); try writer.print("{s} * {d}", .{ @tagName(si.index), si.scale }); + any = true; } - if (sib.disp != 0) { - if (sib.base != null or sib.scale_index != null) { - try writer.writeByte(' '); - } - try writer.writeByte(if (sign(sib.disp) < 0) '-' else '+'); - const disp_abs = try std.math.absInt(sib.disp); - try writer.print(" 0x{x}", .{disp_abs}); + if (sib.disp != 0 or !any) { + if (any) + try writer.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')}) + else if (sib.disp < 0) + try writer.writeByte('-'); + try writer.print("0x{x}", .{std.math.absCast(sib.disp)}); + any = true; } try writer.writeByte(']'); }, - .moffs => |moffs| try writer.print("{s}:0x{x}", .{ @tagName(moffs.seg), moffs.offset }), + .moffs => |moffs| try writer.print("{s}:0x{x}", .{ + @tagName(moffs.seg), + moffs.offset, + }), }, .imm => |imm| try writer.print("0x{x}", .{imm.asUnsigned(enc_op.bitSize())}), } @@ -127,10 +130,10 @@ pub const Instruction = struct { return inst; } - pub fn fmtPrint(inst: Instruction, writer: anytype) !void { + pub fn fmtPrint(inst: Instruction, writer: anytype) @TypeOf(writer).Error!void { if (inst.prefix != .none) try writer.print("{s} ", .{@tagName(inst.prefix)}); try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)}); - for (inst.ops, inst.encodings.ops, 0..) |op, enc, i| { + for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| { if (op == .none) break; if (i > 0) try writer.writeByte(','); try writer.writeByte(' '); @@ -390,10 +393,6 @@ pub const Instruction = struct { } }; -inline fn sign(i: anytype) @TypeOf(i) { - return @as(@TypeOf(i), @boolToInt(i > 0)) - @boolToInt(i < 0); -} - pub const LegacyPrefixes = packed struct { /// LOCK prefix_f0: bool = false, diff --git a/src/print_air.zig b/src/print_air.zig index f5c06daae2..8d29a272ca 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -8,7 +8,7 @@ const Type = @import("type.zig").Type; const Air = @import("Air.zig"); const Liveness = @import("Liveness.zig"); -pub fn dump(module: *Module, air: Air, liveness: Liveness) void { +pub fn write(stream: anytype, module: *Module, air: Air, liveness: Liveness) void { const instruction_bytes = air.instructions.len * // Here we don't use @sizeOf(Air.Inst.Data) because it would include // the debug safety tag but we want to measure release size. @@ -23,7 +23,7 @@ pub fn dump(module: *Module, air: Air, liveness: Liveness) void { liveness_special_bytes + tomb_bytes; // zig fmt: off - std.debug.print( + stream.print( \\# Total AIR+Liveness bytes: {} \\# AIR Instructions: {d} ({}) \\# AIR Extra Data: {d} ({}) @@ -40,65 +40,78 @@ pub fn dump(module: *Module, air: Air, liveness: Liveness) void { fmtIntSizeBin(tomb_bytes), liveness.extra.len, fmtIntSizeBin(liveness_extra_bytes), liveness.special.count(), fmtIntSizeBin(liveness_special_bytes), - }); + }) catch return; // zig fmt: on - var arena = std.heap.ArenaAllocator.init(module.gpa); - defer arena.deinit(); var writer: Writer = .{ .module = module, .gpa = module.gpa, - .arena = arena.allocator(), .air = air, .liveness = liveness, .indent = 2, + .skip_body = false, }; - const stream = std.io.getStdErr().writer(); writer.writeAllConstants(stream) catch return; stream.writeByte('\n') catch return; writer.writeBody(stream, air.getMainBody()) catch return; } +pub fn writeInst( + stream: anytype, + inst: Air.Inst.Index, + module: *Module, + air: Air, + liveness: Liveness, +) void { + var writer: Writer = .{ + .module = module, + .gpa = module.gpa, + .air = air, + .liveness = liveness, + .indent = 2, + .skip_body = true, + }; + writer.writeInst(stream, inst) catch return; +} + +pub fn dump(module: *Module, air: Air, liveness: Liveness) void { + write(std.io.getStdErr().writer(), module, air, liveness); +} + +pub fn dumpInst(inst: Air.Inst.Index, module: *Module, air: Air, liveness: Liveness) void { + writeInst(std.io.getStdErr().writer(), inst, module, air, liveness); +} + const Writer = struct { module: *Module, gpa: Allocator, - arena: Allocator, air: Air, liveness: Liveness, indent: usize, + skip_body: bool, fn writeAllConstants(w: *Writer, s: anytype) @TypeOf(s).Error!void { for (w.air.instructions.items(.tag), 0..) |tag, i| { - const inst = @intCast(u32, i); + const inst = @intCast(Air.Inst.Index, i); switch (tag) { - .constant, .const_ty => { - try s.writeByteNTimes(' ', w.indent); - try s.print("%{d} ", .{inst}); - try w.writeInst(s, inst); - try s.writeAll(")\n"); - }, + .constant, .const_ty => try w.writeInst(s, inst), else => continue, } } } fn writeBody(w: *Writer, s: anytype, body: []const Air.Inst.Index) @TypeOf(s).Error!void { - for (body) |inst| { - try s.writeByteNTimes(' ', w.indent); - if (w.liveness.isUnused(inst)) { - try s.print("%{d}!", .{inst}); - } else { - try s.print("%{d} ", .{inst}); - } - try w.writeInst(s, inst); - try s.writeAll(")\n"); - } + for (body) |inst| try w.writeInst(s, inst); } fn writeInst(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { - const tags = w.air.instructions.items(.tag); - const tag = tags[inst]; - try s.print("= {s}(", .{@tagName(tags[inst])}); + const tag = w.air.instructions.items(.tag)[inst]; + try s.writeByteNTimes(' ', w.indent); + try s.print("%{d}{c}= {s}(", .{ + inst, + @as(u8, if (w.liveness.isUnused(inst)) '!' else ' '), + @tagName(tag), + }); switch (tag) { .add, .addwrap, @@ -316,6 +329,7 @@ const Writer = struct { .dbg_block_begin, .dbg_block_end => {}, } + try s.writeAll(")\n"); } fn writeBinOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { @@ -372,6 +386,7 @@ const Writer = struct { const body = w.air.extra[extra.end..][0..extra.data.body_len]; try w.writeType(s, w.air.getRefType(ty_pl.ty)); + if (w.skip_body) return s.writeAll(", ..."); try s.writeAll(", {\n"); const old_indent = w.indent; w.indent += 2; @@ -703,6 +718,7 @@ const Writer = struct { const body = w.air.extra[extra.end..][0..extra.data.body_len]; try w.writeOperand(s, inst, 0, pl_op.operand); + if (w.skip_body) return s.writeAll(", ..."); try s.writeAll(", {\n"); const old_indent = w.indent; w.indent += 2; @@ -721,6 +737,7 @@ const Writer = struct { try s.writeAll(", "); try w.writeType(s, w.air.getRefType(ty_pl.ty)); + if (w.skip_body) return s.writeAll(", ..."); try s.writeAll(", {\n"); const old_indent = w.indent; w.indent += 2; @@ -738,6 +755,7 @@ const Writer = struct { const liveness_condbr = w.liveness.getCondBr(inst); try w.writeOperand(s, inst, 0, pl_op.operand); + if (w.skip_body) return s.writeAll(", ..."); try s.writeAll(", {\n"); const old_indent = w.indent; w.indent += 2; @@ -900,10 +918,7 @@ const Writer = struct { dies: bool, ) @TypeOf(s).Error!void { _ = w; - if (dies) { - try s.print("%{d}!", .{inst}); - } else { - try s.print("%{d}", .{inst}); - } + try s.print("%{d}", .{inst}); + if (dies) try s.writeByte('!'); } }; From 65838fcabeee8f0330425156c31a4711d0e026f7 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 03:11:34 -0400 Subject: [PATCH 126/216] x86_64: implement some binary ops for large values --- src/arch/x86_64/CodeGen.zig | 233 ++++++++++++++++++++++-------------- 1 file changed, 145 insertions(+), 88 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f93cc31b92..2e80226933 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -4010,9 +4010,6 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue .register_overflow => unreachable, .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), .ptr_stack_offset, .stack_offset => |off| { - if (off > math.maxInt(i32)) { - return self.fail("stack offset too large", .{}); - } if (abi_size > 8) { return self.fail("TODO implement {} for stack dst with large ABI", .{mir_tag}); } @@ -4454,9 +4451,6 @@ fn genBinOp( if (lhs_ty.zigTypeTag() == .Vector) { return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)}); } - if (lhs_ty.abiSize(self.target.*) > 8) { - return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)}); - } switch (lhs) { .immediate => |imm| switch (imm) { @@ -4686,7 +4680,6 @@ fn genBinOp( const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_reg_lock); - try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mat_src_mcv); // To get the actual address of the value we want to modify we @@ -4801,9 +4794,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = reg }); }, .stack_offset => |off| { - if (off > math.maxInt(i32)) { - return self.fail("stack offset too large", .{}); - } try self.asmRegisterMemory( mir_tag, registerAlias(dst_reg, abi_size), @@ -4812,78 +4802,155 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s }, } }, - .ptr_stack_offset, .stack_offset => |off| { - if (off > math.maxInt(i32)) { - return self.fail("stack offset too large", .{}); - } - if (abi_size > 8) { - return self.fail("TODO implement {} for stack dst with large ABI", .{mir_tag}); - } + .ptr_stack_offset, .stack_offset => |dst_off| { + const src: ?struct { + limb_reg: Register, + limb_lock: RegisterLock, + addr_reg: Register, + addr_lock: RegisterLock, + } = switch (src_mcv) { + else => null, + .memory, .linker_load => addr: { + const src_limb_reg = try self.register_manager.allocReg(null, gp); + const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); + errdefer self.register_manager.unlockReg(src_limb_lock); - switch (src_mcv) { - .none => unreachable, - .undef => unreachable, - .dead, .unreach => unreachable, - .register_overflow => unreachable, - .register => |src_reg| { - try self.asmMemoryRegister(mir_tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - }), registerAlias(src_reg, abi_size)); + const src_addr_reg = try self.register_manager.allocReg(null, gp); + const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); + errdefer self.register_manager.unlockReg(src_addr_lock); + + try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_mcv); + // To get the actual address of the value we want to modify we + // we have to go through the GOT + try self.asmRegisterMemory( + .mov, + src_addr_reg, + Memory.sib(.qword, .{ .base = src_addr_reg }), + ); + + break :addr .{ + .addr_reg = src_addr_reg, + .addr_lock = src_addr_lock, + .limb_reg = src_limb_reg, + .limb_lock = src_limb_lock, + }; }, - .immediate => |imm| { - switch (self.regBitSize(ty)) { - 8, 16, 32 => { - try self.asmMemoryImmediate( - mir_tag, - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - }), - if (math.cast(i32, @bitCast(i64, imm))) |small| - Immediate.s(small) - else - Immediate.u(@intCast(u32, imm)), - ); - }, - 64 => { - if (math.cast(i32, @bitCast(i64, imm))) |small| { + }; + defer if (src) |locks| { + self.register_manager.unlockReg(locks.limb_lock); + self.register_manager.unlockReg(locks.addr_lock); + }; + + const ty_signedness = + if (ty.isAbiInt()) ty.intInfo(self.target.*).signedness else .unsigned; + const limb_ty = if (abi_size <= 8) ty else switch (ty_signedness) { + .signed => Type.usize, + .unsigned => Type.isize, + }; + const limb_abi_size = @min(abi_size, 8); + var off: i32 = 0; + while (off < abi_size) : (off += 8) { + const mir_limb_tag = switch (off) { + 0 => mir_tag, + else => switch (mir_tag) { + .add => .adc, + .sub => .sbb, + .@"or", .@"and", .xor => mir_tag, + else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{ + @tagName(mir_tag), + }), + }, + }; + const dst_limb_mem = Memory.sib( + Memory.PtrSize.fromSize(limb_abi_size), + .{ .base = .rbp, .disp = off - dst_off }, + ); + switch (src_mcv) { + .none => unreachable, + .undef => unreachable, + .dead, .unreach => unreachable, + .register_overflow => unreachable, + .register => |src_reg| { + assert(off == 0); + try self.asmMemoryRegister( + mir_limb_tag, + dst_limb_mem, + registerAlias(src_reg, limb_abi_size), + ); + }, + .immediate => |src_imm| { + const imm = if (off == 0) src_imm else switch (ty_signedness) { + .signed => @bitCast(u64, @bitCast(i64, src_imm) >> 63), + .unsigned => 0, + }; + switch (self.regBitSize(limb_ty)) { + 8, 16, 32 => { try self.asmMemoryImmediate( - mir_tag, - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - }), - Immediate.s(small), + mir_limb_tag, + dst_limb_mem, + if (math.cast(i32, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u32, imm)), ); - } else { - try self.asmMemoryRegister( - mir_tag, - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - }), - registerAlias(try self.copyToTmpRegister(ty, src_mcv), abi_size), - ); - } - }, - else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}), - } - }, - .memory, - .linker_load, - .stack_offset, - .ptr_stack_offset, - .eflags, - => { - assert(abi_size <= 8); + }, + 64 => { + if (math.cast(i32, @bitCast(i64, imm))) |small| { + try self.asmMemoryImmediate( + mir_limb_tag, + dst_limb_mem, + Immediate.s(small), + ); + } else { + try self.asmMemoryRegister( + mir_limb_tag, + dst_limb_mem, + registerAlias( + try self.copyToTmpRegister(limb_ty, .{ .immediate = imm }), + limb_abi_size, + ), + ); + } + }, + else => unreachable, + } + }, + .memory, .linker_load => { + try self.asmRegisterMemory( + .mov, + registerAlias(src.?.limb_reg, limb_abi_size), + Memory.sib( + Memory.PtrSize.fromSize(limb_abi_size), + .{ .base = src.?.addr_reg, .disp = off }, + ), + ); + try self.asmMemoryRegister( + mir_limb_tag, + dst_limb_mem, + registerAlias(src.?.limb_reg, limb_abi_size), + ); + }, + .stack_offset, .ptr_stack_offset, .eflags => { + const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) { + .stack_offset => |src_off| .{ .stack_offset = src_off - off }, + .ptr_stack_offset, + .eflags, + => off: { + assert(off == 0); + break :off src_mcv; + }, + else => unreachable, + }); + const src_limb_lock = self.register_manager.lockReg(src_limb_reg); + defer if (src_limb_lock) |lock| self.register_manager.unlockReg(lock); - const tmp_reg = try self.copyToTmpRegister(ty, src_mcv); - const tmp_lock = self.register_manager.lockReg(tmp_reg); - defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock); - - return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = tmp_reg }); - }, + try self.asmMemoryRegister( + mir_limb_tag, + dst_limb_mem, + registerAlias(src_limb_reg, limb_abi_size), + ); + }, + } } }, .memory => { @@ -6735,10 +6802,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl } }, .register => |reg| { - if (stack_offset > math.maxInt(i32)) { - return self.fail("stack offset too large", .{}); - } - const base_reg = opts.dest_stack_base orelse .rbp; switch (ty.zigTypeTag()) { @@ -6973,13 +7036,11 @@ fn genInlineMemset( fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { const abi_size = @intCast(u32, ty.abiSize(self.target.*)); + if (abi_size > 8) return self.fail("genSetReg called with a value larger than one register", .{}); switch (mcv) { .dead => unreachable, .register_overflow => unreachable, .ptr_stack_offset => |off| { - if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { - return self.fail("stack offset too large", .{}); - } try self.asmRegisterMemory( .lea, registerAlias(reg, abi_size), @@ -7158,10 +7219,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void }, }, .stack_offset => |off| { - if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { - return self.fail("stack offset too large", .{}); - } - switch (ty.zigTypeTag()) { .Int => switch (ty.intInfo(self.target.*).signedness) { .signed => { From 587eacefec7d00c60cb32a10f7084dd7e61a970a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 03:36:44 -0400 Subject: [PATCH 127/216] x86_64: fix 64-bit multiply by 32-bit immediate --- src/arch/x86_64/CodeGen.zig | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 2e80226933..9128d6ce22 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -4974,6 +4974,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .ptr_stack_offset => unreachable, .register_overflow => unreachable, .register => |dst_reg| { + const dst_alias = registerAlias(dst_reg, abi_size); + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + switch (src_mcv) { .none => unreachable, .undef => try self.genSetReg(dst_ty, dst_reg, .undef), @@ -4982,21 +4986,18 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .register_overflow => unreachable, .register => |src_reg| try self.asmRegisterRegister( .imul, - registerAlias(dst_reg, abi_size), + dst_alias, registerAlias(src_reg, abi_size), ), .immediate => |imm| { - if (math.minInt(i32) <= imm and imm <= math.maxInt(i32)) { - // TODO take into account the type's ABI size when selecting the register alias - // register, immediate + if (std.math.cast(i32, imm)) |small| { try self.asmRegisterRegisterImmediate( .imul, - dst_reg.to32(), - dst_reg.to32(), - Immediate.u(@intCast(u32, imm)), + dst_alias, + dst_alias, + Immediate.s(small), ); } else { - // TODO verify we don't spill and assign to the same register as dst_mcv const src_reg = try self.copyToTmpRegister(dst_ty, src_mcv); return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg }); } @@ -5004,7 +5005,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .stack_offset => |off| { try self.asmRegisterMemory( .imul, - registerAlias(dst_reg, abi_size), + dst_alias, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), ); }, From 6c5442841565196ddeb90735496aad04db3ecdfd Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 04:05:19 -0400 Subject: [PATCH 128/216] x86_64: implement trunc with large source --- src/arch/x86_64/CodeGen.zig | 82 +++++++++++++++---------------------- 1 file changed, 34 insertions(+), 48 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 9128d6ce22..a3615611ba 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1549,43 +1549,31 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - if (self.liveness.isUnused(inst)) - return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); - - const src_ty = self.air.typeOf(ty_op.operand); - const dst_ty = self.air.typeOfIndex(inst); - const operand = try self.resolveInst(ty_op.operand); - - const src_ty_size = src_ty.abiSize(self.target.*); - const dst_ty_size = dst_ty.abiSize(self.target.*); - - if (src_ty_size > 8 or dst_ty_size > 8) { - return self.fail("TODO implement trunc for abi sizes larger than 8", .{}); - } - - const operand_lock: ?RegisterLock = switch (operand) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); - - const reg: Register = blk: { - if (operand.isRegister()) { - if (self.reuseOperand(inst, ty_op.operand, 0, operand)) { - break :blk operand.register.to64(); - } + const result = if (self.liveness.isUnused(inst)) .dead else result: { + const dst_ty = self.air.typeOfIndex(inst); + const dst_abi_size = dst_ty.abiSize(self.target.*); + if (dst_abi_size > 8) { + return self.fail("TODO implement trunc for abi sizes larger than 8", .{}); } - const mcv = try self.copyToRegisterWithInstTracking(inst, src_ty, operand); - break :blk mcv.register.to64(); + + const src_mcv = try self.resolveInst(ty_op.operand); + const src_lock = switch (src_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); + + // when truncating a `u16` to `u5`, for example, those top 3 bits in the result + // have to be removed. this only happens if the dst if not a power-of-two size. + if (self.regExtraBits(dst_ty) > 0) try self.truncateRegister(dst_ty, dst_mcv.register.to64()); + break :result dst_mcv; }; - - // when truncating a `u16` to `u5`, for example, those top 3 bits in the result - // have to be removed. this only happens if the dst if not a power-of-two size. - if (self.regExtraBits(dst_ty) > 0) { - try self.truncateRegister(dst_ty, reg); - } - - return self.finishAir(inst, .{ .register = reg }, .{ ty_op.operand, .none, .none }); + return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void { @@ -3499,23 +3487,21 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { const elem_ty = self.air.typeOfIndex(inst); const elem_size = elem_ty.abiSize(self.target.*); const result: MCValue = result: { - if (!elem_ty.hasRuntimeBitsIgnoreComptime()) - break :result MCValue.none; + if (!elem_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; + + try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); const ptr = try self.resolveInst(ty_op.operand); const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr(); - if (self.liveness.isUnused(inst) and !is_volatile) - break :result MCValue.dead; + if (self.liveness.isUnused(inst) and !is_volatile) break :result .dead; - const dst_mcv: MCValue = blk: { - if (elem_size <= 8 and self.reuseOperand(inst, ty_op.operand, 0, ptr)) { - // The MCValue that holds the pointer can be re-used as the value. - break :blk ptr; - } else { - break :blk try self.allocRegOrMem(inst, true); - } - }; - log.debug("airLoad(%{d}): {} <- {}", .{ inst, dst_mcv, ptr }); + const dst_mcv: MCValue = if (elem_size <= 8 and self.reuseOperand(inst, ty_op.operand, 0, ptr)) + // The MCValue that holds the pointer can be re-used as the value. + ptr + else + try self.allocRegOrMem(inst, true); try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand)); break :result dst_mcv; }; From 802c2e4fae4450679c995767d6409dbc9cf568b3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 04:30:41 -0400 Subject: [PATCH 129/216] x86_64: fix popcnt and disable regressed test --- src/arch/x86_64/CodeGen.zig | 6 +++++- test/behavior/bugs/9584.zig | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index a3615611ba..5f39bc586a 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3095,7 +3095,8 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { }; defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); - const dst_mcv: MCValue = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + const dst_mcv: MCValue = + if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else .{ .register = try self.register_manager.allocReg(inst, gp) }; @@ -5478,6 +5479,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { } const ty = self.air.typeOf(bin_op.lhs); + const abi_size = ty.abiSize(self.target.*); + if (abi_size > 8) return self.fail("TODO implement cmp for large values", .{}); + const signedness: std.builtin.Signedness = blk: { // For non-int types, we treat the values as unsigned if (ty.zigTypeTag() != .Int) break :blk .unsigned; diff --git a/test/behavior/bugs/9584.zig b/test/behavior/bugs/9584.zig index 307f1689bf..fe3dedcd30 100644 --- a/test/behavior/bugs/9584.zig +++ b/test/behavior/bugs/9584.zig @@ -47,6 +47,7 @@ test { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var flags = A{ .a = false, From fd13e44e0c69465cf9ea9ef4fd17dfebf5cffd45 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 05:03:28 -0400 Subject: [PATCH 130/216] x86_64: cleanup debug mir dumping --- src/arch/x86_64/CodeGen.zig | 102 ++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 58 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 5f39bc586a..b071d14447 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -8,7 +8,6 @@ const link = @import("../../link.zig"); const log = std.log.scoped(.codegen); const math = std.math; const mem = std.mem; -const print_air = @import("../../print_air.zig"); const trace = @import("../../tracy.zig").trace; const Air = @import("../../Air.zig"); @@ -107,12 +106,8 @@ air_bookkeeping: @TypeOf(air_bookkeeping_init) = air_bookkeeping_init, /// For mir debug info, maps a mir index to a air index mir_to_air_map: if (builtin.mode == .Debug) std.AutoHashMap(Mir.Inst.Index, Air.Inst.Index) else void, -debug_wip_mir_inst: @TypeOf(debug_wip_mir_inst_init) = debug_wip_mir_inst_init, - const air_bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {}; -const debug_wip_mir_inst_init = if (debug_wip_mir) @as(Mir.Inst.Index, 0) else {}; - pub const MCValue = union(enum) { /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc. /// TODO Look into deleting this tag and using `dead` instead, since every use @@ -395,11 +390,49 @@ pub fn generate( } } +fn dumpWipMir(self: *Self, inst: Mir.Inst) !void { + if (!debug_wip_mir) return; + const stderr = std.io.getStdErr().writer(); + + var lower = Lower{ + .allocator = self.gpa, + .mir = .{ + .instructions = self.mir_instructions.slice(), + .extra = self.mir_extra.items, + }, + .target = self.target, + .src_loc = self.src_loc, + }; + for (lower.lowerMir(inst) catch |err| switch (err) { + error.LowerFail => { + defer { + lower.err_msg.?.deinit(self.gpa); + lower.err_msg = null; + } + try stderr.print("{s}\n", .{lower.err_msg.?.msg}); + return; + }, + error.InvalidInstruction, error.CannotEncode => |e| { + try stderr.writeAll(switch (e) { + error.InvalidInstruction => "CodeGen failed to find a viable instruction.\n", + error.CannotEncode => "CodeGen failed to encode the instruction.\n", + }); + return; + }, + else => |e| return e, + }) |lower_inst| { + try stderr.writeAll(" | "); + try lower_inst.fmtPrint(stderr); + try stderr.writeByte('\n'); + } +} + fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { const gpa = self.gpa; try self.mir_instructions.ensureUnusedCapacity(gpa, 1); const result_index = @intCast(Mir.Inst.Index, self.mir_instructions.len); self.mir_instructions.appendAssumeCapacity(inst); + self.dumpWipMir(inst) catch {}; return result_index; } @@ -697,56 +730,6 @@ fn asmMemoryRegisterImmediate( }); } -fn printWipMir(self: *Self, stream: anytype, air_inst: ?Air.Inst.Index) !void { - const mod = self.bin_file.options.module.?; - if (!debug_wip_mir) return; - - var lower = Lower{ - .allocator = self.gpa, - .mir = .{ - .instructions = self.mir_instructions.slice(), - .extra = self.mir_extra.items, - }, - .target = self.target, - .src_loc = self.src_loc, - }; - var mir_inst = self.debug_wip_mir_inst; - var mir_end = @intCast(Mir.Inst.Index, self.mir_instructions.len); - defer self.debug_wip_mir_inst = mir_end; - while (mir_inst < mir_end) : (mir_inst += 1) { - for (lower.lowerMir(lower.mir.instructions.get(mir_inst)) catch |err| switch (err) { - error.LowerFail => { - defer { - lower.err_msg.?.deinit(self.gpa); - lower.err_msg = null; - } - try stream.print("{s}\n", .{lower.err_msg.?.msg}); - continue; - }, - error.InvalidInstruction, error.CannotEncode => |e| { - try stream.writeAll(switch (e) { - error.InvalidInstruction => "CodeGen failed to find a viable instruction.\n", - error.CannotEncode => "CodeGen failed to encode the instruction.\n", - }); - continue; - }, - else => |e| return e, - }) |lower_inst| { - try stream.writeAll(" | "); - try lower_inst.fmtPrint(stream); - try stream.writeByte('\n'); - } - } - - if (air_inst) |inst| { - print_air.writeInst(stream, inst, mod, self.air, self.liveness); - } -} - -fn dumpWipMir(self: *Self, air_inst: ?Air.Inst.Index) void { - self.printWipMir(std.io.getStdErr().writer(), air_inst) catch return; -} - fn gen(self: *Self) InnerError!void { const cc = self.fn_type.fnCallingConvention(); if (cc != .Naked) { @@ -900,8 +883,6 @@ fn gen(self: *Self) InnerError!void { .ops = undefined, .data = .{ .payload = payload }, }); - - self.dumpWipMir(null); } fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { @@ -913,7 +894,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { if (builtin.mode == .Debug) { try self.mir_to_air_map.put(@intCast(Mir.Inst.Index, self.mir_instructions.len), inst); } - self.dumpWipMir(inst); + if (debug_wip_mir) @import("../../print_air.zig").dumpInst( + inst, + self.bin_file.options.module.?, + self.air, + self.liveness, + ); switch (air_tags[inst]) { // zig fmt: off From d2040b2763ad2684dcacce9acd8f8511bf9db397 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 27 Mar 2023 16:19:43 +0200 Subject: [PATCH 131/216] coff: grow .idata if required --- src/link/Coff.zig | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index f210f2f2b3..2374bf9517 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1625,12 +1625,10 @@ fn writeBaseRelocations(self: *Coff) !void { const needed_size = @intCast(u32, buffer.items.len); if (needed_size > sect_capacity) { const new_offset = self.findFreeSpace(needed_size, default_file_alignment); - log.debug("writing {s} at 0x{x} to 0x{x} (0x{x} - 0x{x})", .{ + log.debug("moving {s} from 0x{x} to 0x{x}", .{ self.getSectionName(header), header.pointer_to_raw_data, - header.pointer_to_raw_data + needed_size, new_offset, - new_offset + needed_size, }); header.pointer_to_raw_data = new_offset; @@ -1656,11 +1654,11 @@ fn writeImportTable(self: *Coff) !void { const gpa = self.base.allocator; - const section = self.sections.get(self.idata_section_index.?); - const last_atom_index = section.last_atom_index orelse return; + const last_atom_index = self.sections.items(.last_atom_index)[self.idata_section_index.?] orelse return; + const header = &self.sections.items(.header)[self.idata_section_index.?]; const last_atom = self.getAtom(last_atom_index); - const iat_rva = section.header.virtual_address; + const iat_rva = header.virtual_address; const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer const dll_name = "KERNEL32.dll"; @@ -1696,9 +1694,18 @@ fn writeImportTable(self: *Coff) !void { try lookup_table.append(.{ .name_table_rva = 0 }); // the sentinel const dir_entry_size = @sizeOf(coff.ImportDirectoryEntry) + lookup_table.items.len * @sizeOf(coff.ImportLookupEntry64.ByName) + names_table.items.len + dll_name.len + 1; - const needed_size = iat_size + dir_entry_size + @sizeOf(coff.ImportDirectoryEntry); - const sect_capacity = self.allocatedSize(section.header.pointer_to_raw_data); - assert(needed_size < sect_capacity); // TODO: implement expanding .idata section + const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); + const needed_size = @intCast(u32, iat_size + dir_entry_size + @sizeOf(coff.ImportDirectoryEntry)); + if (needed_size > sect_capacity) { + const new_offset = self.findFreeSpace(needed_size, default_file_alignment); + log.debug("moving .idata from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset }); + header.pointer_to_raw_data = new_offset; + + const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); + if (needed_size > sect_vm_capacity) { + try self.growSectionVM(self.idata_section_index.?, needed_size); + } + } // Fixup offsets const base_rva = iat_rva + iat_size; @@ -1719,10 +1726,10 @@ fn writeImportTable(self: *Coff) !void { buffer.appendSliceAssumeCapacity(dll_name); buffer.appendAssumeCapacity(0); - try self.base.file.?.pwriteAll(buffer.items, section.header.pointer_to_raw_data + iat_size); + try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data + iat_size); // Override the IAT atoms // TODO: we should rewrite only dirtied atoms, but that's for way later - try self.base.file.?.pwriteAll(mem.sliceAsBytes(lookup_table.items), section.header.pointer_to_raw_data); + try self.base.file.?.pwriteAll(mem.sliceAsBytes(lookup_table.items), header.pointer_to_raw_data); self.data_directories[@enumToInt(coff.DirectoryEntry.IMPORT)] = .{ .virtual_address = iat_rva + iat_size, From 0dc210f950ff926fb8e57288a8ff257abc942b6d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 27 Mar 2023 18:23:25 +0200 Subject: [PATCH 132/216] link: pass expected lib name as hint in getGlobalSymbol() --- src/arch/aarch64/CodeGen.zig | 14 ++++---------- src/arch/wasm/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 14 ++++---------- src/link.zig | 12 +++++++----- src/link/Coff.zig | 3 ++- src/link/MachO.zig | 3 ++- src/link/Wasm.zig | 3 ++- 7 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index e2e2ce9ead..ee23696950 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -4318,16 +4318,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }); } else if (func_value.castTag(.extern_fn)) |func_payload| { const extern_fn = func_payload.data; - const decl_name = mod.declPtr(extern_fn.owner_decl).name; - if (extern_fn.lib_name) |lib_name| { - log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{ - decl_name, - lib_name, - }); - } - + const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); + const lib_name = mem.sliceTo(extern_fn.lib_name, 0); if (self.bin_file.cast(link.File.MachO)) |macho_file| { - const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; _ = try self.addInst(.{ @@ -4340,7 +4334,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }, }); } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { - const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); try self.genSetReg(Type.initTag(.u64), .x30, .{ .linker_load = .{ .type = .import, diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 9af66eb40c..199ddada65 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -6121,7 +6121,7 @@ fn callIntrinsic( args: []const WValue, ) InnerError!WValue { assert(param_types.len == args.len); - const symbol_index = func.bin_file.base.getGlobalSymbol(name) catch |err| { + const symbol_index = func.bin_file.base.getGlobalSymbol(name, null) catch |err| { return func.fail("Could not find or create global symbol '{s}'", .{@errorName(err)}); }; diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b071d14447..5ddc9c77ca 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5317,16 +5317,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier } else unreachable; } else if (func_value.castTag(.extern_fn)) |func_payload| { const extern_fn = func_payload.data; - const decl_name = mod.declPtr(extern_fn.owner_decl).name; - if (extern_fn.lib_name) |lib_name| { - log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{ - decl_name, - lib_name, - }); - } - + const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); + const lib_name = mem.sliceTo(extern_fn.lib_name, 0); if (self.bin_file.cast(link.File.Coff)) |coff_file| { - const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); try self.genSetReg(Type.initTag(.usize), .rax, .{ .linker_load = .{ .type = .import, @@ -5335,7 +5329,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }); try self.asmRegister(.call, .rax); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { - const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; _ = try self.addInst(.{ diff --git a/src/link.zig b/src/link.zig index ae6c02c08b..a7c3ac51bc 100644 --- a/src/link.zig +++ b/src/link.zig @@ -504,18 +504,20 @@ pub const File = struct { /// Called from within CodeGen to retrieve the symbol index of a global symbol. /// If no symbol exists yet with this name, a new undefined global symbol will /// be created. This symbol may get resolved once all relocatables are (re-)linked. - pub fn getGlobalSymbol(base: *File, name: []const u8) UpdateDeclError!u32 { + /// Optionally, it is possible to specify where to expect the symbol defined if it + /// is an import. + pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateDeclError!u32 { if (build_options.only_c) @compileError("unreachable"); - log.debug("getGlobalSymbol '{s}'", .{name}); + log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); switch (base.tag) { // zig fmt: off - .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name), + .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name, lib_name), .elf => unreachable, - .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name), + .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name, lib_name), .plan9 => unreachable, .spirv => unreachable, .c => unreachable, - .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name), + .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name, lib_name), .nvptx => unreachable, // zig fmt: on } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 2374bf9517..8d2a4ad16e 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1526,7 +1526,8 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link return 0; } -pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { +pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name: ?[]const u8) !u32 { + _ = lib_name; const gop = try self.getOrPutGlobalPtr(name); const global_index = self.getGlobalIndex(name).?; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2f594d1fda..885afd37c3 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3202,7 +3202,8 @@ fn insertSection(self: *MachO, segment_index: u8, header: macho.section_64) !u8 return insertion_index; } -pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { +pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { + _ = lib_name; const gpa = self.base.allocator; const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 3561c86ce8..e59b83176c 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1573,7 +1573,8 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In /// such as an exported or imported symbol. /// If the symbol does not yet exist, creates a new one symbol instead /// and then returns the index to it. -pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8) !u32 { +pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 { + _ = lib_name; const name_index = try wasm.string_table.put(wasm.base.allocator, name); const gop = try wasm.globals.getOrPut(wasm.base.allocator, name_index); if (gop.found_existing) { From 2a5c4ea8f08d212b10d4dc8748fbaf5beddecbb6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 27 Mar 2023 20:45:32 +0200 Subject: [PATCH 133/216] coff: repurpose value field of import Symbol for lib_name offset --- src/link/Coff.zig | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 8d2a4ad16e..a87996001e 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -64,6 +64,8 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{}, strtab: StringTable(.strtab) = .{}, strtab_offset: ?u32 = null, +temp_strtab: StringTable(.temp_strtab) = .{}, + got_entries: std.ArrayListUnmanaged(Entry) = .{}, got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, @@ -309,6 +311,7 @@ pub fn deinit(self: *Coff) void { self.locals_free_list.deinit(gpa); self.globals_free_list.deinit(gpa); self.strtab.deinit(gpa); + self.temp_strtab.deinit(gpa); self.got_entries.deinit(gpa); self.got_entries_free_list.deinit(gpa); self.got_entries_table.deinit(gpa); @@ -358,6 +361,8 @@ fn populateMissingMetadata(self: *Coff) !void { try self.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32)); self.strtab.buffer.appendNTimesAssumeCapacity(0, @sizeOf(u32)); + try self.temp_strtab.buffer.append(gpa, 0); + // Index 0 is always a null symbol. try self.locals.append(gpa, .{ .name = [_]u8{0} ** 8, @@ -1526,8 +1531,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link return 0; } -pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name: ?[]const u8) !u32 { - _ = lib_name; +pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8) !u32 { const gop = try self.getOrPutGlobalPtr(name); const global_index = self.getGlobalIndex(name).?; @@ -1544,6 +1548,12 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name: ?[]const u8) !u3 try self.setSymbolName(sym, name); sym.storage_class = .EXTERNAL; + if (lib_name_name) |lib_name| { + // We repurpose the 'value' of the Symbol struct to store an offset into + // temporary string table where we will store the library name hint. + sym.value = try self.temp_strtab.insert(gpa, lib_name); + } + try self.unresolved.putNoClobber(gpa, global_index, true); return global_index; From fb3345e346d26cfac01e45e3662385c587ec3462 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 10:40:19 +0200 Subject: [PATCH 134/216] coff: do not use atoms for synthetic import address table Instead, introduce a custom ImportTable structure which will act as a thunk in the MachO linker, and we will use that to calculate the address of a pointer on-the-fly. Additionally, fix logic in writeImportTables to allow for multiple DLLs. --- src/link/Coff.zig | 368 +++++++++++++++++++++++------------ src/link/Coff/Relocation.zig | 36 ++-- 2 files changed, 258 insertions(+), 146 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index a87996001e..bcc507b02f 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -70,9 +70,10 @@ got_entries: std.ArrayListUnmanaged(Entry) = .{}, got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, -imports: std.ArrayListUnmanaged(Entry) = .{}, -imports_free_list: std.ArrayListUnmanaged(u32) = .{}, -imports_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, +/// A table of ImportTables partitioned by the library name. +/// Key is an offset into the interning string table `temp_strtab`. +import_tables: std.AutoArrayHashMapUnmanaged(u32, ImportTable) = .{}, +imports_count_dirty: bool = true, /// Virtual address of the entry point procedure relative to image base. entry_addr: ?u32 = null, @@ -159,6 +160,92 @@ const Section = struct { free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, }; +/// Represents an import table in the .idata section where each contained pointer +/// is to a symbol from the same DLL. +/// +/// The layout of .idata section is as follows: +/// +/// --- ADDR1 : IAT (all import tables concatenated together) +/// ptr +/// ptr +/// 0 sentinel +/// ptr +/// 0 sentinel +/// --- ADDR2: headers +/// ImportDirectoryEntry header +/// ImportDirectoryEntry header +/// sentinel +/// --- ADDR2: lookup tables +/// Lookup table +/// 0 sentinel +/// Lookup table +/// 0 sentinel +/// --- ADDR3: name hint tables +/// hint-symname +/// hint-symname +/// --- ADDR4: DLL names +/// DLL#1 name +/// DLL#2 name +/// --- END +const ImportTable = struct { + entries: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, + free_list: std.ArrayListUnmanaged(u32) = .{}, + lookup: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, + index: u8, + + const ITable = @This(); + + fn deinit(itab: *ITable, allocator: Allocator) void { + itab.entries.deinit(allocator); + itab.free_list.deinit(allocator); + itab.lookup.deinit(allocator); + } + + fn size(itab: ITable) u32 { + return @intCast(u32, itab.entries.items.len) * @sizeOf(u64); + } + + fn addImport(itab: *ITable, allocator: Allocator, target: SymbolWithLoc) !u32 { + try itab.entries.ensureUnusedCapacity(allocator, 1); + const index: u32 = blk: { + if (itab.free_list.popOrNull()) |index| { + log.debug(" (reusing import entry index {d})", .{index}); + break :blk index; + } else { + log.debug(" (allocating import entry at index {d})", .{itab.entries.items.len}); + const index = @intCast(u32, itab.entries.items.len); + _ = itab.entries.addOneAssumeCapacity(); + break :blk index; + } + }; + itab.entries.items[index] = target; + try itab.lookup.putNoClobber(allocator, target, index); + return index; + } + + fn getBaseAddress(itab: *const ITable, coff_file: *const Coff) u32 { + const header = coff_file.sections.items(.header)[coff_file.idata_section_index.?]; + var addr = header.virtual_address; + for (coff_file.import_tables.values(), 0..) |other_itab, i| { + if (itab.index == i) break; + addr += @intCast(u32, other_itab.entries.items.len * @sizeOf(u64)) + 8; + } + return addr; + } + + pub fn getImportAddress(itab: *const ITable, coff_file: *const Coff, target: SymbolWithLoc) ?u32 { + const index = itab.lookup.get(target) orelse return null; + const base_vaddr = itab.getBaseAddress(coff_file); + return base_vaddr + index * @sizeOf(u64); + } + + pub fn write(itab: ITable, writer: anytype) !void { + for (itab.entries.items) |_| { + try writer.writeIntLittle(u64, 0); + } + } +}; + const DeclMetadata = struct { atom: Atom.Index, section: u16, @@ -315,9 +402,11 @@ pub fn deinit(self: *Coff) void { self.got_entries.deinit(gpa); self.got_entries_free_list.deinit(gpa); self.got_entries_table.deinit(gpa); - self.imports.deinit(gpa); - self.imports_free_list.deinit(gpa); - self.imports_table.deinit(gpa); + + for (self.import_tables.values()) |*itab| { + itab.deinit(gpa); + } + self.import_tables.deinit(gpa); { var it = self.decls.iterator(); @@ -730,28 +819,6 @@ pub fn allocateGotEntry(self: *Coff, target: SymbolWithLoc) !u32 { return index; } -pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 { - const gpa = self.base.allocator; - try self.imports.ensureUnusedCapacity(gpa, 1); - - const index: u32 = blk: { - if (self.imports_free_list.popOrNull()) |index| { - log.debug(" (reusing import entry index {d})", .{index}); - break :blk index; - } else { - log.debug(" (allocating import entry at index {d})", .{self.imports.items.len}); - const index = @intCast(u32, self.imports.items.len); - _ = self.imports.addOneAssumeCapacity(); - break :blk index; - } - }; - - self.imports.items[index] = .{ .target = target, .sym_index = 0 }; - try self.imports_table.putNoClobber(gpa, target, index); - - return index; -} - pub fn createAtom(self: *Coff) !Atom.Index { const gpa = self.base.allocator; const atom_index = @intCast(Atom.Index, self.atoms.items.len); @@ -802,21 +869,6 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !Atom.Index { return atom_index; } -fn createImportAtom(self: *Coff) !Atom.Index { - const atom_index = try self.createAtom(); - const atom = self.getAtomPtr(atom_index); - atom.size = @sizeOf(u64); - atom.alignment = @alignOf(u64); - - const sym = atom.getSymbolPtr(self); - sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1); - sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment); - - log.debug("allocated import atom at 0x{x}", .{sym.value}); - - return atom_index; -} - fn growAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 { const atom = self.getAtom(atom_index); const sym = atom.getSymbol(self); @@ -876,10 +928,8 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { var it = self.relocs.valueIterator(); while (it.next()) |relocs| { for (relocs.items) |*reloc| { - const target_atom_index = reloc.getTargetAtomIndex(self) orelse continue; - const target_atom = self.getAtom(target_atom_index); - const target_sym = target_atom.getSymbol(self); - if (target_sym.value < addr) continue; + const target_vaddr = reloc.getTargetAddress(self) orelse continue; + if (target_vaddr < addr) continue; reloc.dirty = true; } } @@ -1468,35 +1518,42 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod sub_prog_node.activate(); defer sub_prog_node.end(); + const gpa = self.base.allocator; + while (self.unresolved.popOrNull()) |entry| { assert(entry.value); // We only expect imports generated by the incremental linker for now. const global = self.globals.items[entry.key]; - if (self.imports_table.contains(global)) continue; - - const import_index = try self.allocateImportEntry(global); - const import_atom_index = try self.createImportAtom(); - const import_atom = self.getAtom(import_atom_index); - self.imports.items[import_index].sym_index = import_atom.getSymbolIndex().?; - try self.writePtrWidthAtom(import_atom_index); - } - - if (build_options.enable_logging) { - self.logSymtab(); + const sym = self.getSymbol(global); + const res = try self.import_tables.getOrPut(gpa, sym.value); + const itable = res.value_ptr; + if (!res.found_existing) { + itable.* = .{ .index = @intCast(u8, self.import_tables.values().len - 1) }; + } + if (itable.lookup.contains(global)) continue; + // TODO: we could technically write the pointer placeholder for to-be-bound import here, + // but since this happens in flush, there is currently no point. + _ = try itable.addImport(gpa, global); + self.imports_count_dirty = true; } + try self.writeImportTables(); { var it = self.relocs.keyIterator(); while (it.next()) |atom| { try self.resolveRelocs(atom.*); } } - try self.writeImportTable(); try self.writeBaseRelocations(); if (self.getEntryPoint()) |entry_sym_loc| { self.entry_addr = self.getSymbol(entry_sym_loc).value; } + if (build_options.enable_logging) { + self.logSymtab(); + self.logImportTables(); + } + try self.writeStrtab(); try self.writeDataDirectoriesHeaders(); try self.writeSectionHeaders(); @@ -1660,53 +1717,36 @@ fn writeBaseRelocations(self: *Coff) !void { }; } -fn writeImportTable(self: *Coff) !void { +fn writeImportTables(self: *Coff) !void { if (self.idata_section_index == null) return; + if (!self.imports_count_dirty) return; const gpa = self.base.allocator; - const last_atom_index = self.sections.items(.last_atom_index)[self.idata_section_index.?] orelse return; + const ext = ".dll"; const header = &self.sections.items(.header)[self.idata_section_index.?]; - const last_atom = self.getAtom(last_atom_index); - const iat_rva = header.virtual_address; - const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer - - const dll_name = "KERNEL32.dll"; - - var import_dir_entry = coff.ImportDirectoryEntry{ - .import_lookup_table_rva = @sizeOf(coff.ImportDirectoryEntry) * 2, - .time_date_stamp = 0, - .forwarder_chain = 0, - .name_rva = 0, - .import_address_table_rva = iat_rva, - }; - - // TODO: we currently assume there's only one (implicit) DLL - ntdll - var lookup_table = std.ArrayList(coff.ImportLookupEntry64.ByName).init(gpa); - defer lookup_table.deinit(); - - var names_table = std.ArrayList(u8).init(gpa); - defer names_table.deinit(); - - // TODO: check if import is still valid - for (self.imports.items) |entry| { - const target_name = self.getSymbolName(entry.target); - const start = names_table.items.len; - mem.writeIntLittle(u16, try names_table.addManyAsArray(2), 0); // TODO: currently, hint is set to 0 as we haven't yet parsed any DLL - try names_table.appendSlice(target_name); - try names_table.append(0); - const end = names_table.items.len; - if (!mem.isAlignedGeneric(usize, end - start, @sizeOf(u16))) { - try names_table.append(0); + // Calculate needed size + var iat_size: u32 = 0; + var dir_table_size: u32 = @sizeOf(coff.ImportDirectoryEntry); // sentinel + var lookup_table_size: u32 = 0; + var names_table_size: u32 = 0; + var dll_names_size: u32 = 0; + for (self.import_tables.keys(), 0..) |off, i| { + const lib_name = self.temp_strtab.getAssumeExists(off); + const itable = self.import_tables.values()[i]; + iat_size += itable.size() + 8; + dir_table_size += @sizeOf(coff.ImportDirectoryEntry); + lookup_table_size += @intCast(u32, itable.entries.items.len + 1) * @sizeOf(coff.ImportLookupEntry64.ByName); + for (itable.entries.items) |entry| { + const sym_name = self.getSymbolName(entry); + names_table_size += 2 + mem.alignForwardGeneric(u32, @intCast(u32, sym_name.len + 1), 2); } - try lookup_table.append(.{ .name_table_rva = @intCast(u31, start) }); + dll_names_size += @intCast(u32, lib_name.len + ext.len + 1); } - try lookup_table.append(.{ .name_table_rva = 0 }); // the sentinel - const dir_entry_size = @sizeOf(coff.ImportDirectoryEntry) + lookup_table.items.len * @sizeOf(coff.ImportLookupEntry64.ByName) + names_table.items.len + dll_name.len + 1; + const needed_size = iat_size + dir_table_size + lookup_table_size + names_table_size + dll_names_size; const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); - const needed_size = @intCast(u32, iat_size + dir_entry_size + @sizeOf(coff.ImportDirectoryEntry)); if (needed_size > sect_capacity) { const new_offset = self.findFreeSpace(needed_size, default_file_alignment); log.debug("moving .idata from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset }); @@ -1716,41 +1756,105 @@ fn writeImportTable(self: *Coff) !void { if (needed_size > sect_vm_capacity) { try self.growSectionVM(self.idata_section_index.?, needed_size); } + + header.virtual_size = @max(header.virtual_size, needed_size); + header.size_of_raw_data = needed_size; } - // Fixup offsets - const base_rva = iat_rva + iat_size; - import_dir_entry.import_lookup_table_rva += base_rva; - import_dir_entry.name_rva = @intCast(u32, base_rva + dir_entry_size + @sizeOf(coff.ImportDirectoryEntry) - dll_name.len - 1); - - for (lookup_table.items[0 .. lookup_table.items.len - 1]) |*lk| { - lk.name_table_rva += @intCast(u31, base_rva + @sizeOf(coff.ImportDirectoryEntry) * 2 + lookup_table.items.len * @sizeOf(coff.ImportLookupEntry64.ByName)); - } - + // Do the actual writes var buffer = std.ArrayList(u8).init(gpa); defer buffer.deinit(); - try buffer.ensureTotalCapacity(dir_entry_size + @sizeOf(coff.ImportDirectoryEntry)); - buffer.appendSliceAssumeCapacity(mem.asBytes(&import_dir_entry)); - buffer.appendNTimesAssumeCapacity(0, @sizeOf(coff.ImportDirectoryEntry)); // the sentinel; TODO: I think doing all of the above on bytes directly might be cleaner - buffer.appendSliceAssumeCapacity(mem.sliceAsBytes(lookup_table.items)); - buffer.appendSliceAssumeCapacity(names_table.items); - buffer.appendSliceAssumeCapacity(dll_name); - buffer.appendAssumeCapacity(0); + try buffer.ensureTotalCapacityPrecise(needed_size); + buffer.resize(needed_size) catch unreachable; - try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data + iat_size); - // Override the IAT atoms - // TODO: we should rewrite only dirtied atoms, but that's for way later - try self.base.file.?.pwriteAll(mem.sliceAsBytes(lookup_table.items), header.pointer_to_raw_data); + const dir_header_size = @sizeOf(coff.ImportDirectoryEntry); + const lookup_entry_size = @sizeOf(coff.ImportLookupEntry64.ByName); + + var iat_offset: u32 = 0; + var dir_table_offset = iat_size; + var lookup_table_offset = dir_table_offset + dir_table_size; + var names_table_offset = lookup_table_offset + lookup_table_size; + var dll_names_offset = names_table_offset + names_table_size; + for (self.import_tables.keys(), 0..) |off, i| { + const lib_name = self.temp_strtab.getAssumeExists(off); + const itable = self.import_tables.values()[i]; + + // Lookup table header + const lookup_header = coff.ImportDirectoryEntry{ + .import_lookup_table_rva = header.virtual_address + lookup_table_offset, + .time_date_stamp = 0, + .forwarder_chain = 0, + .name_rva = header.virtual_address + dll_names_offset, + .import_address_table_rva = header.virtual_address + iat_offset, + }; + mem.copy(u8, buffer.items[dir_table_offset..], mem.asBytes(&lookup_header)); + dir_table_offset += dir_header_size; + + for (itable.entries.items) |entry| { + const import_name = self.getSymbolName(entry); + + // IAT and lookup table entry + const lookup = coff.ImportLookupEntry64.ByName{ .name_table_rva = @intCast(u31, header.virtual_address + names_table_offset) }; + mem.copy(u8, buffer.items[iat_offset..], mem.asBytes(&lookup)); + iat_offset += lookup_entry_size; + mem.copy(u8, buffer.items[lookup_table_offset..], mem.asBytes(&lookup)); + lookup_table_offset += lookup_entry_size; + + // Names table entry + mem.writeIntLittle(u16, buffer.items[names_table_offset..][0..2], 0); // Hint set to 0 until we learn how to parse DLLs + names_table_offset += 2; + mem.copy(u8, buffer.items[names_table_offset..], import_name); + names_table_offset += @intCast(u32, import_name.len); + buffer.items[names_table_offset] = 0; + names_table_offset += 1; + if (!mem.isAlignedGeneric(usize, names_table_offset, @sizeOf(u16))) { + buffer.items[names_table_offset] = 0; + names_table_offset += 1; + } + } + + // IAT sentinel + mem.writeIntLittle(u64, buffer.items[iat_offset..][0..lookup_entry_size], 0); + iat_offset += 8; + + // Lookup table sentinel + mem.copy(u8, buffer.items[lookup_table_offset..], mem.asBytes(&coff.ImportLookupEntry64.ByName{ .name_table_rva = 0 })); + lookup_table_offset += lookup_entry_size; + + // DLL name + mem.copy(u8, buffer.items[dll_names_offset..], lib_name); + dll_names_offset += @intCast(u32, lib_name.len); + mem.copy(u8, buffer.items[dll_names_offset..], ext); + dll_names_offset += @intCast(u32, ext.len); + buffer.items[dll_names_offset] = 0; + dll_names_offset += 1; + } + + // Sentinel + const lookup_header = coff.ImportDirectoryEntry{ + .import_lookup_table_rva = 0, + .time_date_stamp = 0, + .forwarder_chain = 0, + .name_rva = 0, + .import_address_table_rva = 0, + }; + mem.copy(u8, buffer.items[dir_table_offset..], mem.asBytes(&lookup_header)); + dir_table_offset += dir_header_size; + + assert(dll_names_offset == needed_size); + + try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data); self.data_directories[@enumToInt(coff.DirectoryEntry.IMPORT)] = .{ - .virtual_address = iat_rva + iat_size, - .size = @intCast(u32, @sizeOf(coff.ImportDirectoryEntry) * 2), + .virtual_address = header.virtual_address + iat_size, + .size = dir_table_size, }; - self.data_directories[@enumToInt(coff.DirectoryEntry.IAT)] = .{ - .virtual_address = iat_rva, + .virtual_address = header.virtual_address, .size = iat_size, }; + + self.imports_count_dirty = false; } fn writeStrtab(self: *Coff) !void { @@ -2139,14 +2243,6 @@ pub fn getGotAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom return self.getAtomIndexForSymbol(.{ .sym_index = got_entry.sym_index, .file = null }); } -/// Returns import atom that references `sym_loc` if one exists. -/// Returns null otherwise. -pub fn getImportAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index { - const imports_index = self.imports_table.get(sym_loc) orelse return null; - const imports_entry = self.imports.items[imports_index]; - return self.getAtomIndexForSymbol(.{ .sym_index = imports_entry.sym_index, .file = null }); -} - fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void { if (name.len <= 8) { mem.copy(u8, &header.name, name); @@ -2267,3 +2363,19 @@ fn logSections(self: *Coff) void { }); } } + +fn logImportTables(self: *const Coff) void { + log.debug("import tables:", .{}); + for (self.import_tables.keys(), 0..) |off, i| { + const lib_name = self.temp_strtab.getAssumeExists(off); + const itable = self.import_tables.values()[i]; + log.debug("IAT({s}) @{x}:", .{ lib_name, itable.getBaseAddress(self) }); + for (itable.entries.items, 0..) |entry, j| { + log.debug(" {d}@{?x} => {s}", .{ + j, + itable.getImportAddress(self, entry), + self.getSymbolName(entry), + }); + } + } +} diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 1ba1d7a1c1..5dcb0552fc 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -45,23 +45,25 @@ pcrel: bool, length: u2, dirty: bool = true, -/// Returns an Atom which is the target node of this relocation edge (if any). -pub fn getTargetAtomIndex(self: Relocation, coff_file: *const Coff) ?Atom.Index { +/// Returns address of the target if any. +pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { switch (self.type) { - .got, - .got_page, - .got_pageoff, - => return coff_file.getGotAtomIndexForSymbol(self.target), + .got, .got_page, .got_pageoff, .direct, .page, .pageoff => { + const maybe_target_atom_index = switch (self.type) { + .got, .got_page, .got_pageoff => coff_file.getGotAtomIndexForSymbol(self.target), + .direct, .page, .pageoff => coff_file.getAtomIndexForSymbol(self.target), + else => unreachable, + }; + const target_atom_index = maybe_target_atom_index orelse return null; + const target_atom = coff_file.getAtom(target_atom_index); + return target_atom.getSymbol(coff_file).value; + }, - .direct, - .page, - .pageoff, - => return coff_file.getAtomIndexForSymbol(self.target), - - .import, - .import_page, - .import_pageoff, - => return coff_file.getImportAtomIndexForSymbol(self.target), + .import, .import_page, .import_pageoff => { + const sym = coff_file.getSymbol(self.target); + const itab = coff_file.import_tables.get(sym.value) orelse return null; + return itab.getImportAddress(coff_file, self.target); + }, } } @@ -73,9 +75,7 @@ pub fn resolve(self: *Relocation, atom_index: Atom.Index, coff_file: *Coff) !voi const file_offset = source_section.pointer_to_raw_data + source_sym.value - source_section.virtual_address; - const target_atom_index = self.getTargetAtomIndex(coff_file) orelse return; - const target_atom = coff_file.getAtom(target_atom_index); - const target_vaddr = target_atom.getSymbol(coff_file).value; + const target_vaddr = self.getTargetAddress(coff_file) orelse return; const target_vaddr_with_addend = target_vaddr + self.addend; log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) (in file at 0x{x})", .{ From 5d63d1115f0f18984ed7c517c2d85224aa4da444 Mon Sep 17 00:00:00 2001 From: Tw Date: Tue, 28 Mar 2023 16:22:22 +0800 Subject: [PATCH 135/216] bpf: add missing *const for helper functions Signed-off-by: Tw --- lib/std/os/linux/bpf/helpers.zig | 282 +++++++++++++++---------------- 1 file changed, 141 insertions(+), 141 deletions(-) diff --git a/lib/std/os/linux/bpf/helpers.zig b/lib/std/os/linux/bpf/helpers.zig index 720af2ddf9..dafd4de69f 100644 --- a/lib/std/os/linux/bpf/helpers.zig +++ b/lib/std/os/linux/bpf/helpers.zig @@ -11,147 +11,147 @@ const SkFullSock = @compileError("TODO missing os bits: SkFullSock"); // // Note, these function signatures were created from documentation found in // '/usr/include/linux/bpf.h' -pub const map_lookup_elem = @intToPtr(fn (map: *const kern.MapDef, key: ?*const anyopaque) ?*anyopaque, 1); -pub const map_update_elem = @intToPtr(fn (map: *const kern.MapDef, key: ?*const anyopaque, value: ?*const anyopaque, flags: u64) c_long, 2); -pub const map_delete_elem = @intToPtr(fn (map: *const kern.MapDef, key: ?*const anyopaque) c_long, 3); -pub const probe_read = @intToPtr(fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 4); -pub const ktime_get_ns = @intToPtr(fn () u64, 5); -pub const trace_printk = @intToPtr(fn (fmt: [*:0]const u8, fmt_size: u32, arg1: u64, arg2: u64, arg3: u64) c_long, 6); -pub const get_prandom_u32 = @intToPtr(fn () u32, 7); -pub const get_smp_processor_id = @intToPtr(fn () u32, 8); -pub const skb_store_bytes = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: ?*const anyopaque, len: u32, flags: u64) c_long, 9); -pub const l3_csum_replace = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: u64, to: u64, size: u64) c_long, 10); -pub const l4_csum_replace = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: u64, to: u64, flags: u64) c_long, 11); -pub const tail_call = @intToPtr(fn (ctx: ?*anyopaque, prog_array_map: *const kern.MapDef, index: u32) c_long, 12); -pub const clone_redirect = @intToPtr(fn (skb: *kern.SkBuff, ifindex: u32, flags: u64) c_long, 13); -pub const get_current_pid_tgid = @intToPtr(fn () u64, 14); -pub const get_current_uid_gid = @intToPtr(fn () u64, 15); -pub const get_current_comm = @intToPtr(fn (buf: ?*anyopaque, size_of_buf: u32) c_long, 16); -pub const get_cgroup_classid = @intToPtr(fn (skb: *kern.SkBuff) u32, 17); +pub const map_lookup_elem = @intToPtr(*const fn (map: *const kern.MapDef, key: ?*const anyopaque) ?*anyopaque, 1); +pub const map_update_elem = @intToPtr(*const fn (map: *const kern.MapDef, key: ?*const anyopaque, value: ?*const anyopaque, flags: u64) c_long, 2); +pub const map_delete_elem = @intToPtr(*const fn (map: *const kern.MapDef, key: ?*const anyopaque) c_long, 3); +pub const probe_read = @intToPtr(*const fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 4); +pub const ktime_get_ns = @intToPtr(*const fn () u64, 5); +pub const trace_printk = @intToPtr(*const fn (fmt: [*:0]const u8, fmt_size: u32, arg1: u64, arg2: u64, arg3: u64) c_long, 6); +pub const get_prandom_u32 = @intToPtr(*const fn () u32, 7); +pub const get_smp_processor_id = @intToPtr(*const fn () u32, 8); +pub const skb_store_bytes = @intToPtr(*const fn (skb: *kern.SkBuff, offset: u32, from: ?*const anyopaque, len: u32, flags: u64) c_long, 9); +pub const l3_csum_replace = @intToPtr(*const fn (skb: *kern.SkBuff, offset: u32, from: u64, to: u64, size: u64) c_long, 10); +pub const l4_csum_replace = @intToPtr(*const fn (skb: *kern.SkBuff, offset: u32, from: u64, to: u64, flags: u64) c_long, 11); +pub const tail_call = @intToPtr(*const fn (ctx: ?*anyopaque, prog_array_map: *const kern.MapDef, index: u32) c_long, 12); +pub const clone_redirect = @intToPtr(*const fn (skb: *kern.SkBuff, ifindex: u32, flags: u64) c_long, 13); +pub const get_current_pid_tgid = @intToPtr(*const fn () u64, 14); +pub const get_current_uid_gid = @intToPtr(*const fn () u64, 15); +pub const get_current_comm = @intToPtr(*const fn (buf: ?*anyopaque, size_of_buf: u32) c_long, 16); +pub const get_cgroup_classid = @intToPtr(*const fn (skb: *kern.SkBuff) u32, 17); // Note vlan_proto is big endian -pub const skb_vlan_push = @intToPtr(fn (skb: *kern.SkBuff, vlan_proto: u16, vlan_tci: u16) c_long, 18); -pub const skb_vlan_pop = @intToPtr(fn (skb: *kern.SkBuff) c_long, 19); -pub const skb_get_tunnel_key = @intToPtr(fn (skb: *kern.SkBuff, key: *kern.TunnelKey, size: u32, flags: u64) c_long, 20); -pub const skb_set_tunnel_key = @intToPtr(fn (skb: *kern.SkBuff, key: *kern.TunnelKey, size: u32, flags: u64) c_long, 21); -pub const perf_event_read = @intToPtr(fn (map: *const kern.MapDef, flags: u64) u64, 22); -pub const redirect = @intToPtr(fn (ifindex: u32, flags: u64) c_long, 23); -pub const get_route_realm = @intToPtr(fn (skb: *kern.SkBuff) u32, 24); -pub const perf_event_output = @intToPtr(fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64, data: ?*anyopaque, size: u64) c_long, 25); -pub const skb_load_bytes = @intToPtr(fn (skb: ?*anyopaque, offset: u32, to: ?*anyopaque, len: u32) c_long, 26); -pub const get_stackid = @intToPtr(fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64) c_long, 27); +pub const skb_vlan_push = @intToPtr(*const fn (skb: *kern.SkBuff, vlan_proto: u16, vlan_tci: u16) c_long, 18); +pub const skb_vlan_pop = @intToPtr(*const fn (skb: *kern.SkBuff) c_long, 19); +pub const skb_get_tunnel_key = @intToPtr(*const fn (skb: *kern.SkBuff, key: *kern.TunnelKey, size: u32, flags: u64) c_long, 20); +pub const skb_set_tunnel_key = @intToPtr(*const fn (skb: *kern.SkBuff, key: *kern.TunnelKey, size: u32, flags: u64) c_long, 21); +pub const perf_event_read = @intToPtr(*const fn (map: *const kern.MapDef, flags: u64) u64, 22); +pub const redirect = @intToPtr(*const fn (ifindex: u32, flags: u64) c_long, 23); +pub const get_route_realm = @intToPtr(*const fn (skb: *kern.SkBuff) u32, 24); +pub const perf_event_output = @intToPtr(*const fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64, data: ?*anyopaque, size: u64) c_long, 25); +pub const skb_load_bytes = @intToPtr(*const fn (skb: ?*anyopaque, offset: u32, to: ?*anyopaque, len: u32) c_long, 26); +pub const get_stackid = @intToPtr(*const fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64) c_long, 27); // from and to point to __be32 -pub const csum_diff = @intToPtr(fn (from: *u32, from_size: u32, to: *u32, to_size: u32, seed: u32) i64, 28); -pub const skb_get_tunnel_opt = @intToPtr(fn (skb: *kern.SkBuff, opt: ?*anyopaque, size: u32) c_long, 29); -pub const skb_set_tunnel_opt = @intToPtr(fn (skb: *kern.SkBuff, opt: ?*anyopaque, size: u32) c_long, 30); +pub const csum_diff = @intToPtr(*const fn (from: *u32, from_size: u32, to: *u32, to_size: u32, seed: u32) i64, 28); +pub const skb_get_tunnel_opt = @intToPtr(*const fn (skb: *kern.SkBuff, opt: ?*anyopaque, size: u32) c_long, 29); +pub const skb_set_tunnel_opt = @intToPtr(*const fn (skb: *kern.SkBuff, opt: ?*anyopaque, size: u32) c_long, 30); // proto is __be16 -pub const skb_change_proto = @intToPtr(fn (skb: *kern.SkBuff, proto: u16, flags: u64) c_long, 31); -pub const skb_change_type = @intToPtr(fn (skb: *kern.SkBuff, skb_type: u32) c_long, 32); -pub const skb_under_cgroup = @intToPtr(fn (skb: *kern.SkBuff, map: ?*const anyopaque, index: u32) c_long, 33); -pub const get_hash_recalc = @intToPtr(fn (skb: *kern.SkBuff) u32, 34); -pub const get_current_task = @intToPtr(fn () u64, 35); -pub const probe_write_user = @intToPtr(fn (dst: ?*anyopaque, src: ?*const anyopaque, len: u32) c_long, 36); -pub const current_task_under_cgroup = @intToPtr(fn (map: *const kern.MapDef, index: u32) c_long, 37); -pub const skb_change_tail = @intToPtr(fn (skb: *kern.SkBuff, len: u32, flags: u64) c_long, 38); -pub const skb_pull_data = @intToPtr(fn (skb: *kern.SkBuff, len: u32) c_long, 39); -pub const csum_update = @intToPtr(fn (skb: *kern.SkBuff, csum: u32) i64, 40); -pub const set_hash_invalid = @intToPtr(fn (skb: *kern.SkBuff) void, 41); -pub const get_numa_node_id = @intToPtr(fn () c_long, 42); -pub const skb_change_head = @intToPtr(fn (skb: *kern.SkBuff, len: u32, flags: u64) c_long, 43); -pub const xdp_adjust_head = @intToPtr(fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 44); -pub const probe_read_str = @intToPtr(fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 45); -pub const get_socket_cookie = @intToPtr(fn (ctx: ?*anyopaque) u64, 46); -pub const get_socket_uid = @intToPtr(fn (skb: *kern.SkBuff) u32, 47); -pub const set_hash = @intToPtr(fn (skb: *kern.SkBuff, hash: u32) c_long, 48); -pub const setsockopt = @intToPtr(fn (bpf_socket: *kern.SockOps, level: c_int, optname: c_int, optval: ?*anyopaque, optlen: c_int) c_long, 49); -pub const skb_adjust_room = @intToPtr(fn (skb: *kern.SkBuff, len_diff: i32, mode: u32, flags: u64) c_long, 50); -pub const redirect_map = @intToPtr(fn (map: *const kern.MapDef, key: u32, flags: u64) c_long, 51); -pub const sk_redirect_map = @intToPtr(fn (skb: *kern.SkBuff, map: *const kern.MapDef, key: u32, flags: u64) c_long, 52); -pub const sock_map_update = @intToPtr(fn (skops: *kern.SockOps, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 53); -pub const xdp_adjust_meta = @intToPtr(fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 54); -pub const perf_event_read_value = @intToPtr(fn (map: *const kern.MapDef, flags: u64, buf: *kern.PerfEventValue, buf_size: u32) c_long, 55); -pub const perf_prog_read_value = @intToPtr(fn (ctx: *kern.PerfEventData, buf: *kern.PerfEventValue, buf_size: u32) c_long, 56); -pub const getsockopt = @intToPtr(fn (bpf_socket: ?*anyopaque, level: c_int, optname: c_int, optval: ?*anyopaque, optlen: c_int) c_long, 57); -pub const override_return = @intToPtr(fn (regs: *PtRegs, rc: u64) c_long, 58); -pub const sock_ops_cb_flags_set = @intToPtr(fn (bpf_sock: *kern.SockOps, argval: c_int) c_long, 59); -pub const msg_redirect_map = @intToPtr(fn (msg: *kern.SkMsgMd, map: *const kern.MapDef, key: u32, flags: u64) c_long, 60); -pub const msg_apply_bytes = @intToPtr(fn (msg: *kern.SkMsgMd, bytes: u32) c_long, 61); -pub const msg_cork_bytes = @intToPtr(fn (msg: *kern.SkMsgMd, bytes: u32) c_long, 62); -pub const msg_pull_data = @intToPtr(fn (msg: *kern.SkMsgMd, start: u32, end: u32, flags: u64) c_long, 63); -pub const bind = @intToPtr(fn (ctx: *kern.BpfSockAddr, addr: *kern.SockAddr, addr_len: c_int) c_long, 64); -pub const xdp_adjust_tail = @intToPtr(fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 65); -pub const skb_get_xfrm_state = @intToPtr(fn (skb: *kern.SkBuff, index: u32, xfrm_state: *kern.XfrmState, size: u32, flags: u64) c_long, 66); -pub const get_stack = @intToPtr(fn (ctx: ?*anyopaque, buf: ?*anyopaque, size: u32, flags: u64) c_long, 67); -pub const skb_load_bytes_relative = @intToPtr(fn (skb: ?*const anyopaque, offset: u32, to: ?*anyopaque, len: u32, start_header: u32) c_long, 68); -pub const fib_lookup = @intToPtr(fn (ctx: ?*anyopaque, params: *kern.FibLookup, plen: c_int, flags: u32) c_long, 69); -pub const sock_hash_update = @intToPtr(fn (skops: *kern.SockOps, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 70); -pub const msg_redirect_hash = @intToPtr(fn (msg: *kern.SkMsgMd, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 71); -pub const sk_redirect_hash = @intToPtr(fn (skb: *kern.SkBuff, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 72); -pub const lwt_push_encap = @intToPtr(fn (skb: *kern.SkBuff, typ: u32, hdr: ?*anyopaque, len: u32) c_long, 73); -pub const lwt_seg6_store_bytes = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: ?*const anyopaque, len: u32) c_long, 74); -pub const lwt_seg6_adjust_srh = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, delta: i32) c_long, 75); -pub const lwt_seg6_action = @intToPtr(fn (skb: *kern.SkBuff, action: u32, param: ?*anyopaque, param_len: u32) c_long, 76); -pub const rc_repeat = @intToPtr(fn (ctx: ?*anyopaque) c_long, 77); -pub const rc_keydown = @intToPtr(fn (ctx: ?*anyopaque, protocol: u32, scancode: u64, toggle: u32) c_long, 78); -pub const skb_cgroup_id = @intToPtr(fn (skb: *kern.SkBuff) u64, 79); -pub const get_current_cgroup_id = @intToPtr(fn () u64, 80); -pub const get_local_storage = @intToPtr(fn (map: ?*anyopaque, flags: u64) ?*anyopaque, 81); -pub const sk_select_reuseport = @intToPtr(fn (reuse: *kern.SkReusePortMd, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 82); -pub const skb_ancestor_cgroup_id = @intToPtr(fn (skb: *kern.SkBuff, ancestor_level: c_int) u64, 83); -pub const sk_lookup_tcp = @intToPtr(fn (ctx: ?*anyopaque, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 84); -pub const sk_lookup_udp = @intToPtr(fn (ctx: ?*anyopaque, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 85); -pub const sk_release = @intToPtr(fn (sock: *kern.Sock) c_long, 86); -pub const map_push_elem = @intToPtr(fn (map: *const kern.MapDef, value: ?*const anyopaque, flags: u64) c_long, 87); -pub const map_pop_elem = @intToPtr(fn (map: *const kern.MapDef, value: ?*anyopaque) c_long, 88); -pub const map_peek_elem = @intToPtr(fn (map: *const kern.MapDef, value: ?*anyopaque) c_long, 89); -pub const msg_push_data = @intToPtr(fn (msg: *kern.SkMsgMd, start: u32, len: u32, flags: u64) c_long, 90); -pub const msg_pop_data = @intToPtr(fn (msg: *kern.SkMsgMd, start: u32, len: u32, flags: u64) c_long, 91); -pub const rc_pointer_rel = @intToPtr(fn (ctx: ?*anyopaque, rel_x: i32, rel_y: i32) c_long, 92); -pub const spin_lock = @intToPtr(fn (lock: *kern.SpinLock) c_long, 93); -pub const spin_unlock = @intToPtr(fn (lock: *kern.SpinLock) c_long, 94); -pub const sk_fullsock = @intToPtr(fn (sk: *kern.Sock) ?*SkFullSock, 95); -pub const tcp_sock = @intToPtr(fn (sk: *kern.Sock) ?*kern.TcpSock, 96); -pub const skb_ecn_set_ce = @intToPtr(fn (skb: *kern.SkBuff) c_long, 97); -pub const get_listener_sock = @intToPtr(fn (sk: *kern.Sock) ?*kern.Sock, 98); -pub const skc_lookup_tcp = @intToPtr(fn (ctx: ?*anyopaque, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 99); -pub const tcp_check_syncookie = @intToPtr(fn (sk: *kern.Sock, iph: ?*anyopaque, iph_len: u32, th: *TcpHdr, th_len: u32) c_long, 100); -pub const sysctl_get_name = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong, flags: u64) c_long, 101); -pub const sysctl_get_current_value = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong) c_long, 102); -pub const sysctl_get_new_value = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong) c_long, 103); -pub const sysctl_set_new_value = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*const u8, buf_len: c_ulong) c_long, 104); -pub const strtol = @intToPtr(fn (buf: *const u8, buf_len: c_ulong, flags: u64, res: *c_long) c_long, 105); -pub const strtoul = @intToPtr(fn (buf: *const u8, buf_len: c_ulong, flags: u64, res: *c_ulong) c_long, 106); -pub const sk_storage_get = @intToPtr(fn (map: *const kern.MapDef, sk: *kern.Sock, value: ?*anyopaque, flags: u64) ?*anyopaque, 107); -pub const sk_storage_delete = @intToPtr(fn (map: *const kern.MapDef, sk: *kern.Sock) c_long, 108); -pub const send_signal = @intToPtr(fn (sig: u32) c_long, 109); -pub const tcp_gen_syncookie = @intToPtr(fn (sk: *kern.Sock, iph: ?*anyopaque, iph_len: u32, th: *TcpHdr, th_len: u32) i64, 110); -pub const skb_output = @intToPtr(fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64, data: ?*anyopaque, size: u64) c_long, 111); -pub const probe_read_user = @intToPtr(fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 112); -pub const probe_read_kernel = @intToPtr(fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 113); -pub const probe_read_user_str = @intToPtr(fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 114); -pub const probe_read_kernel_str = @intToPtr(fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 115); -pub const tcp_send_ack = @intToPtr(fn (tp: ?*anyopaque, rcv_nxt: u32) c_long, 116); -pub const send_signal_thread = @intToPtr(fn (sig: u32) c_long, 117); -pub const jiffies64 = @intToPtr(fn () u64, 118); -pub const read_branch_records = @intToPtr(fn (ctx: *kern.PerfEventData, buf: ?*anyopaque, size: u32, flags: u64) c_long, 119); -pub const get_ns_current_pid_tgid = @intToPtr(fn (dev: u64, ino: u64, nsdata: *kern.PidNsInfo, size: u32) c_long, 120); -pub const xdp_output = @intToPtr(fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64, data: ?*anyopaque, size: u64) c_long, 121); -pub const get_netns_cookie = @intToPtr(fn (ctx: ?*anyopaque) u64, 122); -pub const get_current_ancestor_cgroup_id = @intToPtr(fn (ancestor_level: c_int) u64, 123); -pub const sk_assign = @intToPtr(fn (skb: *kern.SkBuff, sk: *kern.Sock, flags: u64) c_long, 124); -pub const ktime_get_boot_ns = @intToPtr(fn () u64, 125); -pub const seq_printf = @intToPtr(fn (m: *kern.SeqFile, fmt: ?*const u8, fmt_size: u32, data: ?*const anyopaque, data_len: u32) c_long, 126); -pub const seq_write = @intToPtr(fn (m: *kern.SeqFile, data: ?*const u8, len: u32) c_long, 127); -pub const sk_cgroup_id = @intToPtr(fn (sk: *kern.BpfSock) u64, 128); -pub const sk_ancestor_cgroup_id = @intToPtr(fn (sk: *kern.BpfSock, ancestor_level: c_long) u64, 129); -pub const ringbuf_output = @intToPtr(fn (ringbuf: ?*anyopaque, data: ?*anyopaque, size: u64, flags: u64) ?*anyopaque, 130); -pub const ringbuf_reserve = @intToPtr(fn (ringbuf: ?*anyopaque, size: u64, flags: u64) ?*anyopaque, 131); -pub const ringbuf_submit = @intToPtr(fn (data: ?*anyopaque, flags: u64) void, 132); -pub const ringbuf_discard = @intToPtr(fn (data: ?*anyopaque, flags: u64) void, 133); -pub const ringbuf_query = @intToPtr(fn (ringbuf: ?*anyopaque, flags: u64) u64, 134); -pub const csum_level = @intToPtr(fn (skb: *kern.SkBuff, level: u64) c_long, 135); -pub const skc_to_tcp6_sock = @intToPtr(fn (sk: ?*anyopaque) ?*kern.Tcp6Sock, 136); -pub const skc_to_tcp_sock = @intToPtr(fn (sk: ?*anyopaque) ?*kern.TcpSock, 137); -pub const skc_to_tcp_timewait_sock = @intToPtr(fn (sk: ?*anyopaque) ?*kern.TcpTimewaitSock, 138); -pub const skc_to_tcp_request_sock = @intToPtr(fn (sk: ?*anyopaque) ?*kern.TcpRequestSock, 139); -pub const skc_to_udp6_sock = @intToPtr(fn (sk: ?*anyopaque) ?*kern.Udp6Sock, 140); -pub const get_task_stack = @intToPtr(fn (task: ?*anyopaque, buf: ?*anyopaque, size: u32, flags: u64) c_long, 141); +pub const skb_change_proto = @intToPtr(*const fn (skb: *kern.SkBuff, proto: u16, flags: u64) c_long, 31); +pub const skb_change_type = @intToPtr(*const fn (skb: *kern.SkBuff, skb_type: u32) c_long, 32); +pub const skb_under_cgroup = @intToPtr(*const fn (skb: *kern.SkBuff, map: ?*const anyopaque, index: u32) c_long, 33); +pub const get_hash_recalc = @intToPtr(*const fn (skb: *kern.SkBuff) u32, 34); +pub const get_current_task = @intToPtr(*const fn () u64, 35); +pub const probe_write_user = @intToPtr(*const fn (dst: ?*anyopaque, src: ?*const anyopaque, len: u32) c_long, 36); +pub const current_task_under_cgroup = @intToPtr(*const fn (map: *const kern.MapDef, index: u32) c_long, 37); +pub const skb_change_tail = @intToPtr(*const fn (skb: *kern.SkBuff, len: u32, flags: u64) c_long, 38); +pub const skb_pull_data = @intToPtr(*const fn (skb: *kern.SkBuff, len: u32) c_long, 39); +pub const csum_update = @intToPtr(*const fn (skb: *kern.SkBuff, csum: u32) i64, 40); +pub const set_hash_invalid = @intToPtr(*const fn (skb: *kern.SkBuff) void, 41); +pub const get_numa_node_id = @intToPtr(*const fn () c_long, 42); +pub const skb_change_head = @intToPtr(*const fn (skb: *kern.SkBuff, len: u32, flags: u64) c_long, 43); +pub const xdp_adjust_head = @intToPtr(*const fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 44); +pub const probe_read_str = @intToPtr(*const fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 45); +pub const get_socket_cookie = @intToPtr(*const fn (ctx: ?*anyopaque) u64, 46); +pub const get_socket_uid = @intToPtr(*const fn (skb: *kern.SkBuff) u32, 47); +pub const set_hash = @intToPtr(*const fn (skb: *kern.SkBuff, hash: u32) c_long, 48); +pub const setsockopt = @intToPtr(*const fn (bpf_socket: *kern.SockOps, level: c_int, optname: c_int, optval: ?*anyopaque, optlen: c_int) c_long, 49); +pub const skb_adjust_room = @intToPtr(*const fn (skb: *kern.SkBuff, len_diff: i32, mode: u32, flags: u64) c_long, 50); +pub const redirect_map = @intToPtr(*const fn (map: *const kern.MapDef, key: u32, flags: u64) c_long, 51); +pub const sk_redirect_map = @intToPtr(*const fn (skb: *kern.SkBuff, map: *const kern.MapDef, key: u32, flags: u64) c_long, 52); +pub const sock_map_update = @intToPtr(*const fn (skops: *kern.SockOps, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 53); +pub const xdp_adjust_meta = @intToPtr(*const fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 54); +pub const perf_event_read_value = @intToPtr(*const fn (map: *const kern.MapDef, flags: u64, buf: *kern.PerfEventValue, buf_size: u32) c_long, 55); +pub const perf_prog_read_value = @intToPtr(*const fn (ctx: *kern.PerfEventData, buf: *kern.PerfEventValue, buf_size: u32) c_long, 56); +pub const getsockopt = @intToPtr(*const fn (bpf_socket: ?*anyopaque, level: c_int, optname: c_int, optval: ?*anyopaque, optlen: c_int) c_long, 57); +pub const override_return = @intToPtr(*const fn (regs: *PtRegs, rc: u64) c_long, 58); +pub const sock_ops_cb_flags_set = @intToPtr(*const fn (bpf_sock: *kern.SockOps, argval: c_int) c_long, 59); +pub const msg_redirect_map = @intToPtr(*const fn (msg: *kern.SkMsgMd, map: *const kern.MapDef, key: u32, flags: u64) c_long, 60); +pub const msg_apply_bytes = @intToPtr(*const fn (msg: *kern.SkMsgMd, bytes: u32) c_long, 61); +pub const msg_cork_bytes = @intToPtr(*const fn (msg: *kern.SkMsgMd, bytes: u32) c_long, 62); +pub const msg_pull_data = @intToPtr(*const fn (msg: *kern.SkMsgMd, start: u32, end: u32, flags: u64) c_long, 63); +pub const bind = @intToPtr(*const fn (ctx: *kern.BpfSockAddr, addr: *kern.SockAddr, addr_len: c_int) c_long, 64); +pub const xdp_adjust_tail = @intToPtr(*const fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 65); +pub const skb_get_xfrm_state = @intToPtr(*const fn (skb: *kern.SkBuff, index: u32, xfrm_state: *kern.XfrmState, size: u32, flags: u64) c_long, 66); +pub const get_stack = @intToPtr(*const fn (ctx: ?*anyopaque, buf: ?*anyopaque, size: u32, flags: u64) c_long, 67); +pub const skb_load_bytes_relative = @intToPtr(*const fn (skb: ?*const anyopaque, offset: u32, to: ?*anyopaque, len: u32, start_header: u32) c_long, 68); +pub const fib_lookup = @intToPtr(*const fn (ctx: ?*anyopaque, params: *kern.FibLookup, plen: c_int, flags: u32) c_long, 69); +pub const sock_hash_update = @intToPtr(*const fn (skops: *kern.SockOps, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 70); +pub const msg_redirect_hash = @intToPtr(*const fn (msg: *kern.SkMsgMd, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 71); +pub const sk_redirect_hash = @intToPtr(*const fn (skb: *kern.SkBuff, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 72); +pub const lwt_push_encap = @intToPtr(*const fn (skb: *kern.SkBuff, typ: u32, hdr: ?*anyopaque, len: u32) c_long, 73); +pub const lwt_seg6_store_bytes = @intToPtr(*const fn (skb: *kern.SkBuff, offset: u32, from: ?*const anyopaque, len: u32) c_long, 74); +pub const lwt_seg6_adjust_srh = @intToPtr(*const fn (skb: *kern.SkBuff, offset: u32, delta: i32) c_long, 75); +pub const lwt_seg6_action = @intToPtr(*const fn (skb: *kern.SkBuff, action: u32, param: ?*anyopaque, param_len: u32) c_long, 76); +pub const rc_repeat = @intToPtr(*const fn (ctx: ?*anyopaque) c_long, 77); +pub const rc_keydown = @intToPtr(*const fn (ctx: ?*anyopaque, protocol: u32, scancode: u64, toggle: u32) c_long, 78); +pub const skb_cgroup_id = @intToPtr(*const fn (skb: *kern.SkBuff) u64, 79); +pub const get_current_cgroup_id = @intToPtr(*const fn () u64, 80); +pub const get_local_storage = @intToPtr(*const fn (map: ?*anyopaque, flags: u64) ?*anyopaque, 81); +pub const sk_select_reuseport = @intToPtr(*const fn (reuse: *kern.SkReusePortMd, map: *const kern.MapDef, key: ?*anyopaque, flags: u64) c_long, 82); +pub const skb_ancestor_cgroup_id = @intToPtr(*const fn (skb: *kern.SkBuff, ancestor_level: c_int) u64, 83); +pub const sk_lookup_tcp = @intToPtr(*const fn (ctx: ?*anyopaque, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 84); +pub const sk_lookup_udp = @intToPtr(*const fn (ctx: ?*anyopaque, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 85); +pub const sk_release = @intToPtr(*const fn (sock: *kern.Sock) c_long, 86); +pub const map_push_elem = @intToPtr(*const fn (map: *const kern.MapDef, value: ?*const anyopaque, flags: u64) c_long, 87); +pub const map_pop_elem = @intToPtr(*const fn (map: *const kern.MapDef, value: ?*anyopaque) c_long, 88); +pub const map_peek_elem = @intToPtr(*const fn (map: *const kern.MapDef, value: ?*anyopaque) c_long, 89); +pub const msg_push_data = @intToPtr(*const fn (msg: *kern.SkMsgMd, start: u32, len: u32, flags: u64) c_long, 90); +pub const msg_pop_data = @intToPtr(*const fn (msg: *kern.SkMsgMd, start: u32, len: u32, flags: u64) c_long, 91); +pub const rc_pointer_rel = @intToPtr(*const fn (ctx: ?*anyopaque, rel_x: i32, rel_y: i32) c_long, 92); +pub const spin_lock = @intToPtr(*const fn (lock: *kern.SpinLock) c_long, 93); +pub const spin_unlock = @intToPtr(*const fn (lock: *kern.SpinLock) c_long, 94); +pub const sk_fullsock = @intToPtr(*const fn (sk: *kern.Sock) ?*SkFullSock, 95); +pub const tcp_sock = @intToPtr(*const fn (sk: *kern.Sock) ?*kern.TcpSock, 96); +pub const skb_ecn_set_ce = @intToPtr(*const fn (skb: *kern.SkBuff) c_long, 97); +pub const get_listener_sock = @intToPtr(*const fn (sk: *kern.Sock) ?*kern.Sock, 98); +pub const skc_lookup_tcp = @intToPtr(*const fn (ctx: ?*anyopaque, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 99); +pub const tcp_check_syncookie = @intToPtr(*const fn (sk: *kern.Sock, iph: ?*anyopaque, iph_len: u32, th: *TcpHdr, th_len: u32) c_long, 100); +pub const sysctl_get_name = @intToPtr(*const fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong, flags: u64) c_long, 101); +pub const sysctl_get_current_value = @intToPtr(*const fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong) c_long, 102); +pub const sysctl_get_new_value = @intToPtr(*const fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong) c_long, 103); +pub const sysctl_set_new_value = @intToPtr(*const fn (ctx: *kern.SysCtl, buf: ?*const u8, buf_len: c_ulong) c_long, 104); +pub const strtol = @intToPtr(*const fn (buf: *const u8, buf_len: c_ulong, flags: u64, res: *c_long) c_long, 105); +pub const strtoul = @intToPtr(*const fn (buf: *const u8, buf_len: c_ulong, flags: u64, res: *c_ulong) c_long, 106); +pub const sk_storage_get = @intToPtr(*const fn (map: *const kern.MapDef, sk: *kern.Sock, value: ?*anyopaque, flags: u64) ?*anyopaque, 107); +pub const sk_storage_delete = @intToPtr(*const fn (map: *const kern.MapDef, sk: *kern.Sock) c_long, 108); +pub const send_signal = @intToPtr(*const fn (sig: u32) c_long, 109); +pub const tcp_gen_syncookie = @intToPtr(*const fn (sk: *kern.Sock, iph: ?*anyopaque, iph_len: u32, th: *TcpHdr, th_len: u32) i64, 110); +pub const skb_output = @intToPtr(*const fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64, data: ?*anyopaque, size: u64) c_long, 111); +pub const probe_read_user = @intToPtr(*const fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 112); +pub const probe_read_kernel = @intToPtr(*const fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 113); +pub const probe_read_user_str = @intToPtr(*const fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 114); +pub const probe_read_kernel_str = @intToPtr(*const fn (dst: ?*anyopaque, size: u32, unsafe_ptr: ?*const anyopaque) c_long, 115); +pub const tcp_send_ack = @intToPtr(*const fn (tp: ?*anyopaque, rcv_nxt: u32) c_long, 116); +pub const send_signal_thread = @intToPtr(*const fn (sig: u32) c_long, 117); +pub const jiffies64 = @intToPtr(*const fn () u64, 118); +pub const read_branch_records = @intToPtr(*const fn (ctx: *kern.PerfEventData, buf: ?*anyopaque, size: u32, flags: u64) c_long, 119); +pub const get_ns_current_pid_tgid = @intToPtr(*const fn (dev: u64, ino: u64, nsdata: *kern.PidNsInfo, size: u32) c_long, 120); +pub const xdp_output = @intToPtr(*const fn (ctx: ?*anyopaque, map: *const kern.MapDef, flags: u64, data: ?*anyopaque, size: u64) c_long, 121); +pub const get_netns_cookie = @intToPtr(*const fn (ctx: ?*anyopaque) u64, 122); +pub const get_current_ancestor_cgroup_id = @intToPtr(*const fn (ancestor_level: c_int) u64, 123); +pub const sk_assign = @intToPtr(*const fn (skb: *kern.SkBuff, sk: *kern.Sock, flags: u64) c_long, 124); +pub const ktime_get_boot_ns = @intToPtr(*const fn () u64, 125); +pub const seq_printf = @intToPtr(*const fn (m: *kern.SeqFile, fmt: ?*const u8, fmt_size: u32, data: ?*const anyopaque, data_len: u32) c_long, 126); +pub const seq_write = @intToPtr(*const fn (m: *kern.SeqFile, data: ?*const u8, len: u32) c_long, 127); +pub const sk_cgroup_id = @intToPtr(*const fn (sk: *kern.BpfSock) u64, 128); +pub const sk_ancestor_cgroup_id = @intToPtr(*const fn (sk: *kern.BpfSock, ancestor_level: c_long) u64, 129); +pub const ringbuf_output = @intToPtr(*const fn (ringbuf: ?*anyopaque, data: ?*anyopaque, size: u64, flags: u64) ?*anyopaque, 130); +pub const ringbuf_reserve = @intToPtr(*const fn (ringbuf: ?*anyopaque, size: u64, flags: u64) ?*anyopaque, 131); +pub const ringbuf_submit = @intToPtr(*const fn (data: ?*anyopaque, flags: u64) void, 132); +pub const ringbuf_discard = @intToPtr(*const fn (data: ?*anyopaque, flags: u64) void, 133); +pub const ringbuf_query = @intToPtr(*const fn (ringbuf: ?*anyopaque, flags: u64) u64, 134); +pub const csum_level = @intToPtr(*const fn (skb: *kern.SkBuff, level: u64) c_long, 135); +pub const skc_to_tcp6_sock = @intToPtr(*const fn (sk: ?*anyopaque) ?*kern.Tcp6Sock, 136); +pub const skc_to_tcp_sock = @intToPtr(*const fn (sk: ?*anyopaque) ?*kern.TcpSock, 137); +pub const skc_to_tcp_timewait_sock = @intToPtr(*const fn (sk: ?*anyopaque) ?*kern.TcpTimewaitSock, 138); +pub const skc_to_tcp_request_sock = @intToPtr(*const fn (sk: ?*anyopaque) ?*kern.TcpRequestSock, 139); +pub const skc_to_udp6_sock = @intToPtr(*const fn (sk: ?*anyopaque) ?*kern.Udp6Sock, 140); +pub const get_task_stack = @intToPtr(*const fn (task: ?*anyopaque, buf: ?*anyopaque, size: u32, flags: u64) c_long, 141); From db877df8eb1831891fc1f3cb6dab1503868b5732 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 14:13:39 +0200 Subject: [PATCH 136/216] coff: move import table definition into a separate ImportTable.zig module --- CMakeLists.txt | 1 + src/link/Coff.zig | 174 +++++++++------------------------- src/link/Coff/ImportTable.zig | 133 ++++++++++++++++++++++++++ src/link/Coff/Relocation.zig | 9 +- 4 files changed, 186 insertions(+), 131 deletions(-) create mode 100644 src/link/Coff/ImportTable.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f5cf7cd6e..eef03325fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -583,6 +583,7 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/src/link/C.zig" "${CMAKE_SOURCE_DIR}/src/link/Coff.zig" "${CMAKE_SOURCE_DIR}/src/link/Coff/Atom.zig" + "${CMAKE_SOURCE_DIR}/src/link/Coff/ImportTable.zig" "${CMAKE_SOURCE_DIR}/src/link/Coff/Object.zig" "${CMAKE_SOURCE_DIR}/src/link/Coff/lld.zig" "${CMAKE_SOURCE_DIR}/src/link/Elf.zig" diff --git a/src/link/Coff.zig b/src/link/Coff.zig index bcc507b02f..6dcad604ac 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1,36 +1,7 @@ -const Coff = @This(); - -const std = @import("std"); -const build_options = @import("build_options"); -const builtin = @import("builtin"); -const assert = std.debug.assert; -const coff = std.coff; -const fmt = std.fmt; -const log = std.log.scoped(.link); -const math = std.math; -const mem = std.mem; - -const Allocator = std.mem.Allocator; - -const codegen = @import("../codegen.zig"); -const link = @import("../link.zig"); -const lld = @import("Coff/lld.zig"); -const trace = @import("../tracy.zig").trace; - -const Air = @import("../Air.zig"); -pub const Atom = @import("Coff/Atom.zig"); -const Compilation = @import("../Compilation.zig"); -const Liveness = @import("../Liveness.zig"); -const LlvmObject = @import("../codegen/llvm.zig").Object; -const Module = @import("../Module.zig"); -const Object = @import("Coff/Object.zig"); -const Relocation = @import("Coff/Relocation.zig"); -const StringTable = @import("strtab.zig").StringTable; -const TypedValue = @import("../TypedValue.zig"); - -pub const base_tag: link.File.Tag = .coff; - -const msdos_stub = @embedFile("msdos-stub.bin"); +//! The main driver of the COFF linker. +//! Currently uses our own implementation for the incremental linker, and falls back to +//! LLD for traditional linking (linking relocatable object files). +//! LLD is also the default linker for LLVM. /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. llvm_object: ?*LlvmObject = null, @@ -160,92 +131,6 @@ const Section = struct { free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, }; -/// Represents an import table in the .idata section where each contained pointer -/// is to a symbol from the same DLL. -/// -/// The layout of .idata section is as follows: -/// -/// --- ADDR1 : IAT (all import tables concatenated together) -/// ptr -/// ptr -/// 0 sentinel -/// ptr -/// 0 sentinel -/// --- ADDR2: headers -/// ImportDirectoryEntry header -/// ImportDirectoryEntry header -/// sentinel -/// --- ADDR2: lookup tables -/// Lookup table -/// 0 sentinel -/// Lookup table -/// 0 sentinel -/// --- ADDR3: name hint tables -/// hint-symname -/// hint-symname -/// --- ADDR4: DLL names -/// DLL#1 name -/// DLL#2 name -/// --- END -const ImportTable = struct { - entries: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, - free_list: std.ArrayListUnmanaged(u32) = .{}, - lookup: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, - index: u8, - - const ITable = @This(); - - fn deinit(itab: *ITable, allocator: Allocator) void { - itab.entries.deinit(allocator); - itab.free_list.deinit(allocator); - itab.lookup.deinit(allocator); - } - - fn size(itab: ITable) u32 { - return @intCast(u32, itab.entries.items.len) * @sizeOf(u64); - } - - fn addImport(itab: *ITable, allocator: Allocator, target: SymbolWithLoc) !u32 { - try itab.entries.ensureUnusedCapacity(allocator, 1); - const index: u32 = blk: { - if (itab.free_list.popOrNull()) |index| { - log.debug(" (reusing import entry index {d})", .{index}); - break :blk index; - } else { - log.debug(" (allocating import entry at index {d})", .{itab.entries.items.len}); - const index = @intCast(u32, itab.entries.items.len); - _ = itab.entries.addOneAssumeCapacity(); - break :blk index; - } - }; - itab.entries.items[index] = target; - try itab.lookup.putNoClobber(allocator, target, index); - return index; - } - - fn getBaseAddress(itab: *const ITable, coff_file: *const Coff) u32 { - const header = coff_file.sections.items(.header)[coff_file.idata_section_index.?]; - var addr = header.virtual_address; - for (coff_file.import_tables.values(), 0..) |other_itab, i| { - if (itab.index == i) break; - addr += @intCast(u32, other_itab.entries.items.len * @sizeOf(u64)) + 8; - } - return addr; - } - - pub fn getImportAddress(itab: *const ITable, coff_file: *const Coff, target: SymbolWithLoc) ?u32 { - const index = itab.lookup.get(target) orelse return null; - const base_vaddr = itab.getBaseAddress(coff_file); - return base_vaddr + index * @sizeOf(u64); - } - - pub fn write(itab: ITable, writer: anytype) !void { - for (itab.entries.items) |_| { - try writer.writeIntLittle(u64, 0); - } - } -}; - const DeclMetadata = struct { atom: Atom.Index, section: u16, @@ -1527,7 +1412,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod const res = try self.import_tables.getOrPut(gpa, sym.value); const itable = res.value_ptr; if (!res.found_existing) { - itable.* = .{ .index = @intCast(u8, self.import_tables.values().len - 1) }; + itable.* = .{}; } if (itable.lookup.contains(global)) continue; // TODO: we could technically write the pointer placeholder for to-be-bound import here, @@ -2367,15 +2252,46 @@ fn logSections(self: *Coff) void { fn logImportTables(self: *const Coff) void { log.debug("import tables:", .{}); for (self.import_tables.keys(), 0..) |off, i| { - const lib_name = self.temp_strtab.getAssumeExists(off); const itable = self.import_tables.values()[i]; - log.debug("IAT({s}) @{x}:", .{ lib_name, itable.getBaseAddress(self) }); - for (itable.entries.items, 0..) |entry, j| { - log.debug(" {d}@{?x} => {s}", .{ - j, - itable.getImportAddress(self, entry), - self.getSymbolName(entry), - }); - } + log.debug("{}", .{itable.fmtDebug(.{ + .coff_file = self, + .index = i, + .name_off = off, + })}); } } + +const Coff = @This(); + +const std = @import("std"); +const build_options = @import("build_options"); +const builtin = @import("builtin"); +const assert = std.debug.assert; +const coff = std.coff; +const fmt = std.fmt; +const log = std.log.scoped(.link); +const math = std.math; +const mem = std.mem; + +const Allocator = std.mem.Allocator; + +const codegen = @import("../codegen.zig"); +const link = @import("../link.zig"); +const lld = @import("Coff/lld.zig"); +const trace = @import("../tracy.zig").trace; + +const Air = @import("../Air.zig"); +pub const Atom = @import("Coff/Atom.zig"); +const Compilation = @import("../Compilation.zig"); +const ImportTable = @import("Coff/ImportTable.zig"); +const Liveness = @import("../Liveness.zig"); +const LlvmObject = @import("../codegen/llvm.zig").Object; +const Module = @import("../Module.zig"); +const Object = @import("Coff/Object.zig"); +const Relocation = @import("Coff/Relocation.zig"); +const StringTable = @import("strtab.zig").StringTable; +const TypedValue = @import("../TypedValue.zig"); + +pub const base_tag: link.File.Tag = .coff; + +const msdos_stub = @embedFile("msdos-stub.bin"); diff --git a/src/link/Coff/ImportTable.zig b/src/link/Coff/ImportTable.zig new file mode 100644 index 0000000000..ba58af2fe0 --- /dev/null +++ b/src/link/Coff/ImportTable.zig @@ -0,0 +1,133 @@ +//! Represents an import table in the .idata section where each contained pointer +//! is to a symbol from the same DLL. +//! +//! The layout of .idata section is as follows: +//! +//! --- ADDR1 : IAT (all import tables concatenated together) +//! ptr +//! ptr +//! 0 sentinel +//! ptr +//! 0 sentinel +//! --- ADDR2: headers +//! ImportDirectoryEntry header +//! ImportDirectoryEntry header +//! sentinel +//! --- ADDR2: lookup tables +//! Lookup table +//! 0 sentinel +//! Lookup table +//! 0 sentinel +//! --- ADDR3: name hint tables +//! hint-symname +//! hint-symname +//! --- ADDR4: DLL names +//! DLL#1 name +//! DLL#2 name +//! --- END + +entries: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, +free_list: std.ArrayListUnmanaged(u32) = .{}, +lookup: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, + +pub fn deinit(itab: *ImportTable, allocator: Allocator) void { + itab.entries.deinit(allocator); + itab.free_list.deinit(allocator); + itab.lookup.deinit(allocator); +} + +/// Size of the import table does not include the sentinel. +pub fn size(itab: ImportTable) u32 { + return @intCast(u32, itab.entries.items.len) * @sizeOf(u64); +} + +pub fn addImport(itab: *ImportTable, allocator: Allocator, target: SymbolWithLoc) !ImportIndex { + try itab.entries.ensureUnusedCapacity(allocator, 1); + const index: u32 = blk: { + if (itab.free_list.popOrNull()) |index| { + log.debug(" (reusing import entry index {d})", .{index}); + break :blk index; + } else { + log.debug(" (allocating import entry at index {d})", .{itab.entries.items.len}); + const index = @intCast(u32, itab.entries.items.len); + _ = itab.entries.addOneAssumeCapacity(); + break :blk index; + } + }; + itab.entries.items[index] = target; + try itab.lookup.putNoClobber(allocator, target, index); + return index; +} + +const Context = struct { + coff_file: *const Coff, + /// Index of this ImportTable in a global list of all tables. + /// This is required in order to calculate the base vaddr of this ImportTable. + index: usize, + /// Offset into the string interning table of the DLL this ImportTable corresponds to. + name_off: u32, +}; + +fn getBaseAddress(ctx: Context) u32 { + const header = ctx.coff_file.sections.items(.header)[ctx.coff_file.idata_section_index.?]; + var addr = header.virtual_address; + for (ctx.coff_file.import_tables.values(), 0..) |other_itab, i| { + if (ctx.index == i) break; + addr += @intCast(u32, other_itab.entries.items.len * @sizeOf(u64)) + 8; + } + return addr; +} + +pub fn getImportAddress(itab: *const ImportTable, target: SymbolWithLoc, ctx: Context) ?u32 { + const index = itab.lookup.get(target) orelse return null; + const base_vaddr = getBaseAddress(ctx); + return base_vaddr + index * @sizeOf(u64); +} + +const FormatContext = struct { + itab: ImportTable, + ctx: Context, +}; + +fn fmt( + fmt_ctx: FormatContext, + comptime unused_format_string: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, +) @TypeOf(writer).Error!void { + _ = options; + comptime assert(unused_format_string.len == 0); + const lib_name = fmt_ctx.ctx.coff_file.temp_strtab.getAssumeExists(fmt_ctx.ctx.name_off); + const base_vaddr = getBaseAddress(fmt_ctx.ctx); + try writer.print("IAT({s}.dll) @{x}:", .{ lib_name, base_vaddr }); + for (fmt_ctx.itab.entries.items, 0..) |entry, i| { + try writer.print("\n {d}@{?x} => {s}", .{ + i, + fmt_ctx.itab.getImportAddress(entry, fmt_ctx.ctx), + fmt_ctx.ctx.coff_file.getSymbolName(entry), + }); + } +} + +fn format(itab: ImportTable, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + _ = itab; + _ = unused_format_string; + _ = options; + _ = writer; + @compileError("do not format ImportTable directly; use itab.fmtDebug()"); +} + +pub fn fmtDebug(itab: ImportTable, ctx: Context) std.fmt.Formatter(fmt) { + return .{ .data = .{ .itab = itab, .ctx = ctx } }; +} + +const ImportIndex = u32; +const ImportTable = @This(); + +const std = @import("std"); +const assert = std.debug.assert; +const log = std.log.scoped(.link); + +const Allocator = std.mem.Allocator; +const Coff = @import("../Coff.zig"); +const SymbolWithLoc = Coff.SymbolWithLoc; diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 5dcb0552fc..45f3a97052 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -61,8 +61,13 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { .import, .import_page, .import_pageoff => { const sym = coff_file.getSymbol(self.target); - const itab = coff_file.import_tables.get(sym.value) orelse return null; - return itab.getImportAddress(coff_file, self.target); + const index = coff_file.import_tables.getIndex(sym.value) orelse return null; + const itab = coff_file.import_tables.values()[index]; + return itab.getImportAddress(self.target, .{ + .coff_file = coff_file, + .index = index, + .name_off = sym.value, + }); }, } } From 70838d34aa581c9723d39592329827cf671cf0e9 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 14:17:12 +0200 Subject: [PATCH 137/216] coff: assert the imports table is not dirty --- src/link/Coff.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 6dcad604ac..df525bba90 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1451,6 +1451,8 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod self.error_flags.no_entry_point_found = false; try self.writeHeader(); } + + assert(!self.imports_count_dirty); } pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 { From 1c5f2557894539d7620933324dad48a43a16d0ef Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 15:49:26 +0200 Subject: [PATCH 138/216] tests: enable multi-threaded x86_64-windows tests with self-hosted --- test/tests.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/test/tests.zig b/test/tests.zig index 517d789b18..26e684cd0d 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -112,7 +112,6 @@ const test_targets = blk: { .os_tag = .windows, .abi = .gnu, }, - .single_threaded = true, // https://github.com/ziglang/zig/issues/15075 .backend = .stage2_x86_64, }, From 004f32e79d61cb549b6cf71499138db0df56e152 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 18:59:44 +0200 Subject: [PATCH 139/216] coff: resolve relocs on bytes buffer directly --- src/link.zig | 2 ++ src/link/Coff.zig | 42 ++++++++++++++++------ src/link/Coff/Relocation.zig | 68 ++++++++++-------------------------- 3 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/link.zig b/src/link.zig index a7c3ac51bc..239dc646b2 100644 --- a/src/link.zig +++ b/src/link.zig @@ -395,6 +395,7 @@ pub const File = struct { .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| { log.warn("attaching failed with error: {s}", .{@errorName(err)}); }, + .windows => {}, else => return error.HotSwapUnavailableOnHostOperatingSystem, } } @@ -436,6 +437,7 @@ pub const File = struct { .macos => base.cast(MachO).?.ptraceDetach(pid) catch |err| { log.warn("detaching failed with error: {s}", .{@errorName(err)}); }, + .windows => {}, else => return error.HotSwapUnavailableOnHostOperatingSystem, } } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index df525bba90..7d853b3181 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -771,7 +771,7 @@ fn shrinkAtom(self: *Coff, atom_index: Atom.Index, new_block_size: u32) void { // capacity, insert a free list node for it. } -fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void { +fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { const atom = self.getAtom(atom_index); const sym = atom.getSymbol(self); const section = self.sections.get(@enumToInt(sym.section_number) - 1); @@ -781,8 +781,8 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void { file_offset, file_offset + code.len, }); + self.resolveRelocs(atom_index, code); try self.base.file.?.pwriteAll(code, file_offset); - try self.resolveRelocs(atom_index); } fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { @@ -820,14 +820,15 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { } } -fn resolveRelocs(self: *Coff, atom_index: Atom.Index) !void { +fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { const relocs = self.relocs.get(atom_index) orelse return; log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); for (relocs.items) |*reloc| { if (!reloc.dirty) continue; - try reloc.resolve(atom_index, self); + reloc.resolve(atom_index, code, self); + reloc.dirty = false; } } @@ -944,7 +945,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live &code_buffer, .none, ); - const code = switch (res) { + var code = switch (res) { .ok => code_buffer.items, .fail => |em| { decl.analysis = .codegen_failure; @@ -994,7 +995,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), tv, &code_buffer, .none, .{ .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, }); - const code = switch (res) { + var code = switch (res) { .ok => code_buffer.items, .fail => |em| { decl.analysis = .codegen_failure; @@ -1057,7 +1058,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! }, &code_buffer, .none, .{ .parent_atom_index = atom.getSymbolIndex().?, }); - const code = switch (res) { + var code = switch (res) { .ok => code_buffer.items, .fail => |em| { decl.analysis = .codegen_failure; @@ -1110,7 +1111,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 { return index; } -fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, complex_type: coff.ComplexType) !void { +fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, complex_type: coff.ComplexType) !void { const gpa = self.base.allocator; const mod = self.base.options.module.?; const decl = mod.declPtr(decl_index); @@ -1424,8 +1425,28 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod try self.writeImportTables(); { var it = self.relocs.keyIterator(); - while (it.next()) |atom| { - try self.resolveRelocs(atom.*); + while (it.next()) |atom_index_ptr| { + const atom_index = atom_index_ptr.*; + const relocs = self.relocs.get(atom_index).?; + const needs_update = for (relocs.items) |reloc| { + if (reloc.dirty) break true; + } else false; + + if (!needs_update) continue; + + const atom = self.getAtom(atom_index); + const sym = atom.getSymbol(self); + const section = self.sections.get(@enumToInt(sym.section_number) - 1).header; + const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address; + + var code = std.ArrayList(u8).init(gpa); + defer code.deinit(); + try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); + + const amt = try self.base.file.?.preadAll(code.items, file_offset); + if (amt != code.items.len) return error.InputOutput; + + try self.writeAtom(atom_index, code.items); } } try self.writeBaseRelocations(); @@ -1642,6 +1663,7 @@ fn writeImportTables(self: *Coff) !void { const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); if (needed_size > sect_vm_capacity) { try self.growSectionVM(self.idata_section_index.?, needed_size); + self.markRelocsDirtyByAddress(header.virtual_address + needed_size); } header.virtual_size = @max(header.virtual_size, needed_size); diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 45f3a97052..c0fd5562e4 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -72,62 +72,46 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { } } -pub fn resolve(self: *Relocation, atom_index: Atom.Index, coff_file: *Coff) !void { +pub fn resolve(self: *Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) void { const atom = coff_file.getAtom(atom_index); const source_sym = atom.getSymbol(coff_file); - const source_section = coff_file.sections.get(@enumToInt(source_sym.section_number) - 1).header; const source_vaddr = source_sym.value + self.offset; - const file_offset = source_section.pointer_to_raw_data + source_sym.value - source_section.virtual_address; - const target_vaddr = self.getTargetAddress(coff_file) orelse return; const target_vaddr_with_addend = target_vaddr + self.addend; - log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) (in file at 0x{x})", .{ + log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) ", .{ source_vaddr, target_vaddr_with_addend, coff_file.getSymbolName(self.target), @tagName(self.type), - file_offset + self.offset, }); const ctx: Context = .{ .source_vaddr = source_vaddr, .target_vaddr = target_vaddr_with_addend, - .file_offset = file_offset, .image_base = coff_file.getImageBase(), + .code = code, + .ptr_width = coff_file.ptr_width, }; switch (coff_file.base.options.target.cpu.arch) { - .aarch64 => try self.resolveAarch64(ctx, coff_file), - .x86, .x86_64 => try self.resolveX86(ctx, coff_file), + .aarch64 => self.resolveAarch64(ctx), + .x86, .x86_64 => self.resolveX86(ctx), else => unreachable, // unhandled target architecture } - - self.dirty = false; } const Context = struct { source_vaddr: u32, target_vaddr: u32, - file_offset: u32, image_base: u64, + code: []u8, + ptr_width: Coff.PtrWidth, }; -fn resolveAarch64(self: Relocation, ctx: Context, coff_file: *Coff) !void { - var buffer: [@sizeOf(u64)]u8 = undefined; - switch (self.length) { - 2 => { - const amt = try coff_file.base.file.?.preadAll(buffer[0..4], ctx.file_offset + self.offset); - if (amt != 4) return error.InputOutput; - }, - 3 => { - const amt = try coff_file.base.file.?.preadAll(&buffer, ctx.file_offset + self.offset); - if (amt != 8) return error.InputOutput; - }, - else => unreachable, - } - +fn resolveAarch64(self: Relocation, ctx: Context) void { + var buffer = ctx.code[self.offset..]; switch (self.type) { .got_page, .import_page, .page => { const source_page = @intCast(i32, ctx.source_vaddr >> 12); @@ -188,7 +172,7 @@ fn resolveAarch64(self: Relocation, ctx: Context, coff_file: *Coff) !void { buffer[0..4], @truncate(u32, ctx.target_vaddr + ctx.image_base), ), - 3 => mem.writeIntLittle(u64, &buffer, ctx.target_vaddr + ctx.image_base), + 3 => mem.writeIntLittle(u64, buffer[0..8], ctx.target_vaddr + ctx.image_base), else => unreachable, } }, @@ -196,15 +180,10 @@ fn resolveAarch64(self: Relocation, ctx: Context, coff_file: *Coff) !void { .got => unreachable, .import => unreachable, } - - switch (self.length) { - 2 => try coff_file.base.file.?.pwriteAll(buffer[0..4], ctx.file_offset + self.offset), - 3 => try coff_file.base.file.?.pwriteAll(&buffer, ctx.file_offset + self.offset), - else => unreachable, - } } -fn resolveX86(self: Relocation, ctx: Context, coff_file: *Coff) !void { +fn resolveX86(self: Relocation, ctx: Context) void { + var buffer = ctx.code[self.offset..]; switch (self.type) { .got_page => unreachable, .got_pageoff => unreachable, @@ -216,26 +195,17 @@ fn resolveX86(self: Relocation, ctx: Context, coff_file: *Coff) !void { .got, .import => { assert(self.pcrel); const disp = @intCast(i32, ctx.target_vaddr) - @intCast(i32, ctx.source_vaddr) - 4; - try coff_file.base.file.?.pwriteAll(mem.asBytes(&disp), ctx.file_offset + self.offset); + mem.writeIntLittle(i32, buffer[0..4], disp); }, .direct => { if (self.pcrel) { const disp = @intCast(i32, ctx.target_vaddr) - @intCast(i32, ctx.source_vaddr) - 4; - try coff_file.base.file.?.pwriteAll(mem.asBytes(&disp), ctx.file_offset + self.offset); - } else switch (coff_file.ptr_width) { - .p32 => try coff_file.base.file.?.pwriteAll( - mem.asBytes(&@intCast(u32, ctx.target_vaddr + ctx.image_base)), - ctx.file_offset + self.offset, - ), + mem.writeIntLittle(i32, buffer[0..4], disp); + } else switch (ctx.ptr_width) { + .p32 => mem.writeIntLittle(u32, buffer[0..4], @intCast(u32, ctx.target_vaddr + ctx.image_base)), .p64 => switch (self.length) { - 2 => try coff_file.base.file.?.pwriteAll( - mem.asBytes(&@truncate(u32, ctx.target_vaddr + ctx.image_base)), - ctx.file_offset + self.offset, - ), - 3 => try coff_file.base.file.?.pwriteAll( - mem.asBytes(&(ctx.target_vaddr + ctx.image_base)), - ctx.file_offset + self.offset, - ), + 2 => mem.writeIntLittle(u32, buffer[0..4], @truncate(u32, ctx.target_vaddr + ctx.image_base)), + 3 => mem.writeIntLittle(u64, buffer[0..8], ctx.target_vaddr + ctx.image_base), else => unreachable, }, } From 25f3175217dace219af643bce7bd28913a970362 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 19:27:05 +0200 Subject: [PATCH 140/216] coff: use ArrayHashMap if we are iterating over keys --- src/link/Coff.zig | 100 +++++++++++++++-------------------- src/link/Coff/Atom.zig | 4 +- src/link/Coff/Relocation.zig | 2 +- 3 files changed, 45 insertions(+), 61 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 7d853b3181..9f7cd6be1c 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -49,11 +49,8 @@ imports_count_dirty: bool = true, /// Virtual address of the entry point procedure relative to image base. entry_addr: ?u32 = null, -/// Table of Decls that are currently alive. -/// We store them here so that we can properly dispose of any allocated -/// memory within the atom in the incremental linker. -/// TODO consolidate this. -decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, +/// Table of tracked Decls. +decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, /// List of atoms that are either synthetic or map directly to the Zig source program. atoms: std.ArrayListUnmanaged(Atom) = .{}, @@ -98,9 +95,9 @@ const Entry = struct { sym_index: u32, }; -const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); -const BaseRelocationTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); -const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); +const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); +const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); +const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); const default_file_alignment: u16 = 0x200; const default_size_of_stack_reserve: u32 = 0x1000000; @@ -137,6 +134,10 @@ const DeclMetadata = struct { /// A list of all exports aliases of this Decl. exports: std.ArrayListUnmanaged(u32) = .{}, + fn deinit(m: *DeclMetadata, allocator: Allocator) void { + m.exports.deinit(allocator); + } + fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 { for (m.exports.items) |exp| { if (mem.eql(u8, name, coff_file.getSymbolName(.{ @@ -293,39 +294,27 @@ pub fn deinit(self: *Coff) void { } self.import_tables.deinit(gpa); - { - var it = self.decls.iterator(); - while (it.next()) |entry| { - entry.value_ptr.exports.deinit(gpa); - } - self.decls.deinit(gpa); + for (self.decls.values()) |*metadata| { + metadata.deinit(gpa); } + self.decls.deinit(gpa); self.atom_by_index_table.deinit(gpa); - { - var it = self.unnamed_const_atoms.valueIterator(); - while (it.next()) |atoms| { - atoms.deinit(gpa); - } - self.unnamed_const_atoms.deinit(gpa); + for (self.unnamed_const_atoms.values()) |*atoms| { + atoms.deinit(gpa); } + self.unnamed_const_atoms.deinit(gpa); - { - var it = self.relocs.valueIterator(); - while (it.next()) |relocs| { - relocs.deinit(gpa); - } - self.relocs.deinit(gpa); + for (self.relocs.values()) |*relocs| { + relocs.deinit(gpa); } + self.relocs.deinit(gpa); - { - var it = self.base_relocs.valueIterator(); - while (it.next()) |relocs| { - relocs.deinit(gpa); - } - self.base_relocs.deinit(gpa); + for (self.base_relocs.values()) |*relocs| { + relocs.deinit(gpa); } + self.base_relocs.deinit(gpa); } fn populateMissingMetadata(self: *Coff) !void { @@ -800,8 +789,7 @@ fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { // TODO: reverse-lookup might come in handy here - var it = self.relocs.valueIterator(); - while (it.next()) |relocs| { + for (self.relocs.values()) |*relocs| { for (relocs.items) |*reloc| { if (!reloc.target.eql(target)) continue; reloc.dirty = true; @@ -810,8 +798,7 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { } fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { - var it = self.relocs.valueIterator(); - while (it.next()) |relocs| { + for (self.relocs.values()) |*relocs| { for (relocs.items) |*reloc| { const target_vaddr = reloc.getTargetAddress(self) orelse continue; if (target_vaddr < addr) continue; @@ -821,7 +808,7 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { } fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { - const relocs = self.relocs.get(atom_index) orelse return; + const relocs = self.relocs.getPtr(atom_index) orelse return; log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); @@ -1196,7 +1183,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { log.debug("freeDecl {*}", .{decl}); - if (self.decls.fetchRemove(decl_index)) |const_kv| { + if (self.decls.fetchOrderedRemove(decl_index)) |const_kv| { var kv = const_kv; self.freeAtom(kv.value.atom); self.freeUnnamedConsts(decl_index); @@ -1423,32 +1410,29 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod } try self.writeImportTables(); - { - var it = self.relocs.keyIterator(); - while (it.next()) |atom_index_ptr| { - const atom_index = atom_index_ptr.*; - const relocs = self.relocs.get(atom_index).?; - const needs_update = for (relocs.items) |reloc| { - if (reloc.dirty) break true; - } else false; - if (!needs_update) continue; + for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| { + const needs_update = for (relocs.items) |reloc| { + if (reloc.dirty) break true; + } else false; - const atom = self.getAtom(atom_index); - const sym = atom.getSymbol(self); - const section = self.sections.get(@enumToInt(sym.section_number) - 1).header; - const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address; + if (!needs_update) continue; - var code = std.ArrayList(u8).init(gpa); - defer code.deinit(); - try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); + const atom = self.getAtom(atom_index); + const sym = atom.getSymbol(self); + const section = self.sections.get(@enumToInt(sym.section_number) - 1).header; + const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address; - const amt = try self.base.file.?.preadAll(code.items, file_offset); - if (amt != code.items.len) return error.InputOutput; + var code = std.ArrayList(u8).init(gpa); + defer code.deinit(); + try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); - try self.writeAtom(atom_index, code.items); - } + const amt = try self.base.file.?.preadAll(code.items, file_offset); + if (amt != code.items.len) return error.InputOutput; + + try self.writeAtom(atom_index, code.items); } + try self.writeBaseRelocations(); if (self.getEntryPoint()) |entry_sym_loc| { diff --git a/src/link/Coff/Atom.zig b/src/link/Coff/Atom.zig index 80c04a8fa1..4afc1f7cb2 100644 --- a/src/link/Coff/Atom.zig +++ b/src/link/Coff/Atom.zig @@ -121,8 +121,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void { const gpa = coff_file.base.allocator; - var removed_relocs = coff_file.relocs.fetchRemove(atom_index); + var removed_relocs = coff_file.relocs.fetchOrderedRemove(atom_index); if (removed_relocs) |*relocs| relocs.value.deinit(gpa); - var removed_base_relocs = coff_file.base_relocs.fetchRemove(atom_index); + var removed_base_relocs = coff_file.base_relocs.fetchOrderedRemove(atom_index); if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(gpa); } diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index c0fd5562e4..4e2f772524 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -72,7 +72,7 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { } } -pub fn resolve(self: *Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) void { +pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) void { const atom = coff_file.getAtom(atom_index); const source_sym = atom.getSymbol(coff_file); const source_vaddr = source_sym.value + self.offset; From cde722a7117b6da129d3c49dabd445136ed5edb5 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 21:42:55 +0200 Subject: [PATCH 141/216] coff: put section growing in helper; only mark section if actually resolved --- src/link/Coff.zig | 111 ++++++++++++++-------------------- src/link/Coff/ImportTable.zig | 2 +- src/link/Coff/Relocation.zig | 8 ++- 3 files changed, 51 insertions(+), 70 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 9f7cd6be1c..7b5539287d 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -444,7 +444,44 @@ fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.Section return index; } -fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void { +fn growSection(self: *Coff, sect_id: u32, needed_size: u32) !void { + const header = &self.sections.items(.header)[sect_id]; + const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id]; + const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); + + if (needed_size > sect_capacity) { + const new_offset = self.findFreeSpace(needed_size, default_file_alignment); + const current_size = if (maybe_last_atom_index) |last_atom_index| blk: { + const last_atom = self.getAtom(last_atom_index); + const sym = last_atom.getSymbol(self); + break :blk (sym.value + last_atom.size) - header.virtual_address; + } else 0; + log.debug("moving {s} from 0x{x} to 0x{x}", .{ + self.getSectionName(header), + header.pointer_to_raw_data, + new_offset, + }); + const amt = try self.base.file.?.copyRangeAll( + header.pointer_to_raw_data, + self.base.file.?, + new_offset, + current_size, + ); + if (amt != current_size) return error.InputOutput; + header.pointer_to_raw_data = new_offset; + } + + const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); + if (needed_size > sect_vm_capacity) { + try self.growSectionVirtualMemory(sect_id, needed_size); + self.markRelocsDirtyByAddress(header.virtual_address + needed_size); + } + + header.virtual_size = @max(header.virtual_size, needed_size); + header.size_of_raw_data = needed_size; +} + +fn growSectionVirtualMemory(self: *Coff, sect_id: u32, needed_size: u32) !void { const header = &self.sections.items(.header)[sect_id]; const increased_size = padToIdeal(needed_size); const old_aligned_end = header.virtual_address + mem.alignForwardGeneric(u32, header.virtual_size, self.page_size); @@ -551,38 +588,8 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme else true; if (expand_section) { - const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; - if (needed_size > sect_capacity) { - const new_offset = self.findFreeSpace(needed_size, default_file_alignment); - const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { - const last_atom = self.getAtom(last_atom_index); - const sym = last_atom.getSymbol(self); - break :blk (sym.value + last_atom.size) - header.virtual_address; - } else 0; - log.debug("moving {s} from 0x{x} to 0x{x}", .{ - self.getSectionName(header), - header.pointer_to_raw_data, - new_offset, - }); - const amt = try self.base.file.?.copyRangeAll( - header.pointer_to_raw_data, - self.base.file.?, - new_offset, - current_size, - ); - if (amt != current_size) return error.InputOutput; - header.pointer_to_raw_data = new_offset; - } - - const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); - if (needed_size > sect_vm_capacity) { - try self.growSectionVM(sect_id, needed_size); - self.markRelocsDirtyByAddress(header.virtual_address + needed_size); - } - - header.virtual_size = @max(header.virtual_size, needed_size); - header.size_of_raw_data = needed_size; + try self.growSection(sect_id, needed_size); maybe_last_atom_index.* = atom_index; } @@ -814,8 +821,9 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { for (relocs.items) |*reloc| { if (!reloc.dirty) continue; - reloc.resolve(atom_index, code, self); - reloc.dirty = false; + if (reloc.resolve(atom_index, code, self)) { + reloc.dirty = false; + } } } @@ -1581,25 +1589,8 @@ fn writeBaseRelocations(self: *Coff) !void { } const header = &self.sections.items(.header)[self.reloc_section_index.?]; - const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); const needed_size = @intCast(u32, buffer.items.len); - if (needed_size > sect_capacity) { - const new_offset = self.findFreeSpace(needed_size, default_file_alignment); - log.debug("moving {s} from 0x{x} to 0x{x}", .{ - self.getSectionName(header), - header.pointer_to_raw_data, - new_offset, - }); - header.pointer_to_raw_data = new_offset; - - const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); - if (needed_size > sect_vm_capacity) { - // TODO: we want to enforce .reloc after every alloc section. - try self.growSectionVM(self.reloc_section_index.?, needed_size); - } - } - header.virtual_size = @max(header.virtual_size, needed_size); - header.size_of_raw_data = needed_size; + try self.growSection(self.reloc_section_index.?, needed_size); try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data); @@ -1638,21 +1629,7 @@ fn writeImportTables(self: *Coff) !void { } const needed_size = iat_size + dir_table_size + lookup_table_size + names_table_size + dll_names_size; - const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); - if (needed_size > sect_capacity) { - const new_offset = self.findFreeSpace(needed_size, default_file_alignment); - log.debug("moving .idata from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset }); - header.pointer_to_raw_data = new_offset; - - const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); - if (needed_size > sect_vm_capacity) { - try self.growSectionVM(self.idata_section_index.?, needed_size); - self.markRelocsDirtyByAddress(header.virtual_address + needed_size); - } - - header.virtual_size = @max(header.virtual_size, needed_size); - header.size_of_raw_data = needed_size; - } + try self.growSection(self.idata_section_index.?, needed_size); // Do the actual writes var buffer = std.ArrayList(u8).init(gpa); diff --git a/src/link/Coff/ImportTable.zig b/src/link/Coff/ImportTable.zig index ba58af2fe0..c3ba77e855 100644 --- a/src/link/Coff/ImportTable.zig +++ b/src/link/Coff/ImportTable.zig @@ -121,7 +121,7 @@ pub fn fmtDebug(itab: ImportTable, ctx: Context) std.fmt.Formatter(fmt) { return .{ .data = .{ .itab = itab, .ctx = ctx } }; } -const ImportIndex = u32; +pub const ImportIndex = u32; const ImportTable = @This(); const std = @import("std"); diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 4e2f772524..37bd3e292f 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -72,12 +72,14 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { } } -pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) void { +/// Returns `false` if obtaining the target address has been deferred until `flushModule`. +/// This can happen when trying to resolve address of an import table entry ahead of time. +pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) bool { const atom = coff_file.getAtom(atom_index); const source_sym = atom.getSymbol(coff_file); const source_vaddr = source_sym.value + self.offset; - const target_vaddr = self.getTargetAddress(coff_file) orelse return; + const target_vaddr = self.getTargetAddress(coff_file) orelse return false; const target_vaddr_with_addend = target_vaddr + self.addend; log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) ", .{ @@ -100,6 +102,8 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: .x86, .x86_64 => self.resolveX86(ctx), else => unreachable, // unhandled target architecture } + + return true; } const Context = struct { From 17ec2cea6455148526f56fa17cb704fd1d656b06 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 28 Mar 2023 21:52:44 +0200 Subject: [PATCH 142/216] macho: remove error_union return from resolveRelocations() --- src/link/MachO.zig | 2 +- src/link/MachO/Atom.zig | 4 ++-- src/link/MachO/Relocation.zig | 20 +++++--------------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 885afd37c3..3206b63fa3 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1091,7 +1091,7 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); if (self.relocs.get(atom_index)) |relocs| { - try Atom.resolveRelocations(self, atom_index, relocs.items, code); + Atom.resolveRelocations(self, atom_index, relocs.items, code); } if (is_hot_update_compatible) { diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 36511dfd78..698e961db4 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -183,11 +183,11 @@ pub fn addLazyBinding(macho_file: *MachO, atom_index: Index, binding: Binding) ! try gop.value_ptr.append(gpa, binding); } -pub fn resolveRelocations(macho_file: *MachO, atom_index: Index, relocs: []Relocation, code: []u8) !void { +pub fn resolveRelocations(macho_file: *MachO, atom_index: Index, relocs: []Relocation, code: []u8) void { log.debug("relocating '{s}'", .{macho_file.getAtom(atom_index).getName(macho_file)}); for (relocs) |*reloc| { if (!reloc.dirty) continue; - try reloc.resolve(macho_file, atom_index, code); + reloc.resolve(macho_file, atom_index, code); reloc.dirty = false; } } diff --git a/src/link/MachO/Relocation.zig b/src/link/MachO/Relocation.zig index 6beae8e8ea..cc565742d1 100644 --- a/src/link/MachO/Relocation.zig +++ b/src/link/MachO/Relocation.zig @@ -50,7 +50,7 @@ pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index { return macho_file.getAtomIndexForSymbol(self.target); } -pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) !void { +pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void { const arch = macho_file.base.options.target.cpu.arch; const atom = macho_file.getAtom(atom_index); const source_sym = atom.getSymbol(macho_file); @@ -68,18 +68,13 @@ pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, cod }); switch (arch) { - .aarch64 => return self.resolveAarch64(source_addr, target_addr, code), - .x86_64 => return self.resolveX8664(source_addr, target_addr, code), + .aarch64 => self.resolveAarch64(source_addr, target_addr, code), + .x86_64 => self.resolveX8664(source_addr, target_addr, code), else => unreachable, } } -fn resolveAarch64( - self: Relocation, - source_addr: u64, - target_addr: i64, - code: []u8, -) !void { +fn resolveAarch64(self: Relocation, source_addr: u64, target_addr: i64, code: []u8) void { const rel_type = @intToEnum(macho.reloc_type_arm64, self.type); if (rel_type == .ARM64_RELOC_UNSIGNED) { return switch (self.length) { @@ -212,12 +207,7 @@ fn resolveAarch64( } } -fn resolveX8664( - self: Relocation, - source_addr: u64, - target_addr: i64, - code: []u8, -) !void { +fn resolveX8664(self: Relocation, source_addr: u64, target_addr: i64, code: []u8) void { const rel_type = @intToEnum(macho.reloc_type_x86_64, self.type); switch (rel_type) { .X86_64_RELOC_BRANCH, From dd66e0addb30d795a04324096c913ca89ccbcf40 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 27 Mar 2023 06:55:48 -0400 Subject: [PATCH 143/216] Sema: fix empty slice pointer value We just checked that inst_child_ty was effectively a zero-bit type, so it is certainly not the non-zero alignment we are looking for. Closes #15085 --- src/Sema.zig | 7 ++++++- src/codegen/c.zig | 2 +- src/codegen/llvm.zig | 2 +- test/behavior/slice.zig | 16 ++++++++++++---- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 13327657a8..1f375853cb 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -25152,7 +25152,7 @@ fn coerceExtra( .ptr = if (dest_info.@"align" != 0) try Value.Tag.int_u64.create(sema.arena, dest_info.@"align") else - try inst_child_ty.lazyAbiAlignment(target, sema.arena), + try dest_info.pointee_type.lazyAbiAlignment(target, sema.arena), .len = Value.zero, }); return sema.addConstant(dest_ty, slice_val); @@ -30213,6 +30213,11 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void { try sema.resolveLazyValue(elem_val); } }, + .slice => { + const slice = val.castTag(.slice).?.data; + try sema.resolveLazyValue(slice.ptr); + return sema.resolveLazyValue(slice.len); + }, else => return, } } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 0c85f0f923..6c4bb3c688 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1069,7 +1069,7 @@ pub const DeclGen = struct { const extern_fn = val.castTag(.extern_fn).?.data; try dg.renderDeclName(writer, extern_fn.owner_decl, 0); }, - .int_u64, .one => { + .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => { try writer.writeAll("(("); try dg.renderType(writer, ty); return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index dd13087afe..4b28fe2afe 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3397,7 +3397,7 @@ pub const DeclGen = struct { }; return dg.context.constStruct(&fields, fields.len, .False); }, - .int_u64, .one, .int_big_positive => { + .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => { const llvm_usize = try dg.lowerType(Type.usize); const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(target), .False); return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 029f6838d0..a9aa9e50e1 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -723,10 +723,18 @@ test "slice with dereferenced value" { test "empty slice ptr is non null" { if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO - const empty_slice: []u8 = &[_]u8{}; - const p: [*]u8 = empty_slice.ptr + 0; - const t = @ptrCast([*]i8, p); - try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr)); + { + const empty_slice: []u8 = &[_]u8{}; + const p: [*]u8 = empty_slice.ptr + 0; + const t = @ptrCast([*]i8, p); + try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr)); + } + { + const empty_slice: []u8 = &.{}; + const p: [*]u8 = empty_slice.ptr + 0; + const t = @ptrCast([*]i8, p); + try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr)); + } } test "slice decays to many pointer" { From ff97bd21c3b6a5079f33ff389da0716a12806e29 Mon Sep 17 00:00:00 2001 From: dweiller <4678790+dweiller@users.noreplay.github.com> Date: Thu, 30 Mar 2023 13:18:13 +1100 Subject: [PATCH 144/216] tests: enable test_runner_module_imports standalone test --- test/standalone.zig | 4 ++++ test/standalone/test_runner_module_imports/build.zig | 1 + 2 files changed, 5 insertions(+) diff --git a/test/standalone.zig b/test/standalone.zig index 98297e9578..92221b9cfb 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -77,6 +77,10 @@ pub const build_cases = [_]BuildCase{ .build_root = "test/standalone/test_runner_path", .import = @import("standalone/test_runner_path/build.zig"), }, + .{ + .build_root = "test/standalone/test_runner_module_imports", + .import = @import("standalone/test_runner_module_imports/build.zig"), + }, .{ .build_root = "test/standalone/issue_13970", .import = @import("standalone/issue_13970/build.zig"), diff --git a/test/standalone/test_runner_module_imports/build.zig b/test/standalone/test_runner_module_imports/build.zig index 73c5536dc6..685a6b1e3d 100644 --- a/test/standalone/test_runner_module_imports/build.zig +++ b/test/standalone/test_runner_module_imports/build.zig @@ -16,4 +16,5 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&t.run().step); + b.default_step = test_step; } From 0543def52f5ec2d76dc415da2546e478af491ac3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 29 Mar 2023 21:22:14 -0400 Subject: [PATCH 145/216] llvm: fix crashes when loading a struct field The result of buildStructGEP is not always a GEP (sorry), so we can't use getGEPResultElementType on it. Closes #14641 --- src/codegen/llvm.zig | 6 +++--- src/codegen/llvm/bindings.zig | 3 --- src/zig_llvm.cpp | 4 ---- src/zig_llvm.h | 2 -- test/behavior/union.zig | 11 +++++++++++ 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4b28fe2afe..8577252423 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5558,7 +5558,7 @@ pub const FuncGen = struct { return fg.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false); } - const load_inst = fg.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, ""); + const load_inst = fg.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, ""); load_inst.setAlignment(payload_ty.abiAlignment(target)); return load_inst; } @@ -6792,7 +6792,7 @@ pub const FuncGen = struct { return self.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false); } - const load_inst = self.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, ""); + const load_inst = self.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, ""); load_inst.setAlignment(payload_ty.abiAlignment(target)); return load_inst; } @@ -8580,7 +8580,7 @@ pub const FuncGen = struct { } const tag_index = @boolToInt(layout.tag_align < layout.payload_align); const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, ""); - return self.builder.buildLoad(tag_field_ptr.getGEPResultElementType(), tag_field_ptr, ""); + return self.builder.buildLoad(llvm_un_ty.structGetTypeAtIndex(tag_index), tag_field_ptr, ""); } else { if (layout.payload_size == 0) { return union_handle; diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index c759c7874b..ef0e55a12c 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -254,9 +254,6 @@ pub const Value = opaque { pub const addFunctionAttr = ZigLLVMAddFunctionAttr; extern fn ZigLLVMAddFunctionAttr(Fn: *Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void; - pub const getGEPResultElementType = ZigLLVMGetGEPResultElementType; - extern fn ZigLLVMGetGEPResultElementType(GEP: *Value) *Type; - pub const addByValAttr = ZigLLVMAddByValAttr; extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void; }; diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 4f73bd2c3c..586abf5b04 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -1239,10 +1239,6 @@ void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef Attribute::get(call_inst->getContext(), Attribute::ElementType, llvm_type)); } -LLVMTypeRef ZigLLVMGetGEPResultElementType(LLVMValueRef GEP) { - return wrap(unwrap(GEP)->getResultElementType()); -} - void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { unwrap(function)->setPrefixData(unwrap(data)); } diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 70c53f61a4..de62592781 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -332,8 +332,6 @@ ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val); ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty); ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); -ZIG_EXTERN_C LLVMTypeRef ZigLLVMGetGEPResultElementType(LLVMValueRef GEP); - ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 35bdca270e..20ad0a60ff 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1529,3 +1529,14 @@ test "reinterpreting enum value inside packed union" { try U.doTest(); comptime try U.doTest(); } + +test "access the tag of a global tagged union" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + + const U = union(enum) { + a, + b: u8, + var u: @This() = .a; + }; + try expect(U.u == .a); +} From 9c3bea8482915277093a5cb68eba6e05f01d404a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 29 Mar 2023 19:47:52 -0400 Subject: [PATCH 146/216] zig.h: fix non-msvc warnings in msvc code --- lib/zig.h | 102 +++++++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/lib/zig.h b/lib/zig.h index 59c3ddd695..677464b49b 100644 --- a/lib/zig.h +++ b/lib/zig.h @@ -2796,6 +2796,10 @@ static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_ /* ========================= Floating Point Support ========================= */ #if _MSC_VER +float __cdecl nanf(char const* input); +double __cdecl nan(char const* input); +long double __cdecl nanl(char const* input); + #define zig_msvc_flt_inf ((double)(1e+300 * 1e+300)) #define zig_msvc_flt_inff ((float)(1e+300 * 1e+300)) #define zig_msvc_flt_infl ((long double)(1e+300 * 1e+300)) @@ -3203,10 +3207,10 @@ zig_float_builtins(f128) // TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 -#define zig_msvc_atomics(ZigType, Type, suffix) \ +#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \ static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \ Type comparand = *expected; \ - Type initial = _InterlockedCompareExchange##suffix(obj, desired, comparand); \ + Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \ bool exchanged = initial == comparand; \ if (!exchanged) { \ *expected = initial; \ @@ -3214,10 +3218,10 @@ zig_float_builtins(f128) return exchanged; \ } \ static inline Type zig_msvc_atomicrmw_xchg_##ZigType(Type volatile* obj, Type value) { \ - return _InterlockedExchange##suffix(obj, value); \ + return _InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ } \ static inline Type zig_msvc_atomicrmw_add_##ZigType(Type volatile* obj, Type value) { \ - return _InterlockedExchangeAdd##suffix(obj, value); \ + return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)value); \ } \ static inline Type zig_msvc_atomicrmw_sub_##ZigType(Type volatile* obj, Type value) { \ bool success = false; \ @@ -3231,13 +3235,13 @@ zig_float_builtins(f128) return prev; \ } \ static inline Type zig_msvc_atomicrmw_or_##ZigType(Type volatile* obj, Type value) { \ - return _InterlockedOr##suffix(obj, value); \ + return _InterlockedOr##suffix((SigType volatile*)obj, (SigType)value); \ } \ static inline Type zig_msvc_atomicrmw_xor_##ZigType(Type volatile* obj, Type value) { \ - return _InterlockedXor##suffix(obj, value); \ + return _InterlockedXor##suffix((SigType volatile*)obj, (SigType)value); \ } \ static inline Type zig_msvc_atomicrmw_and_##ZigType(Type volatile* obj, Type value) { \ - return _InterlockedAnd##suffix(obj, value); \ + return _InterlockedAnd##suffix((SigType volatile*)obj, (SigType)value); \ } \ static inline Type zig_msvc_atomicrmw_nand_##ZigType(Type volatile* obj, Type value) { \ bool success = false; \ @@ -3273,22 +3277,22 @@ zig_float_builtins(f128) return prev; \ } \ static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ - _InterlockedExchange##suffix(obj, value); \ + (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ } \ static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \ - return _InterlockedOr##suffix(obj, 0); \ + return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \ } -zig_msvc_atomics( u8, uint8_t, 8) -zig_msvc_atomics( i8, int8_t, 8) -zig_msvc_atomics(u16, uint16_t, 16) -zig_msvc_atomics(i16, int16_t, 16) -zig_msvc_atomics(u32, uint32_t, ) -zig_msvc_atomics(i32, int32_t, ) +zig_msvc_atomics( u8, uint8_t, char, 8) +zig_msvc_atomics( i8, int8_t, char, 8) +zig_msvc_atomics(u16, uint16_t, short, 16) +zig_msvc_atomics(i16, int16_t, short, 16) +zig_msvc_atomics(u32, uint32_t, long, ) +zig_msvc_atomics(i32, int32_t, long, ) #if _M_X64 -zig_msvc_atomics(u64, uint64_t, 64) -zig_msvc_atomics(i64, int64_t, 64) +zig_msvc_atomics(u64, uint64_t, __int64, 64) +zig_msvc_atomics(i64, int64_t, __int64, 64) #endif #define zig_msvc_flt_atomics(Type, ReprType, suffix) \ @@ -3336,9 +3340,9 @@ zig_msvc_atomics(i64, int64_t, 64) return expected; \ } -zig_msvc_flt_atomics(f32, uint32_t, ) +zig_msvc_flt_atomics(f32, long, ) #if _M_X64 -zig_msvc_flt_atomics(f64, uint64_t, 64) +zig_msvc_flt_atomics(f64, int64_t, 64) #endif #if _M_IX86 @@ -3349,56 +3353,52 @@ static inline void zig_msvc_atomic_barrier() { } } -static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, void* arg) { +static inline void* zig_msvc_atomicrmw_xchg_p32(void volatile* obj, void* arg) { return _InterlockedExchangePointer(obj, arg); } -static inline void zig_msvc_atomic_store_p32(void** obj, void* arg) { - _InterlockedExchangePointer(obj, arg); +static inline void zig_msvc_atomic_store_p32(void volatile* obj, void* arg) { + (void)_InterlockedExchangePointer(obj, arg); } -static inline void* zig_msvc_atomic_load_p32(void** obj) { - return (void*)_InterlockedOr((void*)obj, 0); +static inline void* zig_msvc_atomic_load_p32(void volatile* obj) { + return (void*)_InterlockedExchangeAdd(obj, 0); } -static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desired) { - void* comparand = *expected; +static inline bool zig_msvc_cmpxchg_p32(void volatile* obj, void* expected, void* desired) { + void* comparand = *(void**)expected; void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); - bool exchanged = initial == comparand; - if (!exchanged) { - *expected = initial; - } - return exchanged; + bool success = initial == comparand; + if (!success) *(void**)expected = initial; + return success; } #else /* _M_IX86 */ -static inline void* zig_msvc_atomicrmw_xchg_p64(void** obj, void* arg) { +static inline void* zig_msvc_atomicrmw_xchg_p64(void volatile* obj, void* arg) { return _InterlockedExchangePointer(obj, arg); } -static inline void zig_msvc_atomic_store_p64(void** obj, void* arg) { - _InterlockedExchangePointer(obj, arg); +static inline void zig_msvc_atomic_store_p64(void volatile* obj, void* arg) { + (void)_InterlockedExchangePointer(obj, arg); } -static inline void* zig_msvc_atomic_load_p64(void** obj) { - return (void*)_InterlockedOr64((void*)obj, 0); +static inline void* zig_msvc_atomic_load_p64(void volatile* obj) { + return (void*)_InterlockedExchangeAdd64(obj, 0); } -static inline bool zig_msvc_cmpxchg_p64(void** obj, void** expected, void* desired) { - void* comparand = *expected; +static inline bool zig_msvc_cmpxchg_p64(void volatile* obj, void* expected, void* desired) { + void* comparand = *(void**)expected; void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); - bool exchanged = initial == comparand; - if (!exchanged) { - *expected = initial; - } - return exchanged; + bool success = initial == comparand; + if (!success) *(void**)expected = initial; + return success; } static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) { - return _InterlockedCompareExchange128((int64_t volatile*)obj, desired.hi, desired.lo, (int64_t*)expected); + return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected); } static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) { - return _InterlockedCompareExchange128((int64_t volatile*)obj, desired.hi, desired.lo, (uint64_t*)expected); + return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected); } #define zig_msvc_atomics_128xchg(Type) \ @@ -3471,16 +3471,16 @@ static inline void* zig_x86_windows_teb(void) { #if (_MSC_VER && (_M_IX86 || _M_X64)) || defined(__i386__) || defined(__x86_64__) static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { - uint32_t cpu_info[4]; #if _MSC_VER + int cpu_info[4]; __cpuidex(cpu_info, leaf_id, subid); + *eax = (uint32_t)cpu_info[0]; + *ebx = (uint32_t)cpu_info[1]; + *ecx = (uint32_t)cpu_info[2]; + *edx = (uint32_t)cpu_info[3]; #else - __cpuid_count(leaf_id, subid, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]); + __cpuid_count(leaf_id, subid, *eax, *ebx, *ecx, *edx); #endif - *eax = cpu_info[0]; - *ebx = cpu_info[1]; - *ecx = cpu_info[2]; - *edx = cpu_info[3]; } static inline uint32_t zig_x86_get_xcr0(void) { From 11903436a9818cba1ef474dfd705d10798d16ef6 Mon Sep 17 00:00:00 2001 From: Tw Date: Tue, 28 Mar 2023 16:26:24 +0800 Subject: [PATCH 147/216] llvm/bpf: disable llvm builtins for bpf target As bpf program has no global section for constant values (especially strings), so use llvm's builtins (like memcpy, memset, etc) will lead to compilation failure (something like this: A call to built-in function 'memcpy' is not supported.) Signed-off-by: Tw --- src/codegen/llvm.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8577252423..eea68a80e9 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2719,6 +2719,9 @@ pub const DeclGen = struct { if (comp.bin_file.options.llvm_cpu_features) |s| { llvm_fn.addFunctionAttr("target-features", s); } + if (comp.getTarget().cpu.arch.isBpf()) { + llvm_fn.addFunctionAttr("no-builtins", ""); + } } fn resolveGlobalDecl(dg: *DeclGen, decl_index: Module.Decl.Index) Error!*llvm.Value { From 83051b0cbf31b76e824d3911a7f4a0be3c0cf94d Mon Sep 17 00:00:00 2001 From: Silver Date: Fri, 24 Mar 2023 00:38:02 +0000 Subject: [PATCH 148/216] Update GDB pretty printers --- tools/zig_gdb_pretty_printers.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tools/zig_gdb_pretty_printers.py b/tools/zig_gdb_pretty_printers.py index 7397097cc1..1bc4b36e57 100644 --- a/tools/zig_gdb_pretty_printers.py +++ b/tools/zig_gdb_pretty_printers.py @@ -2,22 +2,24 @@ # put "source /path/to/zig_gdb_pretty_printers.py" in ~/.gdbinit to load it automatically. import gdb.printing + class ZigPrettyPrinter(gdb.printing.PrettyPrinter): def __init__(self): super().__init__('Zig') def __call__(self, val): tag = val.type.tag - if(tag is None): + if tag is None: return None - if(tag == '[]u8'): + if tag == '[]u8': return StringPrinter(val) - if(tag.startswith('[]')): + if tag.startswith('[]'): return SlicePrinter(val) - if(tag.startswith('?')): + if tag.startswith('?'): return OptionalPrinter(val) return None + class SlicePrinter: def __init__(self, val): self.val = val @@ -35,6 +37,7 @@ class SlicePrinter: def display_hint(self): return 'array' + class StringPrinter: def __init__(self, val): self.val = val @@ -45,20 +48,16 @@ class StringPrinter: def display_hint(self): return 'string' + class OptionalPrinter: def __init__(self, val): self.val = val def to_string(self): - if(self.val['maybe']): - return None # printed by children() + if self.val['some']: + return self.val['data'] else: return 'null' - def children(self): - def it(val): - if(val['maybe']): - yield ('payload', val['val']) - return it(self.val) gdb.printing.register_pretty_printer(gdb.current_objfile(), ZigPrettyPrinter()) From 3357c59cebacb6b60da865376b20d2b307d12ec1 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 18 Mar 2023 15:59:56 +0100 Subject: [PATCH 149/216] new builtins: @workItemId, @workGroupId, @workGroupSize * @workItemId returns the index of the work item in a work group for a dimension. * @workGroupId returns the index of the work group in the kernel dispatch for a dimension. * @workGroupSize returns the size of the work group for a dimension. These builtins are mainly useful for GPU backends. They are currently only implemented for the AMDGCN LLVM backend. --- doc/langref.html.in | 22 +++++++++++ src/Air.zig | 21 +++++++++++ src/AstGen.zig | 34 +++++++++++++++++ src/BuiltinFn.zig | 23 ++++++++++++ src/Liveness.zig | 6 +++ src/Sema.zig | 39 +++++++++++++++++++ src/Zir.zig | 9 +++++ src/arch/aarch64/CodeGen.zig | 4 ++ src/arch/arm/CodeGen.zig | 4 ++ src/arch/riscv64/CodeGen.zig | 4 ++ src/arch/sparc64/CodeGen.zig | 4 ++ src/arch/wasm/CodeGen.zig | 5 +++ src/arch/x86_64/CodeGen.zig | 4 ++ src/codegen/c.zig | 5 +++ src/codegen/llvm.zig | 72 ++++++++++++++++++++++++++++++++++++ src/print_air.zig | 10 +++++ src/print_zir.zig | 3 ++ 17 files changed, 269 insertions(+) diff --git a/doc/langref.html.in b/doc/langref.html.in index 907464867e..19ee6cdab2 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -9578,6 +9578,28 @@ fn foo(comptime T: type, ptr: *T) T { Remove {#syntax#}volatile{#endsyntax#} qualifier from a pointer.

{#header_close#} + + {#header_open|@workGroupId#} +
{#syntax#}@workGroupId(comptime dimension: u32) u32{#endsyntax#}
+

+ Returns the index of the work group in the current kernel invocation in dimension {#syntax#}dimension{#endsyntax#}. +

+ {#header_close#} + + {#header_open|@workGroupSize#} +
{#syntax#}@workGroupSize(comptime dimension: u32) u32{#endsyntax#}
+

+ Returns the number of work items that a work group has in dimension {#syntax#}dimension{#endsyntax#}. +

+ {#header_close#} + + {#header_open|@workItemId#} +
{#syntax#}@workItemId(comptime dimension: u32) u32{#endsyntax#}
+

+ Returns the index of the work item in the work group in dimension {#syntax#}dimension{#endsyntax#}. This function returns values between {#syntax#}0{#endsyntax#} (inclusive) and {#syntax#}@workGroupSize(dimension){#endsyntax#} (exclusive). +

+ {#header_close#} + {#header_close#} {#header_open|Build Mode#} diff --git a/src/Air.zig b/src/Air.zig index 4646dcc89e..c63e9826f9 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -761,6 +761,22 @@ pub const Inst = struct { /// Uses the `ty` field. c_va_start, + /// Implements @workItemId builtin. + /// Result type is always `u32` + /// Uses the `pl_op` field, payload is the dimension to get the work item id for. + /// Operand is unused and set to Ref.none + work_item_id, + /// Implements @workGroupSize builtin. + /// Result type is always `u32` + /// Uses the `pl_op` field, payload is the dimension to get the work group size for. + /// Operand is unused and set to Ref.none + work_group_size, + /// Implements @workGroupId builtin. + /// Result type is always `u32` + /// Uses the `pl_op` field, payload is the dimension to get the work group id for. + /// Operand is unused and set to Ref.none + work_group_id, + pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag { switch (op) { .lt => return if (optimized) .cmp_lt_optimized else .cmp_lt, @@ -1267,6 +1283,11 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { const err_union_ty = air.typeOf(datas[inst].pl_op.operand); return err_union_ty.errorUnionPayload(); }, + + .work_item_id, + .work_group_size, + .work_group_id, + => return Type.u32, } } diff --git a/src/AstGen.zig b/src/AstGen.zig index c91303cdb1..4f786edce8 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -8549,6 +8549,40 @@ fn builtinCall( } return rvalue(gz, ri, try gz.addNodeExtended(.c_va_start, node), node); }, + + .work_item_id => { + if (astgen.fn_block == null) { + return astgen.failNode(node, "'@workItemId' outside function scope", .{}); + } + const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); + const result = try gz.addExtendedPayload(.work_item_id, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }); + return rvalue(gz, ri, result, node); + }, + .work_group_size => { + if (astgen.fn_block == null) { + return astgen.failNode(node, "'@workGroupSize' outside function scope", .{}); + } + const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); + const result = try gz.addExtendedPayload(.work_group_size, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }); + return rvalue(gz, ri, result, node); + }, + .work_group_id => { + if (astgen.fn_block == null) { + return astgen.failNode(node, "'@workGroupId' outside function scope", .{}); + } + const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); + const result = try gz.addExtendedPayload(.work_group_id, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }); + return rvalue(gz, ri, result, node); + }, } } diff --git a/src/BuiltinFn.zig b/src/BuiltinFn.zig index 79c6617483..4a98a5a615 100644 --- a/src/BuiltinFn.zig +++ b/src/BuiltinFn.zig @@ -118,6 +118,9 @@ pub const Tag = enum { union_init, Vector, volatile_cast, + work_item_id, + work_group_size, + work_group_id, }; pub const MemLocRequirement = enum { @@ -980,5 +983,25 @@ pub const list = list: { .param_count = 1, }, }, + .{ + "@workItemId", .{ + .tag = .work_item_id, + .param_count = 1, + }, + }, + .{ + "@workGroupSize", + .{ + .tag = .work_group_size, + .param_count = 1, + }, + }, + .{ + "@workGroupId", + .{ + .tag = .work_group_id, + .param_count = 1, + }, + }, }); }; diff --git a/src/Liveness.zig b/src/Liveness.zig index 8dc81aa165..1d57b80097 100644 --- a/src/Liveness.zig +++ b/src/Liveness.zig @@ -240,6 +240,9 @@ pub fn categorizeOperand( .err_return_trace, .save_err_return_trace_index, .c_va_start, + .work_item_id, + .work_group_size, + .work_group_id, => return .none, .fence => return .write, @@ -864,6 +867,9 @@ fn analyzeInst( .err_return_trace, .save_err_return_trace_index, .c_va_start, + .work_item_id, + .work_group_size, + .work_group_id, => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }), .not, diff --git a/src/Sema.zig b/src/Sema.zig index 1f375853cb..da93a2906a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1164,6 +1164,9 @@ fn analyzeBodyInner( .c_va_start => try sema.zirCVaStart( block, extended), .const_cast, => try sema.zirConstCast( block, extended), .volatile_cast, => try sema.zirVolatileCast( block, extended), + .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode), + .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode), + .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode), // zig fmt: on .fence => { @@ -22437,6 +22440,42 @@ fn zirBuiltinExtern( return sema.addConstant(ty, ref); } +fn zirWorkItem( + sema: *Sema, + block: *Block, + extended: Zir.Inst.Extended.InstData, + zir_tag: Zir.Inst.Extended, +) CompileError!Air.Inst.Ref { + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const dimension_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const builtin_src = LazySrcLoc.nodeOffset(extra.node); + const target = sema.mod.getTarget(); + + switch (target.cpu.arch) { + // TODO: Allow for other GPU targets. + .amdgcn => {}, + else => { + return sema.fail(block, builtin_src, "builtin only available on GPU targets; targeted architecture is {s}", .{@tagName(target.cpu.arch)}); + }, + } + + const dimension = @intCast(u32, try sema.resolveInt(block, dimension_src, extra.operand, Type.u32, "dimension must be comptime-known")); + try sema.requireRuntimeBlock(block, builtin_src, null); + + return block.addInst(.{ + .tag = switch (zir_tag) { + .work_item_id => .work_item_id, + .work_group_size => .work_group_size, + .work_group_id => .work_group_id, + else => unreachable, + }, + .data = .{ .pl_op = .{ + .operand = .none, + .payload = dimension, + } }, + }); +} + fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void { if (block.is_comptime) { const msg = msg: { diff --git a/src/Zir.zig b/src/Zir.zig index bc5202c8aa..7a8df49fda 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -2032,6 +2032,15 @@ pub const Inst = struct { /// Implements the `@volatileCast` builtin. /// `operand` is payload index to `UnNode`. volatile_cast, + /// Implements the `@workItemId` builtin. + /// `operand` is payload index to `UnNode`. + work_item_id, + /// Implements the `@workGroupSize` builtin. + /// `operand` is payload index to `UnNode`. + work_group_size, + /// Implements the `@workGroupId` builtin. + /// `operand` is payload index to `UnNode`. + work_group_id, pub const InstData = struct { opcode: Extended, diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index ee23696950..1e07e7e719 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -890,6 +890,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .wasm_memory_size => unreachable, .wasm_memory_grow => unreachable, + + .work_item_id => unreachable, + .work_group_size => unreachable, + .work_group_id => unreachable, // zig fmt: on } diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 8de5ae006a..1cf0e2981e 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -874,6 +874,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .wasm_memory_size => unreachable, .wasm_memory_grow => unreachable, + + .work_item_id => unreachable, + .work_group_size => unreachable, + .work_group_id => unreachable, // zig fmt: on } diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 68df794bf7..11dbb2cb08 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -704,6 +704,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .wasm_memory_size => unreachable, .wasm_memory_grow => unreachable, + + .work_item_id => unreachable, + .work_group_size => unreachable, + .work_group_id => unreachable, // zig fmt: on } if (std.debug.runtime_safety) { diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 30df999267..a1b1be3a76 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -720,6 +720,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .wasm_memory_size => unreachable, .wasm_memory_grow => unreachable, + + .work_item_id => unreachable, + .work_group_size => unreachable, + .work_group_id => unreachable, // zig fmt: on } diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 199ddada65..fc5d13e5a4 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1997,6 +1997,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { .reduce_optimized, .float_to_int_optimized, => return func.fail("TODO implement optimized float mode", .{}), + + .work_item_id, + .work_group_size, + .work_group_id, + => unreachable, }; } diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 5ddc9c77ca..604052ee7e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1132,6 +1132,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .wasm_memory_size => unreachable, .wasm_memory_grow => unreachable, + + .work_item_id => unreachable, + .work_group_size => unreachable, + .work_group_id => unreachable, // zig fmt: on } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 6c4bb3c688..704a1e31c5 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2995,6 +2995,11 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, .c_va_arg => try airCVaArg(f, inst), .c_va_end => try airCVaEnd(f, inst), .c_va_copy => try airCVaCopy(f, inst), + + .work_item_id, + .work_group_size, + .work_group_id, + => unreachable, // zig fmt: on }; if (result_value == .new_local) { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index eea68a80e9..ce49fcde78 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4745,6 +4745,10 @@ pub const FuncGen = struct { .c_va_copy => try self.airCVaCopy(inst), .c_va_end => try self.airCVaEnd(inst), .c_va_start => try self.airCVaStart(inst), + + .work_item_id => try self.airWorkItemId(inst), + .work_group_size => try self.airWorkGroupSize(inst), + .work_group_id => try self.airWorkGroupId(inst), // zig fmt: on }; if (opt_value) |val| { @@ -9567,6 +9571,74 @@ pub const FuncGen = struct { return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, ""); } + fn amdgcnWorkIntrinsic(self: *FuncGen, dimension: u32, default: u32, comptime basename: []const u8) !?*llvm.Value { + const llvm_u32 = self.context.intType(32); + + const llvm_fn_name = switch (dimension) { + 0 => basename ++ ".x", + 1 => basename ++ ".y", + 2 => basename ++ ".z", + else => return llvm_u32.constInt(default, .False), + }; + + const args: [0]*llvm.Value = .{}; + const llvm_fn = self.getIntrinsic(llvm_fn_name, &.{}); + return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); + } + + fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + if (self.liveness.isUnused(inst)) return null; + + const target = self.dg.module.getTarget(); + assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures + + const pl_op = self.air.instructions.items(.data)[inst].pl_op; + const dimension = pl_op.payload; + return self.amdgcnWorkIntrinsic(dimension, 0, "llvm.amdgcn.workitem.id"); + } + + fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + if (self.liveness.isUnused(inst)) return null; + + const target = self.dg.module.getTarget(); + assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures + + const pl_op = self.air.instructions.items(.data)[inst].pl_op; + const dimension = pl_op.payload; + const llvm_u32 = self.context.intType(32); + if (dimension >= 3) { + return llvm_u32.constInt(1, .False); + } + + // Fetch the dispatch pointer, which points to this structure: + // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913 + const llvm_fn = self.getIntrinsic("llvm.amdgcn.dispatch.ptr", &.{}); + const args: [0]*llvm.Value = .{}; + const dispatch_ptr = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); + dispatch_ptr.setAlignment(4); + + // Load the work_group_* member from the struct as u16. + // Just treat the dispatch pointer as an array of u16 to keep things simple. + const offset = 2 + dimension; + const index = [_]*llvm.Value{llvm_u32.constInt(offset, .False)}; + const llvm_u16 = self.context.intType(16); + const workgroup_size_ptr = self.builder.buildInBoundsGEP(llvm_u16, dispatch_ptr, &index, index.len, ""); + const workgroup_size = self.builder.buildLoad(llvm_u16, workgroup_size_ptr, ""); + workgroup_size.setAlignment(2); + return workgroup_size; + } + + fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + if (self.liveness.isUnused(inst)) return null; + + const target = self.dg.module.getTarget(); + assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures + + const pl_op = self.air.instructions.items(.data)[inst].pl_op; + const dimension = pl_op.payload; + return self.amdgcnWorkIntrinsic(dimension, 0, "llvm.amdgcn.workgroup.id"); + } + fn getErrorNameTable(self: *FuncGen) !*llvm.Value { if (self.dg.object.error_name_table) |table| { return table; diff --git a/src/print_air.zig b/src/print_air.zig index 8d29a272ca..803a0f2886 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -328,6 +328,11 @@ const Writer = struct { .vector_store_elem => try w.writeVectorStoreElem(s, inst), .dbg_block_begin, .dbg_block_end => {}, + + .work_item_id, + .work_group_size, + .work_group_id, + => try w.writeWorkDimension(s, inst), } try s.writeAll(")\n"); } @@ -869,6 +874,11 @@ const Writer = struct { try w.writeOperand(s, inst, 0, pl_op.operand); } + fn writeWorkDimension(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + const pl_op = w.air.instructions.items(.data)[inst].pl_op; + try s.print("{d}", .{pl_op.payload}); + } + fn writeOperand( w: *Writer, s: anytype, diff --git a/src/print_zir.zig b/src/print_zir.zig index 755107cd1a..b70a4bbf67 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -512,6 +512,9 @@ const Writer = struct { .c_va_end, .const_cast, .volatile_cast, + .work_item_id, + .work_group_size, + .work_group_id, => { const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(inst_data.node); From 64214b1ca6a295af8521ed6fb3be5a3244a42564 Mon Sep 17 00:00:00 2001 From: bing Date: Thu, 30 Mar 2023 16:51:57 +0000 Subject: [PATCH 150/216] Change ordering of prep provide buffers args --- lib/std/os/linux/io_uring.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/std/os/linux/io_uring.zig b/lib/std/os/linux/io_uring.zig index 4dbf87c501..5b8f0189fa 100644 --- a/lib/std/os/linux/io_uring.zig +++ b/lib/std/os/linux/io_uring.zig @@ -897,13 +897,13 @@ pub const IO_Uring = struct { self: *IO_Uring, user_data: u64, buffers: [*]u8, - buffers_count: usize, buffer_size: usize, + buffers_count: usize, group_id: usize, buffer_id: usize, ) !*linux.io_uring_sqe { const sqe = try self.get_sqe(); - io_uring_prep_provide_buffers(sqe, buffers, buffers_count, buffer_size, group_id, buffer_id); + io_uring_prep_provide_buffers(sqe, buffers, buffer_size, buffers_count, group_id, buffer_id); sqe.user_data = user_data; return sqe; } @@ -1576,8 +1576,8 @@ pub fn io_uring_prep_linkat( pub fn io_uring_prep_provide_buffers( sqe: *linux.io_uring_sqe, buffers: [*]u8, - num: usize, buffer_len: usize, + num: usize, group_id: usize, buffer_id: usize, ) void { @@ -2892,7 +2892,7 @@ test "provide_buffers: read" { // Provide 4 buffers { - const sqe = try ring.provide_buffers(0xcccccccc, @ptrCast([*]u8, &buffers), buffers.len, buffer_len, group_id, buffer_id); + const sqe = try ring.provide_buffers(0xcccccccc, @ptrCast([*]u8, &buffers), buffer_len, buffers.len, group_id, buffer_id); try testing.expectEqual(linux.IORING_OP.PROVIDE_BUFFERS, sqe.opcode); try testing.expectEqual(@as(i32, buffers.len), sqe.fd); try testing.expectEqual(@as(u32, buffers[0].len), sqe.len); @@ -2965,7 +2965,7 @@ test "provide_buffers: read" { const reprovided_buffer_id = 2; { - _ = try ring.provide_buffers(0xabababab, @ptrCast([*]u8, &buffers[reprovided_buffer_id]), 1, buffer_len, group_id, reprovided_buffer_id); + _ = try ring.provide_buffers(0xabababab, @ptrCast([*]u8, &buffers[reprovided_buffer_id]), buffer_len, 1, group_id, reprovided_buffer_id); try testing.expectEqual(@as(u32, 1), try ring.submit()); const cqe = try ring.copy_cqe(); @@ -3024,7 +3024,7 @@ test "remove_buffers" { // Provide 4 buffers { - _ = try ring.provide_buffers(0xcccccccc, @ptrCast([*]u8, &buffers), buffers.len, buffer_len, group_id, buffer_id); + _ = try ring.provide_buffers(0xcccccccc, @ptrCast([*]u8, &buffers), buffer_len, buffers.len, group_id, buffer_id); try testing.expectEqual(@as(u32, 1), try ring.submit()); const cqe = try ring.copy_cqe(); @@ -3113,7 +3113,7 @@ test "provide_buffers: accept/connect/send/recv" { // Provide 4 buffers { - const sqe = try ring.provide_buffers(0xcccccccc, @ptrCast([*]u8, &buffers), buffers.len, buffer_len, group_id, buffer_id); + const sqe = try ring.provide_buffers(0xcccccccc, @ptrCast([*]u8, &buffers), buffer_len, buffers.len, group_id, buffer_id); try testing.expectEqual(linux.IORING_OP.PROVIDE_BUFFERS, sqe.opcode); try testing.expectEqual(@as(i32, buffers.len), sqe.fd); try testing.expectEqual(@as(u32, buffer_len), sqe.len); @@ -3207,7 +3207,7 @@ test "provide_buffers: accept/connect/send/recv" { const reprovided_buffer_id = 2; { - _ = try ring.provide_buffers(0xabababab, @ptrCast([*]u8, &buffers[reprovided_buffer_id]), 1, buffer_len, group_id, reprovided_buffer_id); + _ = try ring.provide_buffers(0xabababab, @ptrCast([*]u8, &buffers[reprovided_buffer_id]), buffer_len, 1, group_id, reprovided_buffer_id); try testing.expectEqual(@as(u32, 1), try ring.submit()); const cqe = try ring.copy_cqe(); From 22e1b033607580756329879ba7158a29aca57981 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 00:57:53 +0200 Subject: [PATCH 151/216] coff: use copy in zig-cache for child process in HCS Ideally, we would just do an atomic rename, but so far I had no luck. I have also tried marking the file to delete-on-close but then we cannot use it to spawn the process. So for now, let's just put a copy in `zig-cache` and let the user decide when to recycle the cache dir. --- src/link.zig | 40 +++++++++++++++++++++++----------------- src/link/Coff.zig | 5 +++++ src/main.zig | 24 +++++++++++++++++++----- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/link.zig b/src/link.zig index 239dc646b2..d821027196 100644 --- a/src/link.zig +++ b/src/link.zig @@ -379,24 +379,30 @@ pub const File = struct { if (base.file != null) return; const emit = base.options.emit orelse return; if (base.child_pid) |pid| { - // If we try to open the output file in write mode while it is running, - // it will return ETXTBSY. So instead, we copy the file, atomically rename it - // over top of the exe path, and then proceed normally. This changes the inode, - // avoiding the error. - const tmp_sub_path = try std.fmt.allocPrint(base.allocator, "{s}-{x}", .{ - emit.sub_path, std.crypto.random.int(u32), - }); - try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); - try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); - switch (builtin.os.tag) { - .linux => std.os.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { - log.warn("ptrace failure: {s}", .{@errorName(err)}); - }, - .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| { + if (builtin.os.tag == .windows) { + base.cast(Coff).?.ptraceAttach(pid) catch |err| { log.warn("attaching failed with error: {s}", .{@errorName(err)}); - }, - .windows => {}, - else => return error.HotSwapUnavailableOnHostOperatingSystem, + }; + } else { + // If we try to open the output file in write mode while it is running, + // it will return ETXTBSY. So instead, we copy the file, atomically rename it + // over top of the exe path, and then proceed normally. This changes the inode, + // avoiding the error. + const tmp_sub_path = try std.fmt.allocPrint(base.allocator, "{s}-{x}", .{ + emit.sub_path, std.crypto.random.int(u32), + }); + try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); + try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); + switch (builtin.os.tag) { + .linux => std.os.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { + log.warn("ptrace failure: {s}", .{@errorName(err)}); + }, + .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| { + log.warn("attaching failed with error: {s}", .{@errorName(err)}); + }, + .windows => unreachable, + else => return error.HotSwapUnavailableOnHostOperatingSystem, + } } } base.file = try emit.directory.handle.createFile(emit.sub_path, .{ diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 7b5539287d..240c61bffd 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -827,6 +827,11 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { } } +pub fn ptraceAttach(self: *Coff, handle: std.os.pid_t) !void { + _ = self; + log.warn("attaching to process with handle {*}", .{handle}); +} + fn freeAtom(self: *Coff, atom_index: Atom.Index) void { log.debug("freeAtom {d}", .{atom_index}); diff --git a/src/main.zig b/src/main.zig index c96fd25766..1a445107ba 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3817,11 +3817,25 @@ fn runOrTestHotSwap( runtime_args_start: ?usize, ) !std.ChildProcess.Id { const exe_emit = comp.bin_file.options.emit.?; - // A naive `directory.join` here will indeed get the correct path to the binary, - // however, in the case of cwd, we actually want `./foo` so that the path can be executed. - const exe_path = try fs.path.join(gpa, &[_][]const u8{ - exe_emit.directory.path orelse ".", exe_emit.sub_path, - }); + + const exe_path = switch (builtin.target.os.tag) { + // On Windows it seems impossible to perform an atomic rename of a file that is currently + // running in a process. Therefore, we do the opposite. We create a copy of the file in + // tmp zig-cache and use it to spawn the child process. This way we are free to update + // the binary with each requested hot update. + .windows => blk: { + try exe_emit.directory.handle.copyFile(exe_emit.sub_path, comp.local_cache_directory.handle, exe_emit.sub_path, .{}); + break :blk try fs.path.join(gpa, &[_][]const u8{ + comp.local_cache_directory.path orelse ".", exe_emit.sub_path, + }); + }, + + // A naive `directory.join` here will indeed get the correct path to the binary, + // however, in the case of cwd, we actually want `./foo` so that the path can be executed. + else => try fs.path.join(gpa, &[_][]const u8{ + exe_emit.directory.path orelse ".", exe_emit.sub_path, + }), + }; defer gpa.free(exe_path); var argv = std.ArrayList([]const u8).init(gpa); From 39d63036441841fb81eebda97fb2932e5c3f79c4 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 12:32:29 +0200 Subject: [PATCH 152/216] coff: first (not-fully-functional) PoC of HCS --- src/link.zig | 2 +- src/link/Coff.zig | 159 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 157 insertions(+), 4 deletions(-) diff --git a/src/link.zig b/src/link.zig index d821027196..dc114eb0ad 100644 --- a/src/link.zig +++ b/src/link.zig @@ -443,7 +443,7 @@ pub const File = struct { .macos => base.cast(MachO).?.ptraceDetach(pid) catch |err| { log.warn("detaching failed with error: {s}", .{@errorName(err)}); }, - .windows => {}, + .windows => base.cast(Coff).?.ptraceDetach(pid), else => return error.HotSwapUnavailableOnHostOperatingSystem, } } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 240c61bffd..c2421ee912 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -89,6 +89,13 @@ relocs: RelocTable = .{}, /// this will be a table indexed by index into the list of Atoms. base_relocs: BaseRelocationTable = .{}, +/// Hot-code swapping state. +hot_state: HotUpdateState = .{}, + +const HotUpdateState = struct { + loaded_base_address: ?u64 = null, +}; + const Entry = struct { target: SymbolWithLoc, // Index into the synthetic symbol table (i.e., file == null). @@ -778,9 +785,147 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { file_offset + code.len, }); self.resolveRelocs(atom_index, code); + + if (self.base.child_pid) |handle| { + const vaddr = sym.value + (self.hot_state.loaded_base_address orelse self.getImageBase()); + log.warn("hcs: writing to memory at address {x}", .{vaddr}); + try debugMem(self.base.allocator, handle, vaddr, code); + if (section.header.flags.MEM_WRITE == 0) { + log.warn(" page not mapped for write access; re-mapping...", .{}); + try writeMemProtected(handle, vaddr, code); + } else { + try writeMem(handle, vaddr, code); + } + } + try self.base.file.?.pwriteAll(code, file_offset); } +extern "kernel32" fn ReadProcessMemory( + hProcess: std.os.windows.HANDLE, + lpBaseAddress: std.os.windows.LPCVOID, + lpBuffer: std.os.windows.LPVOID, + nSize: std.os.windows.SIZE_T, + lpNumberOfBytesRead: *std.os.windows.SIZE_T, +) std.os.windows.BOOL; + +extern "kernel32" fn WriteProcessMemory( + hProcess: std.os.windows.HANDLE, + lpBaseAddress: std.os.windows.LPVOID, + lpBuffer: std.os.windows.LPCVOID, + nSize: std.os.windows.SIZE_T, + lpNumberOfBytesWritten: *std.os.windows.SIZE_T, +) std.os.windows.BOOL; + +extern "kernel32" fn VirtualProtectEx( + hProcess: std.os.windows.HANDLE, + lpAddress: std.os.windows.LPVOID, + dwSize: std.os.windows.SIZE_T, + flNewProtect: std.os.windows.DWORD, + lpflOldProtect: *std.os.windows.DWORD, +) std.os.windows.BOOL; + +const PROCESS_BASIC_INFORMATION = extern struct { + ExitStatus: std.os.windows.NTSTATUS, + PebBaseAddress: *std.os.windows.PEB, + AffinityMask: std.os.windows.ULONG_PTR, + BasePriority: std.os.windows.KPRIORITY, + UniqueProcessId: std.os.windows.ULONG_PTR, + InheritedFromUniqueProcessId: std.os.windows.ULONG_PTR, +}; + +fn getProcessBaseAddress(handle: std.ChildProcess.Id) !u64 { + var info: PROCESS_BASIC_INFORMATION = undefined; + var nread: std.os.windows.DWORD = 0; + const rc = std.os.windows.ntdll.NtQueryInformationProcess( + handle, + .ProcessBasicInformation, + &info, + @sizeOf(PROCESS_BASIC_INFORMATION), + &nread, + ); + switch (rc) { + .SUCCESS => {}, + else => return std.os.windows.unexpectedStatus(rc), + } + + var peb_buf: [@sizeOf(std.os.windows.PEB)]u8 align(@alignOf(std.os.windows.PEB)) = undefined; + var peb_nread: usize = 0; + if (ReadProcessMemory( + handle, + info.PebBaseAddress, + &peb_buf, + @sizeOf(std.os.windows.PEB), + &peb_nread, + ) == 0) { + const err = std.os.windows.kernel32.GetLastError(); + log.warn("hcs: reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + return error.FailedToReadPebForProcess; + } + if (peb_nread != @sizeOf(std.os.windows.PEB)) return error.InputOutput; + + const peb = @ptrCast(*const std.os.windows.PEB, &peb_buf); + return @ptrToInt(peb.ImageBaseAddress); +} + +fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { + var buffer = try allocator.alloc(u8, code.len); + defer allocator.free(buffer); + var nread: usize = 0; + if (ReadProcessMemory( + handle, + @intToPtr(*anyopaque, vaddr), + buffer.ptr, + code.len, + &nread, + ) == 0) { + const err = std.os.windows.kernel32.GetLastError(); + log.warn("hcs: reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + } + if (nread != code.len) { + log.warn("hcs: reading from process memory InputOutput error: read != requested: {x} != {x}", .{ nread, code.len }); + } + + log.warn("in memory: {x}", .{std.fmt.fmtSliceHexLower(buffer)}); + log.warn("to write: {x}", .{std.fmt.fmtSliceHexLower(code)}); +} + +fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { + const pvaddr = @intToPtr(*anyopaque, vaddr); + var new_prot: std.os.windows.DWORD = std.os.windows.PAGE_EXECUTE_WRITECOPY; + var old_prot: std.os.windows.DWORD = undefined; + if (VirtualProtectEx(handle, pvaddr, code.len, new_prot, &old_prot) == 0) { + const err = std.os.windows.kernel32.GetLastError(); + log.warn("hcs: making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + return; + } + log.warn("old = {x}, new = {x}", .{ old_prot, new_prot }); + try writeMem(handle, vaddr, code); + // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes. + // For that though, we want to track which page has already been modified. + if (VirtualProtectEx(handle, pvaddr, code.len, old_prot, &new_prot) == 0) { + const err = std.os.windows.kernel32.GetLastError(); + log.warn("hcs: restoring page(s) attributes failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + } +} + +fn writeMem(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { + var nwritten: usize = 0; + if (WriteProcessMemory( + handle, + @intToPtr(*anyopaque, vaddr), + code.ptr, + code.len, + &nwritten, + ) == 0) { + const err = std.os.windows.kernel32.GetLastError(); + log.warn("hcs: writing to process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + } + if (nwritten != code.len) { + log.warn("hcs: writing to process memory InputOutput error: written != requested: {x} != {x}", .{ nwritten, code.len }); + } +} + fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { switch (self.ptr_width) { .p32 => { @@ -827,9 +972,17 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { } } -pub fn ptraceAttach(self: *Coff, handle: std.os.pid_t) !void { - _ = self; - log.warn("attaching to process with handle {*}", .{handle}); +pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { + log.warn("hcs: attaching to process with handle {*}", .{handle}); + self.hot_state.loaded_base_address = getProcessBaseAddress(handle) catch |err| { + log.warn("hcs: failed to get base address for the process with error: {s}", .{@errorName(err)}); + return; + }; +} + +pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void { + log.warn("hcs: detaching from process with handle {*}", .{handle}); + self.hot_state.loaded_base_address = null; } fn freeAtom(self: *Coff, atom_index: Atom.Index) void { From d2f013085523436b51023f7d28d52a859b70a4b3 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 14:10:11 +0200 Subject: [PATCH 153/216] coff: make sure we correctly slide relocation target when resolving --- src/link/Coff.zig | 30 ++++++++++++++---------------- src/link/Coff/Relocation.zig | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index c2421ee912..8337d69088 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -788,10 +788,9 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { if (self.base.child_pid) |handle| { const vaddr = sym.value + (self.hot_state.loaded_base_address orelse self.getImageBase()); - log.warn("hcs: writing to memory at address {x}", .{vaddr}); - try debugMem(self.base.allocator, handle, vaddr, code); + log.debug("writing to memory at address {x}", .{vaddr}); if (section.header.flags.MEM_WRITE == 0) { - log.warn(" page not mapped for write access; re-mapping...", .{}); + log.debug("page not mapped for write access; re-mapping...", .{}); try writeMemProtected(handle, vaddr, code); } else { try writeMem(handle, vaddr, code); @@ -859,7 +858,7 @@ fn getProcessBaseAddress(handle: std.ChildProcess.Id) !u64 { &peb_nread, ) == 0) { const err = std.os.windows.kernel32.GetLastError(); - log.warn("hcs: reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + log.warn("reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); return error.FailedToReadPebForProcess; } if (peb_nread != @sizeOf(std.os.windows.PEB)) return error.InputOutput; @@ -880,14 +879,14 @@ fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, vaddr: u64, code: &nread, ) == 0) { const err = std.os.windows.kernel32.GetLastError(); - log.warn("hcs: reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + log.warn("reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); } if (nread != code.len) { - log.warn("hcs: reading from process memory InputOutput error: read != requested: {x} != {x}", .{ nread, code.len }); + log.warn("reading from process memory InputOutput error: read != requested: {x} != {x}", .{ nread, code.len }); } - log.warn("in memory: {x}", .{std.fmt.fmtSliceHexLower(buffer)}); - log.warn("to write: {x}", .{std.fmt.fmtSliceHexLower(code)}); + log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(buffer)}); + log.debug("to write: {x}", .{std.fmt.fmtSliceHexLower(code)}); } fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { @@ -896,16 +895,15 @@ fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) var old_prot: std.os.windows.DWORD = undefined; if (VirtualProtectEx(handle, pvaddr, code.len, new_prot, &old_prot) == 0) { const err = std.os.windows.kernel32.GetLastError(); - log.warn("hcs: making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + log.warn("making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); return; } - log.warn("old = {x}, new = {x}", .{ old_prot, new_prot }); try writeMem(handle, vaddr, code); // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes. // For that though, we want to track which page has already been modified. if (VirtualProtectEx(handle, pvaddr, code.len, old_prot, &new_prot) == 0) { const err = std.os.windows.kernel32.GetLastError(); - log.warn("hcs: restoring page(s) attributes failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + log.warn("restoring page(s) attributes failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); } } @@ -919,10 +917,10 @@ fn writeMem(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { &nwritten, ) == 0) { const err = std.os.windows.kernel32.GetLastError(); - log.warn("hcs: writing to process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); + log.warn("writing to process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); } if (nwritten != code.len) { - log.warn("hcs: writing to process memory InputOutput error: written != requested: {x} != {x}", .{ nwritten, code.len }); + log.warn("writing to process memory InputOutput error: written != requested: {x} != {x}", .{ nwritten, code.len }); } } @@ -973,15 +971,15 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { } pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { - log.warn("hcs: attaching to process with handle {*}", .{handle}); + log.debug("attaching to process with handle {*}", .{handle}); self.hot_state.loaded_base_address = getProcessBaseAddress(handle) catch |err| { - log.warn("hcs: failed to get base address for the process with error: {s}", .{@errorName(err)}); + log.warn("failed to get base address for the process with error: {s}", .{@errorName(err)}); return; }; } pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void { - log.warn("hcs: detaching from process with handle {*}", .{handle}); + log.debug("detaching from process with handle {*}", .{handle}); self.hot_state.loaded_base_address = null; } diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 37bd3e292f..d778206e60 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -92,7 +92,7 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: const ctx: Context = .{ .source_vaddr = source_vaddr, .target_vaddr = target_vaddr_with_addend, - .image_base = coff_file.getImageBase(), + .image_base = coff_file.hot_state.loaded_base_address orelse coff_file.getImageBase(), .code = code, .ptr_width = coff_file.ptr_width, }; From 423b9f11144cc7f7f027db9a091174e9c752c511 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 17:04:50 +0200 Subject: [PATCH 154/216] coff: reimplement Read/WriteProcessMemory using our own ntdll wrappers --- src/link/Coff.zig | 117 +++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 8337d69088..2dd29d8022 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -793,28 +793,60 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { log.debug("page not mapped for write access; re-mapping...", .{}); try writeMemProtected(handle, vaddr, code); } else { - try writeMem(handle, vaddr, code); + if (WriteProcessMemory(handle, vaddr, code)) |amt| { + if (amt != code.len) return error.InputOutput; + } else |err| { + log.warn("writing to process memory failed with error: {s}", .{@errorName(err)}); + } } } try self.base.file.?.pwriteAll(code, file_offset); } -extern "kernel32" fn ReadProcessMemory( - hProcess: std.os.windows.HANDLE, - lpBaseAddress: std.os.windows.LPCVOID, - lpBuffer: std.os.windows.LPVOID, - nSize: std.os.windows.SIZE_T, - lpNumberOfBytesRead: *std.os.windows.SIZE_T, -) std.os.windows.BOOL; +extern "ntdll" fn NtReadVirtualMemory( + ProcessHandle: std.os.windows.HANDLE, + BaseAddress: std.os.windows.PVOID, + Buffer: std.os.windows.LPVOID, + NumberOfBytesToRead: std.os.windows.SIZE_T, + NumberOfBytesRead: ?*std.os.windows.SIZE_T, +) std.os.windows.NTSTATUS; -extern "kernel32" fn WriteProcessMemory( - hProcess: std.os.windows.HANDLE, - lpBaseAddress: std.os.windows.LPVOID, - lpBuffer: std.os.windows.LPCVOID, - nSize: std.os.windows.SIZE_T, - lpNumberOfBytesWritten: *std.os.windows.SIZE_T, -) std.os.windows.BOOL; +extern "ntdll" fn NtWriteVirtualMemory( + ProcessHandle: std.os.windows.HANDLE, + BaseAddress: std.os.windows.PVOID, + Buffer: std.os.windows.LPCVOID, + NumberOfBytesToWrite: std.os.windows.SIZE_T, + NumberOfBytesWritten: ?*std.os.windows.SIZE_T, +) std.os.windows.NTSTATUS; + +fn ReadProcessMemory(handle: std.os.windows.HANDLE, base_addr: usize, buffer: []u8) ![]u8 { + var nread: usize = 0; + switch (NtReadVirtualMemory( + handle, + @intToPtr(*anyopaque, base_addr), + buffer.ptr, + buffer.len, + &nread, + )) { + .SUCCESS => return buffer[0..nread], + else => |rc| return std.os.windows.unexpectedStatus(rc), + } +} + +fn WriteProcessMemory(handle: std.os.windows.HANDLE, base_addr: usize, buffer: []const u8) !usize { + var nwritten: usize = 0; + switch (NtWriteVirtualMemory( + handle, + @intToPtr(*anyopaque, base_addr), + @ptrCast(*const anyopaque, buffer.ptr), + buffer.len, + &nwritten, + )) { + .SUCCESS => return nwritten, + else => |rc| return std.os.windows.unexpectedStatus(rc), + } +} extern "kernel32" fn VirtualProtectEx( hProcess: std.os.windows.HANDLE, @@ -849,43 +881,16 @@ fn getProcessBaseAddress(handle: std.ChildProcess.Id) !u64 { } var peb_buf: [@sizeOf(std.os.windows.PEB)]u8 align(@alignOf(std.os.windows.PEB)) = undefined; - var peb_nread: usize = 0; - if (ReadProcessMemory( - handle, - info.PebBaseAddress, - &peb_buf, - @sizeOf(std.os.windows.PEB), - &peb_nread, - ) == 0) { - const err = std.os.windows.kernel32.GetLastError(); - log.warn("reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); - return error.FailedToReadPebForProcess; - } - if (peb_nread != @sizeOf(std.os.windows.PEB)) return error.InputOutput; - - const peb = @ptrCast(*const std.os.windows.PEB, &peb_buf); + const pebout = try ReadProcessMemory(handle, @ptrToInt(info.PebBaseAddress), &peb_buf); + const peb = @ptrCast(*const std.os.windows.PEB, @alignCast(@alignOf(std.os.windows.PEB), pebout.ptr)); return @ptrToInt(peb.ImageBaseAddress); } fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { var buffer = try allocator.alloc(u8, code.len); defer allocator.free(buffer); - var nread: usize = 0; - if (ReadProcessMemory( - handle, - @intToPtr(*anyopaque, vaddr), - buffer.ptr, - code.len, - &nread, - ) == 0) { - const err = std.os.windows.kernel32.GetLastError(); - log.warn("reading from process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); - } - if (nread != code.len) { - log.warn("reading from process memory InputOutput error: read != requested: {x} != {x}", .{ nread, code.len }); - } - - log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(buffer)}); + const memread = try ReadProcessMemory(handle, vaddr, buffer); + log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(memread)}); log.debug("to write: {x}", .{std.fmt.fmtSliceHexLower(code)}); } @@ -898,7 +903,8 @@ fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) log.warn("making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); return; } - try writeMem(handle, vaddr, code); + const amt = try WriteProcessMemory(handle, vaddr, code); + if (amt != code.len) return error.InputOutput; // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes. // For that though, we want to track which page has already been modified. if (VirtualProtectEx(handle, pvaddr, code.len, old_prot, &new_prot) == 0) { @@ -907,23 +913,6 @@ fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) } } -fn writeMem(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { - var nwritten: usize = 0; - if (WriteProcessMemory( - handle, - @intToPtr(*anyopaque, vaddr), - code.ptr, - code.len, - &nwritten, - ) == 0) { - const err = std.os.windows.kernel32.GetLastError(); - log.warn("writing to process memory failed with err: {s}({x})", .{ @tagName(err), @enumToInt(err) }); - } - if (nwritten != code.len) { - log.warn("writing to process memory InputOutput error: written != requested: {x} != {x}", .{ nwritten, code.len }); - } -} - fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { switch (self.ptr_width) { .p32 => { From 5d387742fd0f9e5c2072a2a527ccbf22044d4513 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 17:18:34 +0200 Subject: [PATCH 155/216] coff: reimplement VirtualProtectEx using our own ntdll wrapper --- lib/std/os/windows/ntdll.zig | 2 +- src/link/Coff.zig | 44 ++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 429b36039e..8c31a6fcc9 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -367,7 +367,7 @@ pub extern "ntdll" fn RtlQueryRegistryValues( pub extern "ntdll" fn NtProtectVirtualMemory( ProcessHandle: HANDLE, BaseAddress: *PVOID, - NumberOfBytesToProtect: *ULONG, + NumberOfBytesToProtect: *SIZE_T, NewAccessProtection: ULONG, OldAccessProtection: *ULONG, ) callconv(WINAPI) NTSTATUS; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 2dd29d8022..97a862dfd8 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -820,6 +820,14 @@ extern "ntdll" fn NtWriteVirtualMemory( NumberOfBytesWritten: ?*std.os.windows.SIZE_T, ) std.os.windows.NTSTATUS; +extern "ntdll" fn NtProtectVirtualMemory( + ProcessHandle: std.os.windows.HANDLE, + BaseAddress: *std.os.windows.PVOID, + NumberOfBytesToProtect: *std.os.windows.SIZE_T, + NewAccessProtection: std.os.windows.ULONG, + OldAccessProtection: *std.os.windows.ULONG, +) std.os.windows.NTSTATUS; + fn ReadProcessMemory(handle: std.os.windows.HANDLE, base_addr: usize, buffer: []u8) ![]u8 { var nread: usize = 0; switch (NtReadVirtualMemory( @@ -848,13 +856,21 @@ fn WriteProcessMemory(handle: std.os.windows.HANDLE, base_addr: usize, buffer: [ } } -extern "kernel32" fn VirtualProtectEx( - hProcess: std.os.windows.HANDLE, - lpAddress: std.os.windows.LPVOID, - dwSize: std.os.windows.SIZE_T, - flNewProtect: std.os.windows.DWORD, - lpflOldProtect: *std.os.windows.DWORD, -) std.os.windows.BOOL; +fn VirtualProtectEx(handle: std.os.windows.HANDLE, base_addr: usize, size: usize, new_prot: u32) !u32 { + var out_paddr = @intToPtr(*anyopaque, base_addr); + var out_size = size; + var old_prot: u32 = undefined; + switch (NtProtectVirtualMemory( + handle, + &out_paddr, + &out_size, + new_prot, + &old_prot, + )) { + .SUCCESS => return old_prot, + else => |rc| return std.os.windows.unexpectedStatus(rc), + } +} const PROCESS_BASIC_INFORMATION = extern struct { ExitStatus: std.os.windows.NTSTATUS, @@ -895,22 +911,12 @@ fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, vaddr: u64, code: } fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { - const pvaddr = @intToPtr(*anyopaque, vaddr); - var new_prot: std.os.windows.DWORD = std.os.windows.PAGE_EXECUTE_WRITECOPY; - var old_prot: std.os.windows.DWORD = undefined; - if (VirtualProtectEx(handle, pvaddr, code.len, new_prot, &old_prot) == 0) { - const err = std.os.windows.kernel32.GetLastError(); - log.warn("making page(s) writeable failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); - return; - } + const old_prot = try VirtualProtectEx(handle, vaddr, code.len, std.os.windows.PAGE_EXECUTE_WRITECOPY); const amt = try WriteProcessMemory(handle, vaddr, code); if (amt != code.len) return error.InputOutput; // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes. // For that though, we want to track which page has already been modified. - if (VirtualProtectEx(handle, pvaddr, code.len, old_prot, &new_prot) == 0) { - const err = std.os.windows.kernel32.GetLastError(); - log.warn("restoring page(s) attributes failed with error: {s}({x})", .{ @tagName(err), @enumToInt(err) }); - } + _ = try VirtualProtectEx(handle, vaddr, code.len, old_prot); } fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { From ba5302c4f88d2942890a5838e53eb078d61da123 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 18:52:27 +0200 Subject: [PATCH 156/216] std: move ntdll wrappers to std.os.windows --- lib/std/os/windows.zig | 198 +++++++++++++++++++++++++++++++++++ lib/std/os/windows/ntdll.zig | 130 ++++------------------- 2 files changed, 220 insertions(+), 108 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index fe0a68a13a..97462f6505 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1514,6 +1514,23 @@ pub fn VirtualProtect(lpAddress: ?LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, l } } +pub fn VirtualProtectEx(handle: HANDLE, addr: ?LPVOID, size: usize, new_prot: DWORD, old_prot: ?*DWORD) VirtualProtectError!void { + var out_addr = addr; + var out_size = size; + switch (ntdll.NtProtectVirtualMemory( + handle, + &out_addr, + &out_size, + new_prot, + old_prot, + )) { + .SUCCESS => {}, + .INVALID_ADDRESS => return error.InvalidAddress, + // TODO: map errors + else => |rc| return std.os.windows.unexpectedStatus(rc), + } +} + pub const VirtualQueryError = error{Unexpected}; pub fn VirtualQuery(lpAddress: ?LPVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T) VirtualQueryError!SIZE_T { @@ -4457,3 +4474,184 @@ pub const MODULEENTRY32 = extern struct { szModule: [MAX_MODULE_NAME32 + 1]CHAR, szExePath: [MAX_PATH]CHAR, }; + +pub const THREADINFOCLASS = enum(c_int) { + ThreadBasicInformation, + ThreadTimes, + ThreadPriority, + ThreadBasePriority, + ThreadAffinityMask, + ThreadImpersonationToken, + ThreadDescriptorTableEntry, + ThreadEnableAlignmentFaultFixup, + ThreadEventPair_Reusable, + ThreadQuerySetWin32StartAddress, + ThreadZeroTlsCell, + ThreadPerformanceCount, + ThreadAmILastThread, + ThreadIdealProcessor, + ThreadPriorityBoost, + ThreadSetTlsArrayAddress, + ThreadIsIoPending, + // Windows 2000+ from here + ThreadHideFromDebugger, + // Windows XP+ from here + ThreadBreakOnTermination, + ThreadSwitchLegacyState, + ThreadIsTerminated, + // Windows Vista+ from here + ThreadLastSystemCall, + ThreadIoPriority, + ThreadCycleTime, + ThreadPagePriority, + ThreadActualBasePriority, + ThreadTebInformation, + ThreadCSwitchMon, + // Windows 7+ from here + ThreadCSwitchPmu, + ThreadWow64Context, + ThreadGroupInformation, + ThreadUmsInformation, + ThreadCounterProfiling, + ThreadIdealProcessorEx, + // Windows 8+ from here + ThreadCpuAccountingInformation, + // Windows 8.1+ from here + ThreadSuspendCount, + // Windows 10+ from here + ThreadHeterogeneousCpuPolicy, + ThreadContainerId, + ThreadNameInformation, + ThreadSelectedCpuSets, + ThreadSystemThreadInformation, + ThreadActualGroupAffinity, +}; + +pub const PROCESSINFOCLASS = enum(c_int) { + ProcessBasicInformation, + ProcessQuotaLimits, + ProcessIoCounters, + ProcessVmCounters, + ProcessTimes, + ProcessBasePriority, + ProcessRaisePriority, + ProcessDebugPort, + ProcessExceptionPort, + ProcessAccessToken, + ProcessLdtInformation, + ProcessLdtSize, + ProcessDefaultHardErrorMode, + ProcessIoPortHandlers, + ProcessPooledUsageAndLimits, + ProcessWorkingSetWatch, + ProcessUserModeIOPL, + ProcessEnableAlignmentFaultFixup, + ProcessPriorityClass, + ProcessWx86Information, + ProcessHandleCount, + ProcessAffinityMask, + ProcessPriorityBoost, + ProcessDeviceMap, + ProcessSessionInformation, + ProcessForegroundInformation, + ProcessWow64Information, + ProcessImageFileName, + ProcessLUIDDeviceMapsEnabled, + ProcessBreakOnTermination, + ProcessDebugObjectHandle, + ProcessDebugFlags, + ProcessHandleTracing, + ProcessIoPriority, + ProcessExecuteFlags, + ProcessTlsInformation, + ProcessCookie, + ProcessImageInformation, + ProcessCycleTime, + ProcessPagePriority, + ProcessInstrumentationCallback, + ProcessThreadStackAllocation, + ProcessWorkingSetWatchEx, + ProcessImageFileNameWin32, + ProcessImageFileMapping, + ProcessAffinityUpdateMode, + ProcessMemoryAllocationMode, + ProcessGroupInformation, + ProcessTokenVirtualizationEnabled, + ProcessConsoleHostProcess, + ProcessWindowInformation, + MaxProcessInfoClass, +}; + +pub const PROCESS_BASIC_INFORMATION = extern struct { + ExitStatus: NTSTATUS, + PebBaseAddress: *PEB, + AffinityMask: ULONG_PTR, + BasePriority: KPRIORITY, + UniqueProcessId: ULONG_PTR, + InheritedFromUniqueProcessId: ULONG_PTR, +}; + +pub const ReadMemoryError = error{ + Unexpected, +}; + +pub fn ReadProcessMemory(handle: HANDLE, addr: ?LPVOID, buffer: []u8) ReadMemoryError![]u8 { + var nread: usize = 0; + switch (ntdll.NtReadVirtualMemory( + handle, + addr, + buffer.ptr, + buffer.len, + &nread, + )) { + .SUCCESS => return buffer[0..nread], + // TODO: map errors + else => |rc| return unexpectedStatus(rc), + } +} + +pub const WriteMemoryError = error{ + Unexpected, +}; + +pub fn WriteProcessMemory(handle: HANDLE, addr: ?LPVOID, buffer: []const u8) WriteMemoryError!usize { + var nwritten: usize = 0; + switch (ntdll.NtWriteVirtualMemory( + handle, + addr, + @ptrCast(*const anyopaque, buffer.ptr), + buffer.len, + &nwritten, + )) { + .SUCCESS => return nwritten, + // TODO: map errors + else => |rc| return unexpectedStatus(rc), + } +} + +pub const ProcessBaseAddressError = GetProcessMemoryInfoError || ReadMemoryError; + +/// Returns the base address of the process loaded into memory. +pub fn ProcessBaseAddress(handle: HANDLE) ProcessBaseAddressError!HMODULE { + var info: PROCESS_BASIC_INFORMATION = undefined; + var nread: DWORD = 0; + const rc = ntdll.NtQueryInformationProcess( + handle, + .ProcessBasicInformation, + &info, + @sizeOf(PROCESS_BASIC_INFORMATION), + &nread, + ); + switch (rc) { + .SUCCESS => {}, + .ACCESS_DENIED => return error.AccessDenied, + .INVALID_HANDLE => return error.InvalidHandle, + .INVALID_PARAMETER => unreachable, + else => return unexpectedStatus(rc), + } + + var peb_buf: [@sizeOf(PEB)]u8 align(@alignOf(PEB)) = undefined; + const peb_out = try ReadProcessMemory(handle, info.PebBaseAddress, &peb_buf); + const ppeb = @ptrCast(*const PEB, @alignCast(@alignOf(PEB), peb_out.ptr)); + return ppeb.ImageBaseAddress; +} diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 8c31a6fcc9..6fb75ae321 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -31,61 +31,10 @@ const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE; const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION; const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS; const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE; - -pub const PROCESSINFOCLASS = enum(c_int) { - ProcessBasicInformation, - ProcessQuotaLimits, - ProcessIoCounters, - ProcessVmCounters, - ProcessTimes, - ProcessBasePriority, - ProcessRaisePriority, - ProcessDebugPort, - ProcessExceptionPort, - ProcessAccessToken, - ProcessLdtInformation, - ProcessLdtSize, - ProcessDefaultHardErrorMode, - ProcessIoPortHandlers, - ProcessPooledUsageAndLimits, - ProcessWorkingSetWatch, - ProcessUserModeIOPL, - ProcessEnableAlignmentFaultFixup, - ProcessPriorityClass, - ProcessWx86Information, - ProcessHandleCount, - ProcessAffinityMask, - ProcessPriorityBoost, - ProcessDeviceMap, - ProcessSessionInformation, - ProcessForegroundInformation, - ProcessWow64Information, - ProcessImageFileName, - ProcessLUIDDeviceMapsEnabled, - ProcessBreakOnTermination, - ProcessDebugObjectHandle, - ProcessDebugFlags, - ProcessHandleTracing, - ProcessIoPriority, - ProcessExecuteFlags, - ProcessTlsInformation, - ProcessCookie, - ProcessImageInformation, - ProcessCycleTime, - ProcessPagePriority, - ProcessInstrumentationCallback, - ProcessThreadStackAllocation, - ProcessWorkingSetWatchEx, - ProcessImageFileNameWin32, - ProcessImageFileMapping, - ProcessAffinityUpdateMode, - ProcessMemoryAllocationMode, - ProcessGroupInformation, - ProcessTokenVirtualizationEnabled, - ProcessConsoleHostProcess, - ProcessWindowInformation, - MaxProcessInfoClass, -}; +const THREADINFOCLASS = windows.THREADINFOCLASS; +const PROCESSINFOCLASS = windows.PROCESSINFOCLASS; +const LPVOID = windows.LPVOID; +const LPCVOID = windows.LPCVOID; pub extern "ntdll" fn NtQueryInformationProcess( ProcessHandle: HANDLE, @@ -95,57 +44,6 @@ pub extern "ntdll" fn NtQueryInformationProcess( ReturnLength: ?*ULONG, ) callconv(WINAPI) NTSTATUS; -pub const THREADINFOCLASS = enum(c_int) { - ThreadBasicInformation, - ThreadTimes, - ThreadPriority, - ThreadBasePriority, - ThreadAffinityMask, - ThreadImpersonationToken, - ThreadDescriptorTableEntry, - ThreadEnableAlignmentFaultFixup, - ThreadEventPair_Reusable, - ThreadQuerySetWin32StartAddress, - ThreadZeroTlsCell, - ThreadPerformanceCount, - ThreadAmILastThread, - ThreadIdealProcessor, - ThreadPriorityBoost, - ThreadSetTlsArrayAddress, - ThreadIsIoPending, - // Windows 2000+ from here - ThreadHideFromDebugger, - // Windows XP+ from here - ThreadBreakOnTermination, - ThreadSwitchLegacyState, - ThreadIsTerminated, - // Windows Vista+ from here - ThreadLastSystemCall, - ThreadIoPriority, - ThreadCycleTime, - ThreadPagePriority, - ThreadActualBasePriority, - ThreadTebInformation, - ThreadCSwitchMon, - // Windows 7+ from here - ThreadCSwitchPmu, - ThreadWow64Context, - ThreadGroupInformation, - ThreadUmsInformation, - ThreadCounterProfiling, - ThreadIdealProcessorEx, - // Windows 8+ from here - ThreadCpuAccountingInformation, - // Windows 8.1+ from here - ThreadSuspendCount, - // Windows 10+ from here - ThreadHeterogeneousCpuPolicy, - ThreadContainerId, - ThreadNameInformation, - ThreadSelectedCpuSets, - ThreadSystemThreadInformation, - ThreadActualGroupAffinity, -}; pub extern "ntdll" fn NtQueryInformationThread( ThreadHandle: HANDLE, ThreadInformationClass: THREADINFOCLASS, @@ -364,10 +262,26 @@ pub extern "ntdll" fn RtlQueryRegistryValues( Environment: ?*anyopaque, ) callconv(WINAPI) NTSTATUS; +pub extern "ntdll" fn NtReadVirtualMemory( + ProcessHandle: HANDLE, + BaseAddress: ?PVOID, + Buffer: LPVOID, + NumberOfBytesToRead: SIZE_T, + NumberOfBytesRead: ?*SIZE_T, +) callconv(WINAPI) NTSTATUS; + +pub extern "ntdll" fn NtWriteVirtualMemory( + ProcessHandle: HANDLE, + BaseAddress: ?PVOID, + Buffer: LPCVOID, + NumberOfBytesToWrite: SIZE_T, + NumberOfBytesWritten: ?*SIZE_T, +) callconv(WINAPI) NTSTATUS; + pub extern "ntdll" fn NtProtectVirtualMemory( ProcessHandle: HANDLE, - BaseAddress: *PVOID, + BaseAddress: *?PVOID, NumberOfBytesToProtect: *SIZE_T, NewAccessProtection: ULONG, - OldAccessProtection: *ULONG, + OldAccessProtection: ?*ULONG, ) callconv(WINAPI) NTSTATUS; From 216badef0bd90c6353bf32bd927e2c6d36b3ebf6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 18:52:56 +0200 Subject: [PATCH 157/216] coff: use std.os.windows wrappers; fix relocating in-file --- src/link/Coff.zig | 150 ++++++++--------------------------- src/link/Coff/Relocation.zig | 4 +- 2 files changed, 35 insertions(+), 119 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 97a862dfd8..87ad1085aa 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -93,7 +93,9 @@ base_relocs: BaseRelocationTable = .{}, hot_state: HotUpdateState = .{}, const HotUpdateState = struct { - loaded_base_address: ?u64 = null, + /// Base address at which the process (image) got loaded. + /// We need this info to correctly slide pointers when relocating. + loaded_base_address: ?std.os.windows.HMODULE = null, }; const Entry = struct { @@ -784,139 +786,53 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { file_offset, file_offset + code.len, }); - self.resolveRelocs(atom_index, code); if (self.base.child_pid) |handle| { - const vaddr = sym.value + (self.hot_state.loaded_base_address orelse self.getImageBase()); + const slide = @ptrToInt(self.hot_state.loaded_base_address.?); + + const mem_code = try self.base.allocator.dupe(u8, code); + defer self.base.allocator.free(mem_code); + self.resolveRelocs(atom_index, mem_code, slide); + + const vaddr = sym.value + slide; + const pvaddr = @intToPtr(*anyopaque, vaddr); log.debug("writing to memory at address {x}", .{vaddr}); if (section.header.flags.MEM_WRITE == 0) { log.debug("page not mapped for write access; re-mapping...", .{}); - try writeMemProtected(handle, vaddr, code); + writeMemProtected(handle, pvaddr, mem_code) catch |err| { + log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); + }; } else { - if (WriteProcessMemory(handle, vaddr, code)) |amt| { - if (amt != code.len) return error.InputOutput; - } else |err| { - log.warn("writing to process memory failed with error: {s}", .{@errorName(err)}); - } + writeMem(handle, pvaddr, mem_code) catch |err| { + log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); + }; } } + self.resolveRelocs(atom_index, code, self.getImageBase()); try self.base.file.?.pwriteAll(code, file_offset); } -extern "ntdll" fn NtReadVirtualMemory( - ProcessHandle: std.os.windows.HANDLE, - BaseAddress: std.os.windows.PVOID, - Buffer: std.os.windows.LPVOID, - NumberOfBytesToRead: std.os.windows.SIZE_T, - NumberOfBytesRead: ?*std.os.windows.SIZE_T, -) std.os.windows.NTSTATUS; - -extern "ntdll" fn NtWriteVirtualMemory( - ProcessHandle: std.os.windows.HANDLE, - BaseAddress: std.os.windows.PVOID, - Buffer: std.os.windows.LPCVOID, - NumberOfBytesToWrite: std.os.windows.SIZE_T, - NumberOfBytesWritten: ?*std.os.windows.SIZE_T, -) std.os.windows.NTSTATUS; - -extern "ntdll" fn NtProtectVirtualMemory( - ProcessHandle: std.os.windows.HANDLE, - BaseAddress: *std.os.windows.PVOID, - NumberOfBytesToProtect: *std.os.windows.SIZE_T, - NewAccessProtection: std.os.windows.ULONG, - OldAccessProtection: *std.os.windows.ULONG, -) std.os.windows.NTSTATUS; - -fn ReadProcessMemory(handle: std.os.windows.HANDLE, base_addr: usize, buffer: []u8) ![]u8 { - var nread: usize = 0; - switch (NtReadVirtualMemory( - handle, - @intToPtr(*anyopaque, base_addr), - buffer.ptr, - buffer.len, - &nread, - )) { - .SUCCESS => return buffer[0..nread], - else => |rc| return std.os.windows.unexpectedStatus(rc), - } -} - -fn WriteProcessMemory(handle: std.os.windows.HANDLE, base_addr: usize, buffer: []const u8) !usize { - var nwritten: usize = 0; - switch (NtWriteVirtualMemory( - handle, - @intToPtr(*anyopaque, base_addr), - @ptrCast(*const anyopaque, buffer.ptr), - buffer.len, - &nwritten, - )) { - .SUCCESS => return nwritten, - else => |rc| return std.os.windows.unexpectedStatus(rc), - } -} - -fn VirtualProtectEx(handle: std.os.windows.HANDLE, base_addr: usize, size: usize, new_prot: u32) !u32 { - var out_paddr = @intToPtr(*anyopaque, base_addr); - var out_size = size; - var old_prot: u32 = undefined; - switch (NtProtectVirtualMemory( - handle, - &out_paddr, - &out_size, - new_prot, - &old_prot, - )) { - .SUCCESS => return old_prot, - else => |rc| return std.os.windows.unexpectedStatus(rc), - } -} - -const PROCESS_BASIC_INFORMATION = extern struct { - ExitStatus: std.os.windows.NTSTATUS, - PebBaseAddress: *std.os.windows.PEB, - AffinityMask: std.os.windows.ULONG_PTR, - BasePriority: std.os.windows.KPRIORITY, - UniqueProcessId: std.os.windows.ULONG_PTR, - InheritedFromUniqueProcessId: std.os.windows.ULONG_PTR, -}; - -fn getProcessBaseAddress(handle: std.ChildProcess.Id) !u64 { - var info: PROCESS_BASIC_INFORMATION = undefined; - var nread: std.os.windows.DWORD = 0; - const rc = std.os.windows.ntdll.NtQueryInformationProcess( - handle, - .ProcessBasicInformation, - &info, - @sizeOf(PROCESS_BASIC_INFORMATION), - &nread, - ); - switch (rc) { - .SUCCESS => {}, - else => return std.os.windows.unexpectedStatus(rc), - } - - var peb_buf: [@sizeOf(std.os.windows.PEB)]u8 align(@alignOf(std.os.windows.PEB)) = undefined; - const pebout = try ReadProcessMemory(handle, @ptrToInt(info.PebBaseAddress), &peb_buf); - const peb = @ptrCast(*const std.os.windows.PEB, @alignCast(@alignOf(std.os.windows.PEB), pebout.ptr)); - return @ptrToInt(peb.ImageBaseAddress); -} - -fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { +fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void { var buffer = try allocator.alloc(u8, code.len); defer allocator.free(buffer); - const memread = try ReadProcessMemory(handle, vaddr, buffer); + const memread = try std.os.windows.ReadProcessMemory(handle, pvaddr, buffer); log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(memread)}); log.debug("to write: {x}", .{std.fmt.fmtSliceHexLower(code)}); } -fn writeMemProtected(handle: std.ChildProcess.Id, vaddr: u64, code: []const u8) !void { - const old_prot = try VirtualProtectEx(handle, vaddr, code.len, std.os.windows.PAGE_EXECUTE_WRITECOPY); - const amt = try WriteProcessMemory(handle, vaddr, code); - if (amt != code.len) return error.InputOutput; +fn writeMemProtected(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void { + var old_prot: std.os.windows.DWORD = undefined; + try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, std.os.windows.PAGE_EXECUTE_WRITECOPY, &old_prot); + try writeMem(handle, pvaddr, code); // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes. // For that though, we want to track which page has already been modified. - _ = try VirtualProtectEx(handle, vaddr, code.len, old_prot); + try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, old_prot, null); +} + +fn writeMem(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void { + const amt = try std.os.windows.WriteProcessMemory(handle, pvaddr, code); + if (amt != code.len) return error.InputOutput; } fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { @@ -952,14 +868,14 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { } } -fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { +fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8, image_base: u64) void { const relocs = self.relocs.getPtr(atom_index) orelse return; log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); for (relocs.items) |*reloc| { if (!reloc.dirty) continue; - if (reloc.resolve(atom_index, code, self)) { + if (reloc.resolve(atom_index, code, image_base, self)) { reloc.dirty = false; } } @@ -967,7 +883,7 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void { pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { log.debug("attaching to process with handle {*}", .{handle}); - self.hot_state.loaded_base_address = getProcessBaseAddress(handle) catch |err| { + self.hot_state.loaded_base_address = std.os.windows.ProcessBaseAddress(handle) catch |err| { log.warn("failed to get base address for the process with error: {s}", .{@errorName(err)}); return; }; diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index d778206e60..6b35de93f4 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -74,7 +74,7 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { /// Returns `false` if obtaining the target address has been deferred until `flushModule`. /// This can happen when trying to resolve address of an import table entry ahead of time. -pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) bool { +pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: u64, coff_file: *Coff) bool { const atom = coff_file.getAtom(atom_index); const source_sym = atom.getSymbol(coff_file); const source_vaddr = source_sym.value + self.offset; @@ -92,7 +92,7 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: const ctx: Context = .{ .source_vaddr = source_vaddr, .target_vaddr = target_vaddr_with_addend, - .image_base = coff_file.hot_state.loaded_base_address orelse coff_file.getImageBase(), + .image_base = image_base, .code = code, .ptr_width = coff_file.ptr_width, }; From 349349fa01f77fe3bf2b57dc821f889e2e869004 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 20:54:46 +0200 Subject: [PATCH 158/216] std: simplify VirtualProtectEx and fix ntdll signature --- lib/std/os/windows.zig | 7 ++++--- lib/std/os/windows/ntdll.zig | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 97462f6505..1e6f717bb2 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1514,7 +1514,8 @@ pub fn VirtualProtect(lpAddress: ?LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, l } } -pub fn VirtualProtectEx(handle: HANDLE, addr: ?LPVOID, size: usize, new_prot: DWORD, old_prot: ?*DWORD) VirtualProtectError!void { +pub fn VirtualProtectEx(handle: HANDLE, addr: ?LPVOID, size: SIZE_T, new_prot: DWORD) VirtualProtectError!DWORD { + var old_prot: DWORD = undefined; var out_addr = addr; var out_size = size; switch (ntdll.NtProtectVirtualMemory( @@ -1522,9 +1523,9 @@ pub fn VirtualProtectEx(handle: HANDLE, addr: ?LPVOID, size: usize, new_prot: DW &out_addr, &out_size, new_prot, - old_prot, + &old_prot, )) { - .SUCCESS => {}, + .SUCCESS => return old_prot, .INVALID_ADDRESS => return error.InvalidAddress, // TODO: map errors else => |rc| return std.os.windows.unexpectedStatus(rc), diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 6fb75ae321..a8af39aa4d 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -283,5 +283,5 @@ pub extern "ntdll" fn NtProtectVirtualMemory( BaseAddress: *?PVOID, NumberOfBytesToProtect: *SIZE_T, NewAccessProtection: ULONG, - OldAccessProtection: ?*ULONG, + OldAccessProtection: *ULONG, ) callconv(WINAPI) NTSTATUS; From ee0c4457657523e218c1e211c447d3e196575ddc Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 20:56:25 +0200 Subject: [PATCH 159/216] coff: due to ASLR we need to dupe the code for relocating In addition, we need to be careful not to mark the relocations as resolved prematurely as then we are risking malforming the binary as we need to resolve the relocs twice: once for in-memory writes, and once for in-file updates. --- src/link/Coff.zig | 59 ++++++++++++++++++++++++------------ src/link/Coff/Relocation.zig | 14 +++++---- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 87ad1085aa..a7ca47c151 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -781,24 +781,47 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { const sym = atom.getSymbol(self); const section = self.sections.get(@enumToInt(sym.section_number) - 1); const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address; + log.debug("writing atom for symbol {s} at file offset 0x{x} to 0x{x}", .{ atom.getName(self), file_offset, file_offset + code.len, }); + const gpa = self.base.allocator; + + // Gather relocs which can be resolved. + // We need to do this as we will be applying different slide values depending + // if we are running in hot-code swapping mode or not. + // TODO: how crazy would it be to try and apply the actual image base of the loaded + // process for the in-file values rather than the Windows defaults? + var relocs = std.ArrayList(*Relocation).init(gpa); + defer relocs.deinit(); + + if (self.relocs.getPtr(atom_index)) |rels| { + try relocs.ensureTotalCapacityPrecise(rels.items.len); + for (rels.items) |*reloc| { + if (reloc.isResolvable(self)) relocs.appendAssumeCapacity(reloc); + } + } + if (self.base.child_pid) |handle| { const slide = @ptrToInt(self.hot_state.loaded_base_address.?); - const mem_code = try self.base.allocator.dupe(u8, code); - defer self.base.allocator.free(mem_code); - self.resolveRelocs(atom_index, mem_code, slide); + const mem_code = try gpa.dupe(u8, code); + defer gpa.free(mem_code); + self.resolveRelocs(atom_index, relocs.items, mem_code, slide); const vaddr = sym.value + slide; const pvaddr = @intToPtr(*anyopaque, vaddr); + log.debug("writing to memory at address {x}", .{vaddr}); + + if (build_options.enable_logging) { + try debugMem(gpa, handle, pvaddr, mem_code); + } + if (section.header.flags.MEM_WRITE == 0) { - log.debug("page not mapped for write access; re-mapping...", .{}); writeMemProtected(handle, pvaddr, mem_code) catch |err| { log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); }; @@ -809,25 +832,29 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { } } - self.resolveRelocs(atom_index, code, self.getImageBase()); + self.resolveRelocs(atom_index, relocs.items, code, self.getImageBase()); try self.base.file.?.pwriteAll(code, file_offset); + + // Now we can mark the relocs as resolved. + while (relocs.popOrNull()) |reloc| { + reloc.dirty = false; + } } fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void { var buffer = try allocator.alloc(u8, code.len); defer allocator.free(buffer); const memread = try std.os.windows.ReadProcessMemory(handle, pvaddr, buffer); - log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(memread)}); log.debug("to write: {x}", .{std.fmt.fmtSliceHexLower(code)}); + log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(memread)}); } fn writeMemProtected(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void { - var old_prot: std.os.windows.DWORD = undefined; - try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, std.os.windows.PAGE_EXECUTE_WRITECOPY, &old_prot); + const old_prot = try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, std.os.windows.PAGE_EXECUTE_WRITECOPY); try writeMem(handle, pvaddr, code); // TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes. // For that though, we want to track which page has already been modified. - try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, old_prot, null); + _ = try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, old_prot); } fn writeMem(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void { @@ -868,16 +895,10 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { } } -fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8, image_base: u64) void { - const relocs = self.relocs.getPtr(atom_index) orelse return; - +fn resolveRelocs(self: *Coff, atom_index: Atom.Index, relocs: []*const Relocation, code: []u8, image_base: u64) void { log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); - - for (relocs.items) |*reloc| { - if (!reloc.dirty) continue; - if (reloc.resolve(atom_index, code, image_base, self)) { - reloc.dirty = false; - } + for (relocs) |reloc| { + reloc.resolve(atom_index, code, image_base, self); } } @@ -1488,7 +1509,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| { const needs_update = for (relocs.items) |reloc| { - if (reloc.dirty) break true; + if (reloc.isResolvable(self)) break true; } else false; if (!needs_update) continue; diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig index 6b35de93f4..2fafa0bbdc 100644 --- a/src/link/Coff/Relocation.zig +++ b/src/link/Coff/Relocation.zig @@ -72,14 +72,18 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 { } } -/// Returns `false` if obtaining the target address has been deferred until `flushModule`. -/// This can happen when trying to resolve address of an import table entry ahead of time. -pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: u64, coff_file: *Coff) bool { +/// Returns true if and only if the reloc is dirty AND the target address is available. +pub fn isResolvable(self: Relocation, coff_file: *Coff) bool { + _ = self.getTargetAddress(coff_file) orelse return false; + return self.dirty; +} + +pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: u64, coff_file: *Coff) void { const atom = coff_file.getAtom(atom_index); const source_sym = atom.getSymbol(coff_file); const source_vaddr = source_sym.value + self.offset; - const target_vaddr = self.getTargetAddress(coff_file) orelse return false; + const target_vaddr = self.getTargetAddress(coff_file).?; // Oops, you didn't check if the relocation can be resolved with isResolvable(). const target_vaddr_with_addend = target_vaddr + self.addend; log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) ", .{ @@ -102,8 +106,6 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: .x86, .x86_64 => self.resolveX86(ctx), else => unreachable, // unhandled target architecture } - - return true; } const Context = struct { From 908ccce064a898d5db1d43dbdc4a3590fd84d4ba Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 30 Mar 2023 21:24:49 +0200 Subject: [PATCH 160/216] coff: enable hot-code swapping on a compatible host only --- src/link/Coff.zig | 51 ++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index a7ca47c151..f3068f01a9 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -90,7 +90,12 @@ relocs: RelocTable = .{}, base_relocs: BaseRelocationTable = .{}, /// Hot-code swapping state. -hot_state: HotUpdateState = .{}, +hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, + +const is_hot_update_compatible = switch (builtin.target.os.tag) { + .windows => true, + else => false, +}; const HotUpdateState = struct { /// Base address at which the process (image) got loaded. @@ -805,30 +810,32 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { } } - if (self.base.child_pid) |handle| { - const slide = @ptrToInt(self.hot_state.loaded_base_address.?); + if (is_hot_update_compatible) { + if (self.base.child_pid) |handle| { + const slide = @ptrToInt(self.hot_state.loaded_base_address.?); - const mem_code = try gpa.dupe(u8, code); - defer gpa.free(mem_code); - self.resolveRelocs(atom_index, relocs.items, mem_code, slide); + const mem_code = try gpa.dupe(u8, code); + defer gpa.free(mem_code); + self.resolveRelocs(atom_index, relocs.items, mem_code, slide); - const vaddr = sym.value + slide; - const pvaddr = @intToPtr(*anyopaque, vaddr); + const vaddr = sym.value + slide; + const pvaddr = @intToPtr(*anyopaque, vaddr); - log.debug("writing to memory at address {x}", .{vaddr}); + log.debug("writing to memory at address {x}", .{vaddr}); - if (build_options.enable_logging) { - try debugMem(gpa, handle, pvaddr, mem_code); - } + if (build_options.enable_logging) { + try debugMem(gpa, handle, pvaddr, mem_code); + } - if (section.header.flags.MEM_WRITE == 0) { - writeMemProtected(handle, pvaddr, mem_code) catch |err| { - log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); - }; - } else { - writeMem(handle, pvaddr, mem_code) catch |err| { - log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); - }; + if (section.header.flags.MEM_WRITE == 0) { + writeMemProtected(handle, pvaddr, mem_code) catch |err| { + log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); + }; + } else { + writeMem(handle, pvaddr, mem_code) catch |err| { + log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); + }; + } } } @@ -903,6 +910,8 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, relocs: []*const Relocatio } pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { + if (!is_hot_update_compatible) return; + log.debug("attaching to process with handle {*}", .{handle}); self.hot_state.loaded_base_address = std.os.windows.ProcessBaseAddress(handle) catch |err| { log.warn("failed to get base address for the process with error: {s}", .{@errorName(err)}); @@ -911,6 +920,8 @@ pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void { } pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void { + if (!is_hot_update_compatible) return; + log.debug("detaching from process with handle {*}", .{handle}); self.hot_state.loaded_base_address = null; } From c964e10821c417ceb7d0efcf1625d67484e734f7 Mon Sep 17 00:00:00 2001 From: jagt Date: Sun, 12 Mar 2023 18:45:53 +0800 Subject: [PATCH 161/216] docgen: add `additional_option` token; fix wasm-freestanding example - Fix usage string `--skip-code-test` to `--skip-code-tests`. - Added a token `{#additonal_option|-rdynamic#}` which introduce arbitrary flag to `build-exe/obj/lib` example. - Fix wasm freestanding example, it now needs explicit export symbols to work. --- doc/docgen.zig | 24 ++++++++++++++++++++++-- doc/langref.html.in | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/doc/docgen.zig b/doc/docgen.zig index 277316dd37..0f5967c3ce 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -18,13 +18,13 @@ const tmp_dir_name = "docgen_tmp"; const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext; const usage = - \\Usage: docgen [--zig] [--skip-code-test] input output" + \\Usage: docgen [--zig] [--skip-code-tests] input output" \\ \\ Generates an HTML document from a docgen template. \\ \\Options: \\ -h, --help Print this help and exit - \\ --skip-code-test Skip the doctests + \\ --skip-code-tests Skip the doctests \\ ; @@ -329,6 +329,7 @@ const Code = struct { link_mode: ?std.builtin.LinkMode, disable_cache: bool, verbose_cimport: bool, + additional_options: []const []const u8, const Id = union(enum) { Test, @@ -596,6 +597,8 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { var disable_cache = false; var verbose_cimport = false; var backend_stage1 = false; + var additional_options = std.ArrayList([]const u8).init(allocator); + defer additional_options.deinit(); const source_token = while (true) { const content_tok = try eatToken(tokenizer, Token.Id.Content); @@ -630,6 +633,10 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { link_mode = .Dynamic; } else if (mem.eql(u8, end_tag_name, "backend_stage1")) { backend_stage1 = true; + } else if (mem.eql(u8, end_tag_name, "additonal_option")) { + _ = try eatToken(tokenizer, Token.Id.Separator); + const option = try eatToken(tokenizer, Token.Id.TagContent); + try additional_options.append(tokenizer.buffer[option.start..option.end]); } else if (mem.eql(u8, end_tag_name, "code_end")) { _ = try eatToken(tokenizer, Token.Id.BracketClose); break content_tok; @@ -657,6 +664,7 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { .link_mode = link_mode, .disable_cache = disable_cache, .verbose_cimport = verbose_cimport, + .additional_options = try additional_options.toOwnedSlice(), }, }); tokenizer.code_node_count += 1; @@ -1418,6 +1426,10 @@ fn genHtml( try build_args.append("--verbose-cimport"); try shell_out.print("--verbose-cimport ", .{}); } + for (code.additional_options) |option| { + try build_args.append(option); + try shell_out.print("{s} ", .{option}); + } try shell_out.print("\n", .{}); @@ -1729,6 +1741,10 @@ fn genHtml( try build_args.appendSlice(&[_][]const u8{ "-target", triple }); try shell_out.print("-target {s} ", .{triple}); } + for (code.additional_options) |option| { + try build_args.append(option); + try shell_out.print("{s} ", .{option}); + } if (maybe_error_match) |error_match| { const result = try ChildProcess.exec(.{ @@ -1811,6 +1827,10 @@ fn genHtml( }, } } + for (code.additional_options) |option| { + try test_args.append(option); + try shell_out.print("{s} ", .{option}); + } const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{}); const escaped_stderr = try escapeHtml(allocator, result.stderr); const escaped_stdout = try escapeHtml(allocator, result.stdout); diff --git a/doc/langref.html.in b/doc/langref.html.in index 19ee6cdab2..38e1d674fa 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -11149,6 +11149,7 @@ all your base are belong to us{#end_shell_samp#} {#code_begin|lib|math#} {#target_wasm#} {#link_mode_dynamic#} + {#additonal_option|-rdynamic#} extern fn print(i32) void; export fn add(a: i32, b: i32) void { From 652b005f9bf1836ac507d9ef58cf4b4319557ad8 Mon Sep 17 00:00:00 2001 From: Krzysztof Wolicki Date: Thu, 30 Mar 2023 22:03:58 +0200 Subject: [PATCH 162/216] autodoc: fix Extended builtin functions names rendering --- src/Autodoc.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 15d90b104b..b4d704ded3 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -2984,7 +2984,7 @@ fn walkInstruction( const param_index = self.exprs.items.len; try self.exprs.append(self.arena, param.expr); - self.exprs.items[bin_index] = .{ .builtin = .{ .name = @tagName(tags[inst_index]), .param = param_index } }; + self.exprs.items[bin_index] = .{ .builtin = .{ .name = @tagName(extended.opcode), .param = param_index } }; return DocData.WalkResult{ .typeRef = param.typeRef orelse .{ .type = @enumToInt(Ref.type_type) }, From b69578e19c85e65dbfdf92908416182abf2bede7 Mon Sep 17 00:00:00 2001 From: Krzysztof Wolicki Date: Thu, 30 Mar 2023 22:05:22 +0200 Subject: [PATCH 163/216] autodoc: add new builtins --- lib/docs/main.js | 12 ++++++++++++ src/Autodoc.zig | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/lib/docs/main.js b/lib/docs/main.js index fc99b2f861..280bdbde73 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1267,6 +1267,18 @@ const NAV_MODES = { payloadHtml += "frameSize"; break; } + case "work_item_id": { + payloadHtml += "workItemId"; + break; + } + case "work_group_size": { + payloadHtml += "workGroupSize"; + break; + } + case "work_group_id": { + payloadHtml += "workGroupId"; + break; + } case "ptr_to_int": { payloadHtml += "ptrToInt"; break; diff --git a/src/Autodoc.zig b/src/Autodoc.zig index b4d704ded3..3a684a73b2 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -2991,6 +2991,26 @@ fn walkInstruction( .expr = .{ .builtinIndex = bin_index }, }; }, + .work_item_id, + .work_group_size, + .work_group_id, + => { + const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data; + const bin_index = self.exprs.items.len; + try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } }); + const param = try self.walkRef(file, parent_scope, parent_src, extra.operand, false); + + const param_index = self.exprs.items.len; + try self.exprs.append(self.arena, param.expr); + + self.exprs.items[bin_index] = .{ .builtin = .{ .name = @tagName(extended.opcode), .param = param_index } }; + + return DocData.WalkResult{ + // from docs we know they return u32 + .typeRef = .{ .type = @enumToInt(Ref.u32_type) }, + .expr = .{ .builtinIndex = bin_index }, + }; + }, .cmpxchg => { const extra = file.zir.extraData(Zir.Inst.Cmpxchg, extended.operand).data; From 23cf44c227678bde07b872e2a5ff1089c028c582 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 10:10:18 +0200 Subject: [PATCH 164/216] libc: add missing sys/timex.h to macOS libc headers --- lib/libc/include/any-macos-any/sys/timex.h | 198 +++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 lib/libc/include/any-macos-any/sys/timex.h diff --git a/lib/libc/include/any-macos-any/sys/timex.h b/lib/libc/include/any-macos-any/sys/timex.h new file mode 100644 index 0000000000..dbfddaa1a3 --- /dev/null +++ b/lib/libc/include/any-macos-any/sys/timex.h @@ -0,0 +1,198 @@ +/*- + *********************************************************************** + * * + * Copyright (c) David L. Mills 1993-2001 * + * Copyright (c) Poul-Henning Kamp 2000-2001 * + * * + * Permission to use, copy, modify, and distribute this software and * + * its documentation for any purpose and without fee is hereby * + * granted, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission * + * notice appear in supporting documentation, and that the name * + * University of Delaware not be used in advertising or publicity * + * pertaining to distribution of the software without specific, * + * written prior permission. The University of Delaware makes no * + * representations about the suitability this software for any * + * purpose. It is provided "as is" without express or implied * + * warranty. * + * * + *********************************************************************** + * + * $FreeBSD$ + * + * This header file defines the Network Time Protocol (NTP) interfaces + * for user and daemon application programs. + * + * This file was originally created 17 Sep 93 by David L. Mills, Professor + * of University of Delaware, building on work which had already been ongoing + * for a decade and a half at that point in time. + * + * In 2000 the APIs got a upgrade from microseconds to nanoseconds, + * a joint work between Poul-Henning Kamp and David L. Mills. + * + */ + +/* + * Copyright (c) 2017 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_TIMEX_H_ +#define _SYS_TIMEX_H_ 1 + +#include + +#define NTP_API 4 /* NTP API version */ + +/* + * The following defines establish the performance envelope of the + * kernel discipline loop. Phase or frequency errors greater than + * NAXPHASE or MAXFREQ are clamped to these maxima. For update intervals + * less than MINSEC, the loop always operates in PLL mode; while, for + * update intervals greater than MAXSEC, the loop always operates in FLL + * mode. Between these two limits the operating mode is selected by the + * STA_FLL bit in the status word. + */ + +#define MAXPHASE 500000000L /* max phase error (ns) */ +#define MAXFREQ 500000L /* max freq error (ns/s) */ +#define MINSEC 256 /* min FLL update interval (s) */ +#define MAXSEC 2048 /* max PLL update interval (s) */ +#define NANOSECOND 1000000000L /* nanoseconds in one second */ +#define SCALE_PPM (65536 / 1000) /* crude ns/s to scaled PPM */ +#define MAXTC 10 /* max time constant */ + +/* Codes for PPS (pulse-per-second) signals or leap seconds are not used but kept + * unchanged and commented for future compatibility. + */ + +/* + * Control mode codes (timex.modes) + */ +#define MOD_OFFSET 0x0001 /* set time offset */ +#define MOD_FREQUENCY 0x0002 /* set frequency offset */ +#define MOD_MAXERROR 0x0004 /* set maximum time error */ +#define MOD_ESTERROR 0x0008 /* set estimated time error */ +#define MOD_STATUS 0x0010 /* set clock status bits */ +#define MOD_TIMECONST 0x0020 /* set PLL time constant */ +#define MOD_PPSMAX 0x0040 /* set PPS maximum averaging time */ +#define MOD_TAI 0x0080 /* set TAI offset */ +#define MOD_MICRO 0x1000 /* select microsecond resolution */ +#define MOD_NANO 0x2000 /* select nanosecond resolution */ +#define MOD_CLKB 0x4000 /* select clock B */ +#define MOD_CLKA 0x8000 /* select clock A */ + +/* + * Status codes (timex.status) + */ +#define STA_PLL 0x0001 /* enable PLL updates (rw) */ +#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */ +#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */ +#define STA_FLL 0x0008 /* enable FLL mode (rw) */ +#define STA_INS 0x0010 /* insert leap (rw) */ +#define STA_DEL 0x0020 /* delete leap (rw) */ +#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */ +#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */ +#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */ +#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */ +#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */ +#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */ +#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */ +#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */ +#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */ +#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */ + +#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \ + STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) + +#define STA_SUPPORTED (STA_PLL | STA_FLL | STA_UNSYNC | STA_FREQHOLD | \ + STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) + +/* + * Clock states (ntptimeval.time_state) + */ +#define TIME_OK 0 /* no leap second warning */ +#define TIME_INS 1 /* insert leap second warning */ +#define TIME_DEL 2 /* delete leap second warning */ +#define TIME_OOP 3 /* leap second in progress */ +#define TIME_WAIT 4 /* leap second has occurred */ +#define TIME_ERROR 5 /* error (see status word) */ + +/* + * NTP user interface -- ntp_gettime - used to read kernel clock values + */ +struct ntptimeval { + struct timespec time; /* current time (ns) (ro) */ + long maxerror; /* maximum error (us) (ro) */ + long esterror; /* estimated error (us) (ro) */ + long tai; /* TAI offset */ + int time_state; /* time status */ +}; + +/* + * NTP daemon interface -- ntp_adjtime -- used to discipline CPU clock + * oscillator and control/determine status. + * + * Note: The offset, precision and jitter members are in microseconds if + * STA_NANO is zero and nanoseconds if not. + */ +struct timex { + unsigned int modes; /* clock mode bits (wo) */ + long offset; /* time offset (ns/us) (rw) */ + long freq; /* frequency offset (scaled PPM) (rw) */ + long maxerror; /* maximum error (us) (rw) */ + long esterror; /* estimated error (us) (rw) */ + int status; /* clock status bits (rw) */ + long constant; /* poll interval (log2 s) (rw) */ + long precision; /* clock precision (ns/us) (ro) */ + long tolerance; /* clock frequency tolerance (scaled + * PPM) (ro) */ + /* + * The following read-only structure members are used by + * the PPS signal discipline that is currently not supported. + * They are included for compatibility. + */ + long ppsfreq; /* PPS frequency (scaled PPM) (ro) */ + long jitter; /* PPS jitter (ns/us) (ro) */ + int shift; /* interval duration (s) (shift) (ro) */ + long stabil; /* PPS stability (scaled PPM) (ro) */ + long jitcnt; /* jitter limit exceeded (ro) */ + long calcnt; /* calibration intervals (ro) */ + long errcnt; /* calibration errors (ro) */ + long stbcnt; /* stability limit exceeded (ro) */ +}; + +#include + +__BEGIN_DECLS +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +int ntp_adjtime(struct timex *); +int ntp_gettime(struct ntptimeval *); +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +__END_DECLS + + +#endif /* !_SYS_TIMEX_H_ */ \ No newline at end of file From 26c88e4f4580db1278e5e35914512b40bed345a8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 21:20:41 +0200 Subject: [PATCH 165/216] libc: update macOS libc headers to latest SDK 13.3 --- .../mach/arm/thread_status.h | 5 + lib/libc/include/any-macos-any/sys/timex.h | 198 +++ .../libkern/OSKextLib.h | 0 .../sys/attr.h | 0 .../unistd.h | 0 .../xpc/availability.h | 0 .../any-macos.13-any/AvailabilityInternal.h | 10 +- .../any-macos.13-any/AvailabilityMacros.h | 5 +- .../any-macos.13-any/AvailabilityVersions.h | 8 + lib/libc/include/any-macos.13-any/Block.h | 9 +- .../any-macos.13-any/libkern/OSKextLib.h | 572 +++++++ .../any-macos.13-any/mach-o/arm64/reloc.h | 254 +++ .../mach-o/compact_unwind_encoding.h | 532 +++++++ .../include/any-macos.13-any/mach-o/fat.h | 11 +- .../include/any-macos.13-any/mach/mach_host.h | 4 +- .../any-macos.13-any/mach/mach_types.h | 8 +- lib/libc/include/any-macos.13-any/mach/port.h | 1 + .../any-macos.13-any/mach/vm_statistics.h | 5 +- .../include/any-macos.13-any/mach/vm_types.h | 2 +- .../include/any-macos.13-any/net/if_var.h | 1 + .../include/any-macos.13-any/objc/NSObject.h | 115 ++ .../include/any-macos.13-any/objc/runtime.h | 22 +- lib/libc/include/any-macos.13-any/simd/simd.h | 30 + .../any-macos.13-any/sys/_symbol_aliasing.h | 24 + lib/libc/include/any-macos.13-any/sys/attr.h | 594 +++++++ lib/libc/include/any-macos.13-any/sys/mman.h | 265 ++++ lib/libc/include/any-macos.13-any/sys/mount.h | 19 +- lib/libc/include/any-macos.13-any/tgmath.h | 1381 +++++++++++++++++ lib/libc/include/any-macos.13-any/unistd.h | 791 ++++++++++ .../any-macos.13-any/xpc/availability.h | 134 ++ .../mach/i386/thread_status.h | 6 + 31 files changed, 4975 insertions(+), 31 deletions(-) create mode 100644 lib/libc/include/any-macos-any/sys/timex.h rename lib/libc/include/{any-macos-any => any-macos.12-any}/libkern/OSKextLib.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/sys/attr.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/unistd.h (100%) rename lib/libc/include/{any-macos-any => any-macos.12-any}/xpc/availability.h (100%) create mode 100644 lib/libc/include/any-macos.13-any/libkern/OSKextLib.h create mode 100644 lib/libc/include/any-macos.13-any/mach-o/arm64/reloc.h create mode 100644 lib/libc/include/any-macos.13-any/mach-o/compact_unwind_encoding.h create mode 100644 lib/libc/include/any-macos.13-any/objc/NSObject.h create mode 100644 lib/libc/include/any-macos.13-any/simd/simd.h create mode 100644 lib/libc/include/any-macos.13-any/sys/attr.h create mode 100644 lib/libc/include/any-macos.13-any/sys/mman.h create mode 100644 lib/libc/include/any-macos.13-any/tgmath.h create mode 100644 lib/libc/include/any-macos.13-any/unistd.h create mode 100644 lib/libc/include/any-macos.13-any/xpc/availability.h diff --git a/lib/libc/include/aarch64-macos.13-none/mach/arm/thread_status.h b/lib/libc/include/aarch64-macos.13-none/mach/arm/thread_status.h index f270b61fc6..3b6f9d0625 100644 --- a/lib/libc/include/aarch64-macos.13-none/mach/arm/thread_status.h +++ b/lib/libc/include/aarch64-macos.13-none/mach/arm/thread_status.h @@ -76,6 +76,11 @@ #define ARM_STATE_FLAVOR_IS_OTHER_VALID(_flavor_) 0 #endif +#define FLAVOR_MODIFIES_CORE_CPU_REGISTERS(x) \ +((x == ARM_THREAD_STATE) || \ + (x == ARM_THREAD_STATE32) || \ + (x == ARM_THREAD_STATE64)) + #define VALID_THREAD_STATE_FLAVOR(x) \ ((x == ARM_THREAD_STATE) || \ (x == ARM_VFP_STATE) || \ diff --git a/lib/libc/include/any-macos-any/sys/timex.h b/lib/libc/include/any-macos-any/sys/timex.h new file mode 100644 index 0000000000..dbfddaa1a3 --- /dev/null +++ b/lib/libc/include/any-macos-any/sys/timex.h @@ -0,0 +1,198 @@ +/*- + *********************************************************************** + * * + * Copyright (c) David L. Mills 1993-2001 * + * Copyright (c) Poul-Henning Kamp 2000-2001 * + * * + * Permission to use, copy, modify, and distribute this software and * + * its documentation for any purpose and without fee is hereby * + * granted, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission * + * notice appear in supporting documentation, and that the name * + * University of Delaware not be used in advertising or publicity * + * pertaining to distribution of the software without specific, * + * written prior permission. The University of Delaware makes no * + * representations about the suitability this software for any * + * purpose. It is provided "as is" without express or implied * + * warranty. * + * * + *********************************************************************** + * + * $FreeBSD$ + * + * This header file defines the Network Time Protocol (NTP) interfaces + * for user and daemon application programs. + * + * This file was originally created 17 Sep 93 by David L. Mills, Professor + * of University of Delaware, building on work which had already been ongoing + * for a decade and a half at that point in time. + * + * In 2000 the APIs got a upgrade from microseconds to nanoseconds, + * a joint work between Poul-Henning Kamp and David L. Mills. + * + */ + +/* + * Copyright (c) 2017 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_TIMEX_H_ +#define _SYS_TIMEX_H_ 1 + +#include + +#define NTP_API 4 /* NTP API version */ + +/* + * The following defines establish the performance envelope of the + * kernel discipline loop. Phase or frequency errors greater than + * NAXPHASE or MAXFREQ are clamped to these maxima. For update intervals + * less than MINSEC, the loop always operates in PLL mode; while, for + * update intervals greater than MAXSEC, the loop always operates in FLL + * mode. Between these two limits the operating mode is selected by the + * STA_FLL bit in the status word. + */ + +#define MAXPHASE 500000000L /* max phase error (ns) */ +#define MAXFREQ 500000L /* max freq error (ns/s) */ +#define MINSEC 256 /* min FLL update interval (s) */ +#define MAXSEC 2048 /* max PLL update interval (s) */ +#define NANOSECOND 1000000000L /* nanoseconds in one second */ +#define SCALE_PPM (65536 / 1000) /* crude ns/s to scaled PPM */ +#define MAXTC 10 /* max time constant */ + +/* Codes for PPS (pulse-per-second) signals or leap seconds are not used but kept + * unchanged and commented for future compatibility. + */ + +/* + * Control mode codes (timex.modes) + */ +#define MOD_OFFSET 0x0001 /* set time offset */ +#define MOD_FREQUENCY 0x0002 /* set frequency offset */ +#define MOD_MAXERROR 0x0004 /* set maximum time error */ +#define MOD_ESTERROR 0x0008 /* set estimated time error */ +#define MOD_STATUS 0x0010 /* set clock status bits */ +#define MOD_TIMECONST 0x0020 /* set PLL time constant */ +#define MOD_PPSMAX 0x0040 /* set PPS maximum averaging time */ +#define MOD_TAI 0x0080 /* set TAI offset */ +#define MOD_MICRO 0x1000 /* select microsecond resolution */ +#define MOD_NANO 0x2000 /* select nanosecond resolution */ +#define MOD_CLKB 0x4000 /* select clock B */ +#define MOD_CLKA 0x8000 /* select clock A */ + +/* + * Status codes (timex.status) + */ +#define STA_PLL 0x0001 /* enable PLL updates (rw) */ +#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */ +#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */ +#define STA_FLL 0x0008 /* enable FLL mode (rw) */ +#define STA_INS 0x0010 /* insert leap (rw) */ +#define STA_DEL 0x0020 /* delete leap (rw) */ +#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */ +#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */ +#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */ +#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */ +#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */ +#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */ +#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */ +#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */ +#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */ +#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */ + +#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \ + STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) + +#define STA_SUPPORTED (STA_PLL | STA_FLL | STA_UNSYNC | STA_FREQHOLD | \ + STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) + +/* + * Clock states (ntptimeval.time_state) + */ +#define TIME_OK 0 /* no leap second warning */ +#define TIME_INS 1 /* insert leap second warning */ +#define TIME_DEL 2 /* delete leap second warning */ +#define TIME_OOP 3 /* leap second in progress */ +#define TIME_WAIT 4 /* leap second has occurred */ +#define TIME_ERROR 5 /* error (see status word) */ + +/* + * NTP user interface -- ntp_gettime - used to read kernel clock values + */ +struct ntptimeval { + struct timespec time; /* current time (ns) (ro) */ + long maxerror; /* maximum error (us) (ro) */ + long esterror; /* estimated error (us) (ro) */ + long tai; /* TAI offset */ + int time_state; /* time status */ +}; + +/* + * NTP daemon interface -- ntp_adjtime -- used to discipline CPU clock + * oscillator and control/determine status. + * + * Note: The offset, precision and jitter members are in microseconds if + * STA_NANO is zero and nanoseconds if not. + */ +struct timex { + unsigned int modes; /* clock mode bits (wo) */ + long offset; /* time offset (ns/us) (rw) */ + long freq; /* frequency offset (scaled PPM) (rw) */ + long maxerror; /* maximum error (us) (rw) */ + long esterror; /* estimated error (us) (rw) */ + int status; /* clock status bits (rw) */ + long constant; /* poll interval (log2 s) (rw) */ + long precision; /* clock precision (ns/us) (ro) */ + long tolerance; /* clock frequency tolerance (scaled + * PPM) (ro) */ + /* + * The following read-only structure members are used by + * the PPS signal discipline that is currently not supported. + * They are included for compatibility. + */ + long ppsfreq; /* PPS frequency (scaled PPM) (ro) */ + long jitter; /* PPS jitter (ns/us) (ro) */ + int shift; /* interval duration (s) (shift) (ro) */ + long stabil; /* PPS stability (scaled PPM) (ro) */ + long jitcnt; /* jitter limit exceeded (ro) */ + long calcnt; /* calibration intervals (ro) */ + long errcnt; /* calibration errors (ro) */ + long stbcnt; /* stability limit exceeded (ro) */ +}; + +#include + +__BEGIN_DECLS +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +int ntp_adjtime(struct timex *); +int ntp_gettime(struct ntptimeval *); +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +__END_DECLS + + +#endif /* !_SYS_TIMEX_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos-any/libkern/OSKextLib.h b/lib/libc/include/any-macos.12-any/libkern/OSKextLib.h similarity index 100% rename from lib/libc/include/any-macos-any/libkern/OSKextLib.h rename to lib/libc/include/any-macos.12-any/libkern/OSKextLib.h diff --git a/lib/libc/include/any-macos-any/sys/attr.h b/lib/libc/include/any-macos.12-any/sys/attr.h similarity index 100% rename from lib/libc/include/any-macos-any/sys/attr.h rename to lib/libc/include/any-macos.12-any/sys/attr.h diff --git a/lib/libc/include/any-macos-any/unistd.h b/lib/libc/include/any-macos.12-any/unistd.h similarity index 100% rename from lib/libc/include/any-macos-any/unistd.h rename to lib/libc/include/any-macos.12-any/unistd.h diff --git a/lib/libc/include/any-macos-any/xpc/availability.h b/lib/libc/include/any-macos.12-any/xpc/availability.h similarity index 100% rename from lib/libc/include/any-macos-any/xpc/availability.h rename to lib/libc/include/any-macos.12-any/xpc/availability.h diff --git a/lib/libc/include/any-macos.13-any/AvailabilityInternal.h b/lib/libc/include/any-macos.13-any/AvailabilityInternal.h index 710f24cc92..854942b98c 100644 --- a/lib/libc/include/any-macos.13-any/AvailabilityInternal.h +++ b/lib/libc/include/any-macos.13-any/AvailabilityInternal.h @@ -55,7 +55,7 @@ #ifdef __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ /* compiler sets __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ when -mtvos-version-min is used */ #define __TV_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ - #define __TV_OS_VERSION_MAX_ALLOWED __TVOS_16_2 + #define __TV_OS_VERSION_MAX_ALLOWED __TVOS_16_4 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 90000 #endif @@ -65,7 +65,7 @@ #ifdef __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ /* compiler sets __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ when -mwatchos-version-min is used */ #define __WATCH_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ - #define __WATCH_OS_VERSION_MAX_ALLOWED __WATCHOS_9_2 + #define __WATCH_OS_VERSION_MAX_ALLOWED __WATCHOS_9_4 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 90000 #endif @@ -75,7 +75,7 @@ #ifdef __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ #define __BRIDGE_OS_VERSION_MIN_REQUIRED __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ - #define __BRIDGE_OS_VERSION_MAX_ALLOWED 70100 + #define __BRIDGE_OS_VERSION_MAX_ALLOWED 70300 /* for compatibility with existing code. New code should use platform specific checks */ #define __IPHONE_OS_VERSION_MIN_REQUIRED 110000 #endif @@ -90,14 +90,14 @@ #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED /* make sure a default max version is set */ #ifndef __MAC_OS_X_VERSION_MAX_ALLOWED - #define __MAC_OS_X_VERSION_MAX_ALLOWED __MAC_13_1 + #define __MAC_OS_X_VERSION_MAX_ALLOWED __MAC_13_3 #endif #endif /* __MAC_OS_X_VERSION_MIN_REQUIRED */ #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED /* make sure a default max version is set */ #ifndef __IPHONE_OS_VERSION_MAX_ALLOWED - #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_16_2 + #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_16_4 #endif /* make sure a valid min is set */ #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_2_0 diff --git a/lib/libc/include/any-macos.13-any/AvailabilityMacros.h b/lib/libc/include/any-macos.13-any/AvailabilityMacros.h index 313d37c4cc..e20afe5910 100644 --- a/lib/libc/include/any-macos.13-any/AvailabilityMacros.h +++ b/lib/libc/include/any-macos.13-any/AvailabilityMacros.h @@ -123,6 +123,7 @@ #define MAC_OS_VERSION_12_0 120000 #define MAC_OS_VERSION_13_0 130000 #define MAC_OS_VERSION_13_1 130100 +#define MAC_OS_VERSION_13_3 130300 /* * If min OS not specified, assume 10.4 for intel @@ -149,10 +150,10 @@ * if max OS not specified, assume larger of (10.15, min) */ #ifndef MAC_OS_X_VERSION_MAX_ALLOWED - #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_VERSION_13_1 + #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_VERSION_13_3 #define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_MIN_REQUIRED #else - #define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_VERSION_13_1 + #define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_VERSION_13_3 #endif #endif diff --git a/lib/libc/include/any-macos.13-any/AvailabilityVersions.h b/lib/libc/include/any-macos.13-any/AvailabilityVersions.h index e488b55232..1b36142fcb 100644 --- a/lib/libc/include/any-macos.13-any/AvailabilityVersions.h +++ b/lib/libc/include/any-macos.13-any/AvailabilityVersions.h @@ -69,6 +69,8 @@ #define __MAC_12_3 120300 #define __MAC_13_0 130000 #define __MAC_13_1 130100 +#define __MAC_13_2 130200 +#define __MAC_13_3 130300 /* __MAC_NA is not defined to a value but is used as a token by macros to indicate that the API is unavailable */ #define __IPHONE_2_0 20000 @@ -134,6 +136,8 @@ #define __IPHONE_16_0 160000 #define __IPHONE_16_1 160100 #define __IPHONE_16_2 160200 +#define __IPHONE_16_3 160300 +#define __IPHONE_16_4 160400 /* __IPHONE_NA is not defined to a value but is used as a token by macros to indicate that the API is unavailable */ #define __TVOS_9_0 90000 @@ -172,6 +176,8 @@ #define __TVOS_16_0 160000 #define __TVOS_16_1 160100 #define __TVOS_16_2 160200 +#define __TVOS_16_3 160300 +#define __TVOS_16_4 160400 #define __WATCHOS_1_0 10000 #define __WATCHOS_2_0 20000 @@ -207,6 +213,8 @@ #define __WATCHOS_9_0 90000 #define __WATCHOS_9_1 90100 #define __WATCHOS_9_2 90200 +#define __WATCHOS_9_3 90300 +#define __WATCHOS_9_4 90400 /* * Set up standard Mac OS X versions diff --git a/lib/libc/include/any-macos.13-any/Block.h b/lib/libc/include/any-macos.13-any/Block.h index e381a9585f..e0c8db9dd2 100644 --- a/lib/libc/include/any-macos.13-any/Block.h +++ b/lib/libc/include/any-macos.13-any/Block.h @@ -18,7 +18,12 @@ # endif #endif +#if __has_include() #include +#else +#define __OSX_AVAILABLE_STARTING(m,i) +#endif + #include #include @@ -58,8 +63,8 @@ BLOCK_EXPORT void * _NSConcreteStackBlock[32] // Type correct macros -#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) -#define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) +#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy(__unsafe_forge_single(const void *, (const void *)(__VA_ARGS__)))) +#define Block_release(...) _Block_release(__unsafe_forge_single(const void *, (const void *)(__VA_ARGS__))) #endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/libkern/OSKextLib.h b/lib/libc/include/any-macos.13-any/libkern/OSKextLib.h new file mode 100644 index 0000000000..ad703c433c --- /dev/null +++ b/lib/libc/include/any-macos.13-any/libkern/OSKextLib.h @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _LIBKERN_OSKEXTLIB_H +#define _LIBKERN_OSKEXTLIB_H + +#include +__BEGIN_DECLS + +#include +#include +#include +#include + +#include + +/*! + * @header + * + * Declares functions, basic return values, and other constants + * related to kernel extensions (kexts). + */ + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark OSReturn Values for Kernel Extensions +/********************************************************************/ +#endif +/*! + * @group OSReturn Values for Kernel Extensions + * Many kext-related functions return these values, + * as well as those defined under + * @link //apple_ref/c/tdef/OSReturn OSReturn@/link + * and other variants of kern_return_t. + */ + + +#define sub_libkern_kext err_sub(2) +#define libkern_kext_err(code) (sys_libkern|sub_libkern_kext|(code)) + + +/*! + * @define kOSKextReturnInternalError + * @abstract An internal error in the kext library. + * Contrast with @link //apple_ref/c/econst/OSReturnError + * OSReturnError@/link. + */ +#define kOSKextReturnInternalError libkern_kext_err(0x1) + +/*! + * @define kOSKextReturnNoMemory + * @abstract Memory allocation failed. + */ +#define kOSKextReturnNoMemory libkern_kext_err(0x2) + +/*! + * @define kOSKextReturnNoResources + * @abstract Some resource other than memory (such as available load tags) + * is exhausted. + */ +#define kOSKextReturnNoResources libkern_kext_err(0x3) + +/*! + * @define kOSKextReturnNotPrivileged + * @abstract The caller lacks privileges to perform the requested operation. + */ +#define kOSKextReturnNotPrivileged libkern_kext_err(0x4) + +/*! + * @define kOSKextReturnInvalidArgument + * @abstract Invalid argument. + */ +#define kOSKextReturnInvalidArgument libkern_kext_err(0x5) + +/*! + * @define kOSKextReturnNotFound + * @abstract Search item not found. + */ +#define kOSKextReturnNotFound libkern_kext_err(0x6) + +/*! + * @define kOSKextReturnBadData + * @abstract Malformed data (not used for XML). + */ +#define kOSKextReturnBadData libkern_kext_err(0x7) + +/*! + * @define kOSKextReturnSerialization + * @abstract Error converting or (un)serializing URL, string, or XML. + */ +#define kOSKextReturnSerialization libkern_kext_err(0x8) + +/*! + * @define kOSKextReturnUnsupported + * @abstract Operation is no longer or not yet supported. + */ +#define kOSKextReturnUnsupported libkern_kext_err(0x9) + +/*! + * @define kOSKextReturnDisabled + * @abstract Operation is currently disabled. + */ +#define kOSKextReturnDisabled libkern_kext_err(0xa) + +/*! + * @define kOSKextReturnNotAKext + * @abstract Bundle is not a kernel extension. + */ +#define kOSKextReturnNotAKext libkern_kext_err(0xb) + +/*! + * @define kOSKextReturnValidation + * @abstract Validation failures encountered; check diagnostics for details. + */ +#define kOSKextReturnValidation libkern_kext_err(0xc) + +/*! + * @define kOSKextReturnAuthentication + * @abstract Authetication failures encountered; check diagnostics for details. + */ +#define kOSKextReturnAuthentication libkern_kext_err(0xd) + +/*! + * @define kOSKextReturnDependencies + * @abstract Dependency resolution failures encountered; check diagnostics for details. + */ +#define kOSKextReturnDependencies libkern_kext_err(0xe) + +/*! + * @define kOSKextReturnArchNotFound + * @abstract Kext does not contain code for the requested architecture. + */ +#define kOSKextReturnArchNotFound libkern_kext_err(0xf) + +/*! + * @define kOSKextReturnCache + * @abstract An error occurred processing a system kext cache. + */ +#define kOSKextReturnCache libkern_kext_err(0x10) + +/*! + * @define kOSKextReturnDeferred + * @abstract Operation has been posted asynchronously to user space (kernel only). + */ +#define kOSKextReturnDeferred libkern_kext_err(0x11) + +/*! + * @define kOSKextReturnBootLevel + * @abstract Kext not loadable or operation not allowed at current boot level. + */ +#define kOSKextReturnBootLevel libkern_kext_err(0x12) + +/*! + * @define kOSKextReturnNotLoadable + * @abstract Kext cannot be loaded; check diagnostics for details. + */ +#define kOSKextReturnNotLoadable libkern_kext_err(0x13) + +/*! + * @define kOSKextReturnLoadedVersionDiffers + * @abstract A different version (or executable UUID, or executable by checksum) + * of the requested kext is already loaded. + */ +#define kOSKextReturnLoadedVersionDiffers libkern_kext_err(0x14) + +/*! + * @define kOSKextReturnDependencyLoadError + * @abstract A load error occurred on a dependency of the kext being loaded. + */ +#define kOSKextReturnDependencyLoadError libkern_kext_err(0x15) + +/*! + * @define kOSKextReturnLinkError + * @abstract A link failure occured with this kext or a dependency. + */ +#define kOSKextReturnLinkError libkern_kext_err(0x16) + +/*! + * @define kOSKextReturnStartStopError + * @abstract The kext start or stop routine returned an error. + */ +#define kOSKextReturnStartStopError libkern_kext_err(0x17) + +/*! + * @define kOSKextReturnInUse + * @abstract The kext is currently in use or has outstanding references, + * and cannot be unloaded. + */ +#define kOSKextReturnInUse libkern_kext_err(0x18) + +/*! + * @define kOSKextReturnTimeout + * @abstract A kext request has timed out. + */ +#define kOSKextReturnTimeout libkern_kext_err(0x19) + +/*! + * @define kOSKextReturnStopping + * @abstract The kext is in the process of stopping; requests cannot be made. + */ +#define kOSKextReturnStopping libkern_kext_err(0x1a) + +/*! + * @define kOSKextReturnSystemPolicy + * @abstract The kext was prevented from loading due to system policy. + */ +#define kOSKextReturnSystemPolicy libkern_kext_err(0x1b) + +/*! + * @define kOSKextReturnKCLoadFailure + * @abstract Loading of the System KC failed + */ +#define kOSKextReturnKCLoadFailure libkern_kext_err(0x1c) + +/*! + * @define kOSKextReturnKCLoadFailureSystemKC + * @abstract Loading of the System KC failed + * + * This a sub-code of kOSKextReturnKCLoadFailure. It can be OR'd together + * with: kOSKextReturnKCLoadFailureAuxKC + * + * If both the System and Aux KCs fail to load, then the error code will be: + * libkern_kext_err(0x1f) + */ +#define kOSKextReturnKCLoadFailureSystemKC libkern_kext_err(0x1d) + +/*! + * @define kOSKextReturnKCLoadFailureAuxKC + * @abstract Loading of the Aux KC failed + * + * This a sub-code of kOSKextReturnKCLoadFailure. It can be OR'd together + * with: kOSKextReturnKCLoadFailureSystemKC + * + * If both the System and Aux KCs fail to load, then the error code will be: + * libkern_kext_err(0x1f) + */ +#define kOSKextReturnKCLoadFailureAuxKC libkern_kext_err(0x1e) + +/* next available error is: libkern_kext_err(0x20) */ + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark Kext/OSBundle Property List Keys +/********************************************************************/ +#endif +/*! + * @group Kext Property List Keys + * These constants cover CFBundle properties defined for kernel extensions. + * Because they are used in the kernel, if you want to use one with + * CFBundle APIs you'll need to wrap it in a CFSTR() macro. + */ + + +/*! + * @define kOSBundleCompatibleVersionKey + * @abstract A string giving the backwards-compatible version of a library kext + * in extended Mac OS 'vers' format (####.##.##s{1-255} where 's' + * is a build stage 'd', 'a', 'b', 'f' or 'fc'). + */ +#define kOSBundleCompatibleVersionKey "OSBundleCompatibleVersion" + +/*! + * @define kOSBundleEnableKextLoggingKey + * @abstract Set to true to have the kernel kext logging spec applied + * to the kext. + * See @link //apple_ref/c/econst/OSKextLogSpec + * OSKextLogSpec@/link. + */ +#define kOSBundleEnableKextLoggingKey "OSBundleEnableKextLogging" + +/*! + * @define kOSBundleIsInterfaceKey + * @abstract A boolean value indicating whether the kext executable + * contains only symbol references. + */ +#define kOSBundleIsInterfaceKey "OSBundleIsInterface" + +/*! + * @define kOSBundleLibrariesKey + * @abstract A dictionary listing link dependencies for this kext. + * Keys are bundle identifiers, values are version strings. + */ +#define kOSBundleLibrariesKey "OSBundleLibraries" + +/*! + * @define kOSBundleRequiredKey + * @abstract A string indicating in which kinds of startup this kext + * may need to load during early startup (before + * @link //apple_ref/doc/man/8/kextd kextcache(8)@/link). + * @discussion + * The value is one of: + *
    + *
  • @link kOSBundleRequiredRoot "OSBundleRequiredRoot"@/link
  • + *
  • @link kOSBundleRequiredLocalRoot "OSBundleRequiredLocalRoot"@/link
  • + *
  • @link kOSBundleRequiredNetworkRoot "OSBundleRequiredNetworkRoot"@/link
  • + *
  • @link kOSBundleRequiredSafeBoot "OSBundleRequiredSafeBoot"@/link
  • + *
  • @link kOSBundleRequiredConsole "OSBundleRequiredConsole"@/link
  • + *
+ * + * Use this property judiciously. + * Every kext that declares a value other than "OSBundleRequiredSafeBoot" + * increases startup time, as the booter must read it into memory, + * or startup kext caches must include it. + */ +#define kOSBundleRequiredKey "OSBundleRequired" + +/*! + * @define kOSBundleRequireExplicitLoadKey + * @abstract A boolean value indicating whether the kext requires an + * explicit kextload in order to start/match. + */ +#define kOSBundleRequireExplicitLoadKey "OSBundleRequireExplicitLoad" + +/*! + * @define kOSBundleAllowUserLoadKey + * @abstract A boolean value indicating whether + * @link //apple_ref/doc/man/8/kextd kextcache(8)@/link + * will honor a non-root process's request to load a kext. + * @discussion + * See @link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithURL + * KextManagerLoadKextWithURL@/link + * and @link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithIdentifier + * KextManagerLoadKextWithIdentifier@/link. + */ +#define kOSBundleAllowUserLoadKey "OSBundleAllowUserLoad" + +/*! + * @define kOSBundleAllowUserTerminateKey + * @abstract A boolean value indicating whether the kextunload tool + * is allowed to issue IOService terminate to classes defined in this kext. + * @discussion A boolean value indicating whether the kextunload tool + * is allowed to issue IOService terminate to classes defined in this kext. + */ +#define kOSBundleAllowUserTerminateKey "OSBundleAllowUserTerminate" + +/*! + * @define kOSKernelResourceKey + * @abstract A boolean value indicating whether the kext represents a built-in + * component of the kernel. + */ +#define kOSKernelResourceKey "OSKernelResource" + +/*! + * @define kOSKextVariantOverrideKey + * @abstract A dictionary with target names as key and a target-specific variant + * name as value. + */ +#define kOSKextVariantOverrideKey "OSKextVariantOverride" + +/*! + * @define kIOKitPersonalitiesKey + * @abstract A dictionary of dictionaries used in matching for I/O Kit drivers. + */ +#define kIOKitPersonalitiesKey "IOKitPersonalities" + +/* + * @define kIOPersonalityPublisherKey + * @abstract Used in personalities sent to the I/O Kit, + * contains the CFBundleIdentifier of the kext + * that the personality originated in. + */ +#define kIOPersonalityPublisherKey "IOPersonalityPublisher" + +#if CONFIG_KEC_FIPS +/* + * @define kAppleTextHashesKey + * @abstract A dictionary conataining hashes for corecrypto kext. + */ +#define kAppleTextHashesKey "AppleTextHashes" +#endif + +/*! + * @define kOSMutableSegmentCopy + * @abstract A boolean value indicating whether the kext requires a copy of + * its mutable segments to be kept in memory, and then reset when the kext + * unloads. This should be used with caution as it will increase the + * amount of memory used by the kext. + */ +#define kOSMutableSegmentCopy "OSMutableSegmentCopy" + + +#if PRAGMA_MARK +/********************************************************************/ +#pragma mark Kext/OSBundle Property Deprecated Keys +/********************************************************************/ +#endif +/* + * @define kOSBundleDebugLevelKey + * @abstract + * Deprecated (used on some releases of Mac OS X prior to 10.6 Snow Leopard). + * Value is an integer from 1-6, corresponding to the verbose levels + * of kext tools on those releases. + * On 10.6 Snow Leopard, use @link OSKextEnableKextLogging + * OSKextEnableKextLogging@/link. + */ +#define kOSBundleDebugLevelKey "OSBundleDebugLevel" + +/*! + * @define kOSBundleSharedExecutableIdentifierKey + * @abstract Deprecated (used on some releases of Mac OS X + * prior to 10.6 Snow Leopard). + * Value is the bundle identifier of the pseudokext + * that contains an executable shared by this kext. + */ +#define kOSBundleSharedExecutableIdentifierKey "OSBundleSharedExecutableIdentifier" + + +#if PRAGMA_MARK +/********************************************************************/ +#pragma mark Kext/OSBundle Property List Values +/********************************************************************/ +#endif + +/*! + * @group Kext Property List Values + * These constants encompass established values + * for kernel extension bundle properties. + */ + +/*! + * @define kOSKextKernelIdentifier + * @abstract + * This is the CFBundleIdentifier user for the kernel itself. + */ +#define kOSKextKernelIdentifier "__kernel__" + + +/*! + * @define kOSKextBundlePackageTypeKext + * @abstract + * The bundle type value for Kernel Extensions. + */ +#define kOSKextBundlePackageTypeKext "KEXT" + +/*! + * @define kOSKextBundlePackageTypeDriverKit + * @abstract + * The bundle type value for Driver Extensions. + */ +#define kOSKextBundlePackageTypeDriverKit "DEXT" + +/*! + * @define kOSBundleRequiredRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * whether starting from a local or a network volume. + */ +#define kOSBundleRequiredRoot "Root" + +/*! + * @define kOSBundleRequiredLocalRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * when starting from a local disk. + */ +#define kOSBundleRequiredLocalRoot "Local-Root" + +/*! + * @define kOSBundleRequiredNetworkRoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed to mount the root filesystem + * when starting over a network connection. + */ +#define kOSBundleRequiredNetworkRoot "Network-Root" + +/*! + * @define kOSBundleRequiredSafeBoot + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext can be loaded during a safe startup. + * This value does not normally cause the kext to be read by the booter + * or included in startup kext caches. + */ +#define kOSBundleRequiredSafeBoot "Safe Boot" + +/*! + * @define kOSBundleRequiredConsole + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the kext may be needed for console access + * (specifically in a single-user startup when + * @link //apple_ref/doc/man/8/kextd kextd(8)@/link. + * does not run) + * and should be loaded during early startup. + */ +#define kOSBundleRequiredConsole "Console" + +/*! + * @define kOSBundleRequiredDriverKit + * @abstract + * This @link kOSBundleRequiredKey OSBundleRequired@/link + * value indicates that the driver extension's (DriverKit driver's) + * personalities must be present in the kernel at early boot (specifically + * before @link //apple_ref/doc/man/8/kextd kextd(8)@/link starts) + * in order to compete with kexts built into the prelinkedkernel. Note that + * kextd is still required to launch the user space driver binary. The IOKit + * matching will happen during early boot, and the actual driver launch + * will happen after kextd starts. + */ +#define kOSBundleRequiredDriverKit "DriverKit" + +#if PRAGMA_MARK +#pragma mark - +/********************************************************************/ +#pragma mark Kext Information +/********************************************************************/ +#endif +/*! + * @group Kext Information + * Types, constants, and macros providing a kext with information + * about itself. + */ + +/*! + * @typedef OSKextLoadTag + * + * @abstract + * A unique identifier assigned to a loaded instanace of a kext. + * + * @discussion + * If a kext is unloaded and later reloaded, the new instance + * has a different load tag. + * + * A kext can get its own load tag in the kmod_info_t + * structure passed into its module start routine, as the + * id field (cast to this type). + */ +typedef uint32_t OSKextLoadTag; + +/*! + * @define kOSKextInvalidLoadTag + * + * @abstract + * A load tag value that will never be used for a loaded kext; + * indicates kext not found. + */ +#define kOSKextInvalidLoadTag ((OSKextLoadTag)(-1)) + + +__END_DECLS + +#endif /* _LIBKERN_OSKEXTLIB_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/mach-o/arm64/reloc.h b/lib/libc/include/any-macos.13-any/mach-o/arm64/reloc.h new file mode 100644 index 0000000000..f9b767a509 --- /dev/null +++ b/lib/libc/include/any-macos.13-any/mach-o/arm64/reloc.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2010 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _MACHO_ARM64_RELOC_H_ +#define _MACHO_ARM64_RELOC_H_ + +/* + * Relocations for arm64 are a bit different than for other architectures in + * Mach-O: Scattered relocations are not used. Almost all relocations produced + * by the compiler are external relocations. An external relocation has the + * r_extern bit set to 1 and the r_symbolnum field contains the symbol table + * index of the target label. + * + * When the assembler is generating relocations, if the target label is a local + * label (begins with 'L'), then the previous non-local label in the same + * section is used as the target of the external relocation. An addend is used + * with the distance from that non-local label to the target label. Only when + * there is no previous non-local label in the section is an internal + * relocation used. + * + * The addend (i.e. the 4 in _foo+4) is encoded either in the instruction or + * in the r_symbolnum of ARM64_RELOC_ADDEND. + * For ARM64_RELOC_UNSIGNED and ARM64_RELOC_AUTHENTICATED_POINTER, the addend + * is stored in the instruction. ARM64_RELOC_PAGE21, ARM64_RELOC_PAGEOFF12 and + * ARM64_RELOC_BRANCH26 must be preceded by an ARM64_RELOC_ADDEND if they need + * an addend. No other relocations support addends. + * + * The relocation types are: + * + * ARM64_RELOC_UNSIGNED // For pointer sized fixups + * ARM64_RELOC_SUBTRACTOR // must be followed by a ARM64_RELOC_UNSIGNED + * ARM64_RELOC_BRANCH26 // a BL instruction with pc-relative +-128MB displacement + * ARM64_RELOC_PAGE21 // pc-rel distance to page of target + * ARM64_RELOC_PAGEOFF12 // offset within page, scaled by r_length + * ARM64_RELOC_GOT_LOAD_PAGE21 // load with a pc-rel distance to page of a GOT entry + * ARM64_RELOC_GOT_LOAD_PAGEOFF12 // load with an offset within page, scaled by r_length, of GOT entry + * ARM64_RELOC_POINTER_TO_GOT // 32-bit pc-rel (or 64-bit absolute) offset to a GOT entry + * ARM64_RELOC_TLVP_LOAD_PAGE21 // tlv load with a pc-rel distance to page of a GOT entry + * ARM64_RELOC_TLVP_LOAD_PAGEOFF12 // tlv load with an offset within page, scaled by r_length, of GOT entry + * ARM64_RELOC_ADDEND // must be followed by ARM64_RELOC_BRANCH26/ARM64_RELOC_PAGE21/ARM64_RELOC_PAGEOFF12 + * ARM64_RELOC_AUTHENTICATED_POINTER // 64-bit pointer with authentication + * + * The following are sample assembly instructions, followed by the relocation + * and section content they generate in an object file: + * + * (arm64_32 only) + * .long _foo + * r_type=ARM64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 + * + * (arm64_32 only) + * .long _foo + 4 + * r_type=ARM64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 04 00 00 00 + * + * .quad _foo + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 00 00 00 00 + * + * .quad _foo + 16 + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 10 00 00 00 00 00 00 00 + * + * .quad L1 + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev + * 10 00 00 00 00 00 00 00 + * // assumes _prev is the first non-local label 0x10 bytes before L1 + * 10 00 00 00 00 00 00 00 + * + * (arm64_32 only) + * .long _foo - _bar + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar + * r_type=ARM64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 + * + * (arm64_32 only) + * .long _foo - _bar + 4 + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar + * r_type=ARM64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 04 00 00 00 + * + * .quad _foo - _bar + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 00 00 00 00 + * + * .quad _foo - _bar + 4 + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 04 00 00 00 00 00 00 00 + * + * .long _foo - . + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_prev + * r_type=ARM64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * f8 ff ff ff + * // assumes _prev is the first non-local label 0x8 bytes before this + * // .quad + * + * .long _foo - L1 + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_prev + * r_type=ARM64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * f8 ff ff ff + * // assumes _prev is the first non-local label 0x8 bytes before L1 + * + * .quad _foo - . + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * f8 ff ff ff ff ff ff ff + * // assumes _prev is the first non-local label 0x8 bytes before this + * // .quad + * + * .quad _foo - L1 + * r_type=ARM64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev + * r_type=ARM64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * f8 ff ff ff ff ff ff ff + * // assumes _prev is the first non-local label 0x8 bytes before L1 + * + * .long L1 - _prev + * // No relocations. This is an assembly time constant. + * 12 00 00 00 00 00 00 00 + * // assumes _prev is the first non-local label 0x12 bytes before L1 + * + * .quad L1 - _prev + * // No relocations. This is an assembly time constant. + * 12 00 00 00 00 00 00 00 + * // assumes _prev is the first non-local label 0x12 bytes before L1 + * + * bl _foo + * r_type=ARM64_RELOC_BRANCH26, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 0x14000000 + * + * bl _foo + 4 + * r_type=ARM64_RELOC_ADDEND, r_length=2, r_extern=0, r_pcrel=0, r_symbolnum=0x000004 + * r_type=ARM64_RELOC_BRANCH26, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 0x14000000 + * + * adrp x0, _foo@PAGE + * r_type=ARM64_RELOC_PAGE21, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 0x90000000 + * + * ldr x0, [x0, _foo@PAGEOFF] + * r_type=ARM64_RELOC_PAGEOFF12, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 0xf9400000 + * + * adrp x0, _foo@PAGE + 0x24 + * r_type=ARM64_RELOC_ADDEND, r_length=2, r_extern=0, r_pcrel=0, r_symbolnum=0x000024 + * r_type=ARM64_RELOC_PAGE21, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 0x90000000 + * + * ldr x0, [x0, _foo@PAGEOFF + 0x24] + * r_type=ARM64_RELOC_ADDEND, r_length=2, r_extern=0, r_pcrel=0, r_symbolnum=0x000024 + * r_type=ARM64_RELOC_PAGEOFF12, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 0xf9400000 + * + * adrp x0, _foo@GOTPAGE + * r_type=ARM64_RELOC_GOT_LOAD_PAGE21, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 0x90000000 + * + * ldr x0, [x0, _foo@GOTPAGEOFF] + * r_type=ARM64_RELOC_GOT_LOAD_PAGEOFF12, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 0xf9400000 + * + * adrp x0, _foo@TLVPPAGE + * r_type=ARM64_RELOC_TLVP_LOAD_PAGE21, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 0x90000000 + * + * ldr x0, [x0, _foo@TLVPPAGEOFF] + * r_type=ARM64_RELOC_TLVP_LOAD_PAGEOFF12, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 0xf9400000 + * + * .long _foo@GOT - . + * r_type=ARM64_RELOC_POINTER_TO_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo + * 00 00 00 00 + * + * (arm64_32 only) + * .long _foo@GOT + * r_type=ARM64_RELOC_POINTER_TO_GOT, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 + * + * .quad _foo@GOT + * r_type=ARM64_RELOC_POINTER_TO_GOT, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 00 00 00 00 + * + * (arm64e only) + * .quad _foo@AUTH(da,5,addr) + * r_type=ARM64_RELOC_AUTHENTICATED_POINTER, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 00 00 00 00 05 00 05 80 + * + * (arm64e only) + * .quad (_foo + 0x10)@AUTH(da,5,addr) + * r_type=ARM64_RELOC_AUTHENTICATED_POINTER, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo + * 10 00 00 00 05 00 05 80 + * + * + */ +enum reloc_type_arm64 +{ + ARM64_RELOC_UNSIGNED, // for pointers + ARM64_RELOC_SUBTRACTOR, // must be followed by a ARM64_RELOC_UNSIGNED + ARM64_RELOC_BRANCH26, // a B/BL instruction with 26-bit displacement + ARM64_RELOC_PAGE21, // pc-rel distance to page of target + ARM64_RELOC_PAGEOFF12, // offset within page, scaled by r_length + ARM64_RELOC_GOT_LOAD_PAGE21, // pc-rel distance to page of GOT slot + ARM64_RELOC_GOT_LOAD_PAGEOFF12, // offset within page of GOT slot, + // scaled by r_length + ARM64_RELOC_POINTER_TO_GOT, // for pointers to GOT slots + ARM64_RELOC_TLVP_LOAD_PAGE21, // pc-rel distance to page of TLVP slot + ARM64_RELOC_TLVP_LOAD_PAGEOFF12, // offset within page of TLVP slot, + // scaled by r_length + ARM64_RELOC_ADDEND, // must be followed by PAGE21 or PAGEOFF12 + + // An arm64e authenticated pointer. + // + // Represents a pointer to a symbol (like ARM64_RELOC_UNSIGNED). + // Additionally, the resulting pointer is signed. The signature is + // specified in the target location: the addend is restricted to the lower + // 32 bits (instead of the full 64 bits for ARM64_RELOC_UNSIGNED): + // + // |63|62|61-51|50-49| 48 |47 - 32|31 - 0| + // | 1| 0| 0 | key | addr | discriminator | addend | + // + // The key is one of: + // IA: 00 IB: 01 + // DA: 10 DB: 11 + // + // The discriminator field is used as extra signature diversification. + // + // The addr field indicates whether the target address should be blended + // into the discriminator. + // + ARM64_RELOC_AUTHENTICATED_POINTER, +}; + +#endif /* #ifndef _MACHO_ARM64_RELOC_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/mach-o/compact_unwind_encoding.h b/lib/libc/include/any-macos.13-any/mach-o/compact_unwind_encoding.h new file mode 100644 index 0000000000..4194a1e4aa --- /dev/null +++ b/lib/libc/include/any-macos.13-any/mach-o/compact_unwind_encoding.h @@ -0,0 +1,532 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// +// Darwin's alternative to DWARF based unwind encodings. +// +//===----------------------------------------------------------------------===// + + +#ifndef __COMPACT_UNWIND_ENCODING__ +#define __COMPACT_UNWIND_ENCODING__ + +#include + +// +// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section +// of object files. Or compilers can emit compact unwind information in +// the __LD,__compact_unwind section. +// +// When the linker creates a final linked image, it will create a +// __TEXT,__unwind_info section. This section is a small and fast way for the +// runtime to access unwind info for any given function. If the compiler +// emitted compact unwind info for the function, that compact unwind info will +// be encoded in the __TEXT,__unwind_info section. If the compiler emitted +// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset +// of the FDE in the __TEXT,__eh_frame section in the final linked image. +// +// Note: Previously, the linker would transform some DWARF unwind infos into +// compact unwind info. But that is fragile and no longer done. + + +// +// The compact unwind endoding is a 32-bit value which encoded in an +// architecture specific way, which registers to restore from where, and how +// to unwind out of the function. +// +typedef uint32_t compact_unwind_encoding_t; + + +// architecture independent bits +enum { + UNWIND_IS_NOT_FUNCTION_START = 0x80000000, + UNWIND_HAS_LSDA = 0x40000000, + UNWIND_PERSONALITY_MASK = 0x30000000, +}; + + + + +// +// x86 +// +// 1-bit: start +// 1-bit: has lsda +// 2-bit: personality index +// +// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF +// ebp based: +// 15-bits (5*3-bits per reg) register permutation +// 8-bits for stack offset +// frameless: +// 8-bits stack size +// 3-bits stack adjust +// 3-bits register count +// 10-bits register permutation +// +enum { + UNWIND_X86_MODE_MASK = 0x0F000000, + UNWIND_X86_MODE_EBP_FRAME = 0x01000000, + UNWIND_X86_MODE_STACK_IMMD = 0x02000000, + UNWIND_X86_MODE_STACK_IND = 0x03000000, + UNWIND_X86_MODE_DWARF = 0x04000000, + + UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF, + UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000, + + UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000, + UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000, + UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00, + UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, + + UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF, +}; + +enum { + UNWIND_X86_REG_NONE = 0, + UNWIND_X86_REG_EBX = 1, + UNWIND_X86_REG_ECX = 2, + UNWIND_X86_REG_EDX = 3, + UNWIND_X86_REG_EDI = 4, + UNWIND_X86_REG_ESI = 5, + UNWIND_X86_REG_EBP = 6, +}; + +// +// For x86 there are four modes for the compact unwind encoding: +// UNWIND_X86_MODE_EBP_FRAME: +// EBP based frame where EBP is push on stack immediately after return address, +// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current +// EPB value, then EBP is restored by popping off the stack, and the return +// is done by popping the stack once more into the pc. +// All non-volatile registers that need to be restored must have been saved +// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4 +// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved +// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries. +// Each entry contains which register to restore. +// UNWIND_X86_MODE_STACK_IMMD: +// A "frameless" (EBP not used as frame pointer) function with a small +// constant stack size. To return, a constant (encoded in the compact +// unwind encoding) is added to the ESP. Then the return is done by +// popping the stack into the pc. +// All non-volatile registers that need to be restored must have been saved +// on the stack immediately after the return address. The stack_size/4 is +// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024). +// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT. +// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were +// saved and their order. +// UNWIND_X86_MODE_STACK_IND: +// A "frameless" (EBP not used as frame pointer) function large constant +// stack size. This case is like the previous, except the stack size is too +// large to encode in the compact unwind encoding. Instead it requires that +// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact +// encoding contains the offset to the nnnnnnnn value in the function in +// UNWIND_X86_FRAMELESS_STACK_SIZE. +// UNWIND_X86_MODE_DWARF: +// No compact unwind encoding is available. Instead the low 24-bits of the +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. +// This mode is never used in object files. It is only generated by the +// linker in final linked images which have only DWARF unwind info for a +// function. +// +// The permutation encoding is a Lehmer code sequence encoded into a +// single variable-base number so we can encode the ordering of up to +// six registers in a 10-bit space. +// +// The following is the algorithm used to create the permutation encoding used +// with frameless stacks. It is passed the number of registers to be saved and +// an array of the register numbers saved. +// +//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6]) +//{ +// uint32_t renumregs[6]; +// for (int i=6-registerCount; i < 6; ++i) { +// int countless = 0; +// for (int j=6-registerCount; j < i; ++j) { +// if ( registers[j] < registers[i] ) +// ++countless; +// } +// renumregs[i] = registers[i] - countless -1; +// } +// uint32_t permutationEncoding = 0; +// switch ( registerCount ) { +// case 6: +// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1] +// + 6*renumregs[2] + 2*renumregs[3] +// + renumregs[4]); +// break; +// case 5: +// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2] +// + 6*renumregs[3] + 2*renumregs[4] +// + renumregs[5]); +// break; +// case 4: +// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3] +// + 3*renumregs[4] + renumregs[5]); +// break; +// case 3: +// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4] +// + renumregs[5]); +// break; +// case 2: +// permutationEncoding |= (5*renumregs[4] + renumregs[5]); +// break; +// case 1: +// permutationEncoding |= (renumregs[5]); +// break; +// } +// return permutationEncoding; +//} +// + + + + +// +// x86_64 +// +// 1-bit: start +// 1-bit: has lsda +// 2-bit: personality index +// +// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF +// rbp based: +// 15-bits (5*3-bits per reg) register permutation +// 8-bits for stack offset +// frameless: +// 8-bits stack size +// 3-bits stack adjust +// 3-bits register count +// 10-bits register permutation +// +enum { + UNWIND_X86_64_MODE_MASK = 0x0F000000, + UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, + UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, + UNWIND_X86_64_MODE_STACK_IND = 0x03000000, + UNWIND_X86_64_MODE_DWARF = 0x04000000, + + UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF, + UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000, + + UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000, + UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000, + UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00, + UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, + + UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF, +}; + +enum { + UNWIND_X86_64_REG_NONE = 0, + UNWIND_X86_64_REG_RBX = 1, + UNWIND_X86_64_REG_R12 = 2, + UNWIND_X86_64_REG_R13 = 3, + UNWIND_X86_64_REG_R14 = 4, + UNWIND_X86_64_REG_R15 = 5, + UNWIND_X86_64_REG_RBP = 6, +}; +// +// For x86_64 there are four modes for the compact unwind encoding: +// UNWIND_X86_64_MODE_RBP_FRAME: +// RBP based frame where RBP is push on stack immediately after return address, +// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current +// EPB value, then RBP is restored by popping off the stack, and the return +// is done by popping the stack once more into the pc. +// All non-volatile registers that need to be restored must have been saved +// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8 +// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved +// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries. +// Each entry contains which register to restore. +// UNWIND_X86_64_MODE_STACK_IMMD: +// A "frameless" (RBP not used as frame pointer) function with a small +// constant stack size. To return, a constant (encoded in the compact +// unwind encoding) is added to the RSP. Then the return is done by +// popping the stack into the pc. +// All non-volatile registers that need to be restored must have been saved +// on the stack immediately after the return address. The stack_size/8 is +// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048). +// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT. +// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were +// saved and their order. +// UNWIND_X86_64_MODE_STACK_IND: +// A "frameless" (RBP not used as frame pointer) function large constant +// stack size. This case is like the previous, except the stack size is too +// large to encode in the compact unwind encoding. Instead it requires that +// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact +// encoding contains the offset to the nnnnnnnn value in the function in +// UNWIND_X86_64_FRAMELESS_STACK_SIZE. +// UNWIND_X86_64_MODE_DWARF: +// No compact unwind encoding is available. Instead the low 24-bits of the +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. +// This mode is never used in object files. It is only generated by the +// linker in final linked images which have only DWARF unwind info for a +// function. +// + + +// ARM64 +// +// 1-bit: start +// 1-bit: has lsda +// 2-bit: personality index +// +// 4-bits: 4=frame-based, 3=DWARF, 2=frameless +// frameless: +// 12-bits of stack size +// frame-based: +// 4-bits D reg pairs saved +// 5-bits X reg pairs saved +// DWARF: +// 24-bits offset of DWARF FDE in __eh_frame section +// +enum { + UNWIND_ARM64_MODE_MASK = 0x0F000000, + UNWIND_ARM64_MODE_FRAMELESS = 0x02000000, + UNWIND_ARM64_MODE_DWARF = 0x03000000, + UNWIND_ARM64_MODE_FRAME = 0x04000000, + + UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001, + UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002, + UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004, + UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008, + UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010, + UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100, + UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200, + UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400, + UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800, + + UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000, + UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF, +}; +// For arm64 there are three modes for the compact unwind encoding: +// UNWIND_ARM64_MODE_FRAME: +// This is a standard arm64 prolog where FP/LR are immediately pushed on the +// stack, then SP is copied to FP. If there are any non-volatile registers +// saved, then are copied into the stack frame in pairs in a contiguous +// range right below the saved FP/LR pair. Any subset of the five X pairs +// and four D pairs can be saved, but the memory layout must be in register +// number order. +// UNWIND_ARM64_MODE_FRAMELESS: +// A "frameless" leaf function, where FP/LR are not saved. The return address +// remains in LR throughout the function. If any non-volatile registers +// are saved, they must be pushed onto the stack before any stack space is +// allocated for local variables. The stack sized (including any saved +// non-volatile registers) divided by 16 is encoded in the bits +// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK. +// UNWIND_ARM64_MODE_DWARF: +// No compact unwind encoding is available. Instead the low 24-bits of the +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. +// This mode is never used in object files. It is only generated by the +// linker in final linked images which have only DWARF unwind info for a +// function. +// + + +#ifndef __OPEN_SOURCE__ +// +// armv7k +// +// 1-bit: start +// 1-bit: has lsda +// 2-bit: personality index +// +// 4-bits: 1=frame, 2=frame+dregs, 4=dwarf +// +enum { + UNWIND_ARM_MODE_MASK = 0x0F000000, + UNWIND_ARM_MODE_FRAME = 0x01000000, + UNWIND_ARM_MODE_FRAME_D = 0x02000000, + UNWIND_ARM_MODE_DWARF = 0x04000000, + + UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000, + + UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001, + UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002, + UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004, + + UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008, + UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010, + UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020, + UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040, + UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080, + + UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700, + + UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF, +}; +// For armv7k there are three modes for the compact unwind encoding: +// UNWIND_ARM_MODE_FRAME: +// This is a standard arm prolog where lr/r7 are immediately pushed on the +// stack. As part of that first push r4, r5, or r6 can be also pushed +// and if so the FIRST_PUSH bit is set in the compact unwind. Additionally +// there can be a second push multiple which can save r8 through r12. +// If that is used, the registers saved is recorded with a SECOND_PUSH bit. +// Lastly, for var-args support, the prolog may save r1, r2, r3 to the +// stack before the frame push. If that is done the STACK_ADJUST_MASK +// records that the stack pointer must be adjust (e.g 0x00800000 means +// the stack pointer was adjusted 8 bytes down and the unwinder would +// need to add back 8 bytes to SP when unwinding through this function. +// UNWIND_ARM_MODE_FRAME_D: +// This is the same as UNWIND_ARM_MODE_FRAME, except that additionally +// some D registers were saved. The D_REG_COUNT_MASK contains which +// set if D registers were saved and where. There are currently 8 (0-7) +// possible D register save patterns supported. +// UNWIND_ARM_MODE_DWARF: +// No compact unwind encoding is available. Instead the low 24-bits of the +// compact encoding is the offset of the dwarf FDE in the __eh_frame section. +// The offset only exists in final linked images. It is zero in object files. +#endif + + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// Relocatable Object Files: __LD,__compact_unwind +// +//////////////////////////////////////////////////////////////////////////////// + +// +// A compiler can generated compact unwind information for a function by adding +// a "row" to the __LD,__compact_unwind section. This section has the +// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers. +// It is removed by the new linker, so never ends up in final executables. +// This section is a table, initially with one row per function (that needs +// unwind info). The table columns and some conceptual entries are: +// +// range-start pointer to start of function/range +// range-length +// compact-unwind-encoding 32-bit encoding +// personality-function or zero if no personality function +// lsda or zero if no LSDA data +// +// The length and encoding fields are 32-bits. The other are all pointer sized. +// +// In x86_64 assembly, these entry would look like: +// +// .section __LD,__compact_unwind,regular,debug +// +// #compact unwind for _foo +// .quad _foo +// .set L1,LfooEnd-_foo +// .long L1 +// .long 0x01010001 +// .quad 0 +// .quad 0 +// +// #compact unwind for _bar +// .quad _bar +// .set L2,LbarEnd-_bar +// .long L2 +// .long 0x01020011 +// .quad __gxx_personality +// .quad except_tab1 +// +// +// Notes: There is no need for any labels in the the __compact_unwind section. +// The use of the .set directive is to force the evaluation of the +// range-length at assembly time, instead of generating relocations. +// +// To support future compiler optimizations where which non-volatile registers +// are saved changes within a function (e.g. delay saving non-volatiles until +// necessary), there can by multiple lines in the __compact_unwind table for one +// function, each with a different (non-overlapping) range and each with +// different compact unwind encodings that correspond to the non-volatiles +// saved at that range of the function. +// +// If a particular function is so wacky that there is no compact unwind way +// to encode it, then the compiler can emit traditional DWARF unwind info. +// The runtime will use which ever is available. +// +// Runtime support for compact unwind encodings are only available on 10.6 +// and later. So, the compiler should not generate it when targeting pre-10.6. + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// Final Linked Images: __TEXT,__unwind_info +// +//////////////////////////////////////////////////////////////////////////////// + +// +// The __TEXT,__unwind_info section is laid out for an efficient two level lookup. +// The header of the section contains a coarse index that maps function address +// to the page (4096 byte block) containing the unwind info for that function. +// + +#define UNWIND_SECTION_VERSION 1 +struct unwind_info_section_header +{ + uint32_t version; // UNWIND_SECTION_VERSION + uint32_t commonEncodingsArraySectionOffset; + uint32_t commonEncodingsArrayCount; + uint32_t personalityArraySectionOffset; + uint32_t personalityArrayCount; + uint32_t indexSectionOffset; + uint32_t indexCount; + // compact_unwind_encoding_t[] + // uint32_t personalities[] + // unwind_info_section_header_index_entry[] + // unwind_info_section_header_lsda_index_entry[] +}; + +struct unwind_info_section_header_index_entry +{ + uint32_t functionOffset; + uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page + uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range +}; + +struct unwind_info_section_header_lsda_index_entry +{ + uint32_t functionOffset; + uint32_t lsdaOffset; +}; + +// +// There are two kinds of second level index pages: regular and compressed. +// A compressed page can hold up to 1021 entries, but it cannot be used +// if too many different encoding types are used. The regular page holds +// 511 entries. +// + +struct unwind_info_regular_second_level_entry +{ + uint32_t functionOffset; + compact_unwind_encoding_t encoding; +}; + +#define UNWIND_SECOND_LEVEL_REGULAR 2 +struct unwind_info_regular_second_level_page_header +{ + uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR + uint16_t entryPageOffset; + uint16_t entryCount; + // entry array +}; + +#define UNWIND_SECOND_LEVEL_COMPRESSED 3 +struct unwind_info_compressed_second_level_page_header +{ + uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED + uint16_t entryPageOffset; + uint16_t entryCount; + uint16_t encodingsPageOffset; + uint16_t encodingsCount; + // 32-bit entry array + // encodings array +}; + +#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF) +#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF) + + + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/mach-o/fat.h b/lib/libc/include/any-macos.13-any/mach-o/fat.h index 32959ca42a..415664cc91 100644 --- a/lib/libc/include/any-macos.13-any/mach-o/fat.h +++ b/lib/libc/include/any-macos.13-any/mach-o/fat.h @@ -42,7 +42,10 @@ * and contains the constants for the possible values of these types. */ #include + +#if __has_include() #include +#endif #if __has_include() #include @@ -57,8 +60,8 @@ struct fat_header { }; struct fat_arch { - cpu_type_t cputype; /* cpu specifier (int) */ - cpu_subtype_t cpusubtype; /* machine specifier (int) */ + int32_t cputype; /* cpu specifier (int) */ + int32_t cpusubtype; /* machine specifier (int) */ uint32_t offset; /* file offset to this object file */ uint32_t size; /* size of this object file */ uint32_t align; /* alignment as a power of 2 */ @@ -75,8 +78,8 @@ struct fat_arch { #define FAT_CIGAM_64 0xbfbafeca /* NXSwapLong(FAT_MAGIC_64) */ struct fat_arch_64 { - cpu_type_t cputype; /* cpu specifier (int) */ - cpu_subtype_t cpusubtype; /* machine specifier (int) */ + int32_t cputype; /* cpu specifier (int) */ + int32_t cpusubtype; /* machine specifier (int) */ uint64_t offset; /* file offset to this object file */ uint64_t size; /* size of this object file */ uint32_t align; /* alignment as a power of 2 */ diff --git a/lib/libc/include/any-macos.13-any/mach/mach_host.h b/lib/libc/include/any-macos.13-any/mach/mach_host.h index 2cdf4c33a9..057c069748 100644 --- a/lib/libc/include/any-macos.13-any/mach/mach_host.h +++ b/lib/libc/include/any-macos.13-any/mach/mach_host.h @@ -297,7 +297,7 @@ extern #endif /* mig_external */ kern_return_t mach_zone_info ( - host_priv_t host, + mach_port_t host, mach_zone_name_array_t *names, mach_msg_type_number_t *namesCnt, mach_zone_info_array_t *info, @@ -385,7 +385,7 @@ extern #endif /* mig_external */ kern_return_t mach_memory_info ( - host_priv_t host, + mach_port_t host, mach_zone_name_array_t *names, mach_msg_type_number_t *namesCnt, mach_zone_info_array_t *info, diff --git a/lib/libc/include/any-macos.13-any/mach/mach_types.h b/lib/libc/include/any-macos.13-any/mach/mach_types.h index ed1885d120..0c0f4c5ccc 100644 --- a/lib/libc/include/any-macos.13-any/mach/mach_types.h +++ b/lib/libc/include/any-macos.13-any/mach/mach_types.h @@ -217,8 +217,12 @@ typedef clock_ctrl_t clock_ctrl_port_t; typedef exception_handler_t exception_port_t; typedef exception_handler_array_t exception_port_arrary_t; typedef char vfs_path_t[4096]; -typedef char nspace_path_t[1024]; /* 1024 == PATH_MAX */ -typedef char nspace_name_t[1024]; /* 1024 == PATH_MAX */ +/* + * 8K, c.f. FSGETPATH_MAXBUFLEN in bsd/vfs/vfs_syscalls.c. + * These types should NEVER be allocated on the stack. + */ +typedef char nspace_path_t[8192]; +typedef char nspace_name_t[8192]; #define TASK_NULL ((task_t) 0) #define TASK_NAME_NULL ((task_name_t) 0) diff --git a/lib/libc/include/any-macos.13-any/mach/port.h b/lib/libc/include/any-macos.13-any/mach/port.h index effc74aba4..e8412ba13a 100644 --- a/lib/libc/include/any-macos.13-any/mach/port.h +++ b/lib/libc/include/any-macos.13-any/mach/port.h @@ -400,6 +400,7 @@ enum mach_port_guard_exception_codes { kGUARD_EXC_MOD_REFS = 2, kGUARD_EXC_INVALID_OPTIONS = 3, kGUARD_EXC_SET_CONTEXT = 4, + kGUARD_EXC_THREAD_SET_STATE = 5, kGUARD_EXC_UNGUARDED = 1u << 3, kGUARD_EXC_INCORRECT_GUARD = 1u << 4, kGUARD_EXC_IMMOVABLE = 1u << 5, diff --git a/lib/libc/include/any-macos.13-any/mach/vm_statistics.h b/lib/libc/include/any-macos.13-any/mach/vm_statistics.h index 172e7f3bef..8bed505b28 100644 --- a/lib/libc/include/any-macos.13-any/mach/vm_statistics.h +++ b/lib/libc/include/any-macos.13-any/mach/vm_statistics.h @@ -284,11 +284,12 @@ typedef struct vm_purgeable_info *vm_purgeable_info_t; #define VM_FLAGS_RETURN_4K_DATA_ADDR 0x00800000 /* Return 4K aligned address of target data */ #define VM_FLAGS_ALIAS_MASK 0xFF000000 #define VM_GET_FLAGS_ALIAS(flags, alias) \ - (alias) = ((flags) & VM_FLAGS_ALIAS_MASK) >> 24 + (alias) = (((flags) >> 24) & 0xff) #define VM_SET_FLAGS_ALIAS(flags, alias) \ (flags) = (((flags) & ~VM_FLAGS_ALIAS_MASK) | \ (((alias) & ~VM_FLAGS_ALIAS_MASK) << 24)) + /* These are the flags that we accept from user-space */ #define VM_FLAGS_USER_ALLOCATE (VM_FLAGS_FIXED | \ VM_FLAGS_ANYWHERE | \ @@ -301,9 +302,11 @@ typedef struct vm_purgeable_info *vm_purgeable_info_t; VM_FLAGS_SUPERPAGE_MASK | \ VM_FLAGS_TPRO | \ VM_FLAGS_ALIAS_MASK) + #define VM_FLAGS_USER_MAP (VM_FLAGS_USER_ALLOCATE | \ VM_FLAGS_RETURN_4K_DATA_ADDR | \ VM_FLAGS_RETURN_DATA_ADDR) + #define VM_FLAGS_USER_REMAP (VM_FLAGS_FIXED | \ VM_FLAGS_ANYWHERE | \ VM_FLAGS_RANDOM_ADDR | \ diff --git a/lib/libc/include/any-macos.13-any/mach/vm_types.h b/lib/libc/include/any-macos.13-any/mach/vm_types.h index e5aaa9bb93..c805a290de 100644 --- a/lib/libc/include/any-macos.13-any/mach/vm_types.h +++ b/lib/libc/include/any-macos.13-any/mach/vm_types.h @@ -66,7 +66,7 @@ typedef uint32_t reg64_t; * addresses (that are page aligned) as 32-bit page numbers. * This limits the physical address space to 16TB of RAM. */ -typedef uint32_t ppnum_t; /* Physical page number */ +typedef uint32_t ppnum_t __kernel_ptr_semantics; /* Physical page number */ #define PPNUM_MAX UINT32_MAX diff --git a/lib/libc/include/any-macos.13-any/net/if_var.h b/lib/libc/include/any-macos.13-any/net/if_var.h index 32b7918282..b2d2c49eba 100644 --- a/lib/libc/include/any-macos.13-any/net/if_var.h +++ b/lib/libc/include/any-macos.13-any/net/if_var.h @@ -75,6 +75,7 @@ #endif + #ifdef __APPLE__ #define APPLE_IF_FAM_LOOPBACK 1 #define APPLE_IF_FAM_ETHERNET 2 diff --git a/lib/libc/include/any-macos.13-any/objc/NSObject.h b/lib/libc/include/any-macos.13-any/objc/NSObject.h new file mode 100644 index 0000000000..4f4762519f --- /dev/null +++ b/lib/libc/include/any-macos.13-any/objc/NSObject.h @@ -0,0 +1,115 @@ +/* NSObject.h + Copyright (c) 1994-2012, Apple Inc. All rights reserved. +*/ + +#ifndef _OBJC_NSOBJECT_H_ +#define _OBJC_NSOBJECT_H_ + +#if __OBJC__ + +#include +#include + +@class NSString, NSMethodSignature, NSInvocation; + +@protocol NSObject + +- (BOOL)isEqual:(id)object; +@property (readonly) NSUInteger hash; + +@property (readonly) Class superclass; +- (Class)class OBJC_SWIFT_UNAVAILABLE("use 'type(of: anObject)' instead"); +- (instancetype)self; + +- (id)performSelector:(SEL)aSelector; +- (id)performSelector:(SEL)aSelector withObject:(id)object; +- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; + +- (BOOL)isProxy; + +- (BOOL)isKindOfClass:(Class)aClass; +- (BOOL)isMemberOfClass:(Class)aClass; +- (BOOL)conformsToProtocol:(Protocol *)aProtocol; + +- (BOOL)respondsToSelector:(SEL)aSelector; + +- (instancetype)retain OBJC_ARC_UNAVAILABLE; +- (oneway void)release OBJC_ARC_UNAVAILABLE; +- (instancetype)autorelease OBJC_ARC_UNAVAILABLE; +- (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE; + +- (struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; + +@property (readonly, copy) NSString *description; +@optional +@property (readonly, copy) NSString *debugDescription; + +@end + + +OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) +OBJC_ROOT_CLASS +OBJC_EXPORT +@interface NSObject { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-interface-ivars" + Class isa OBJC_ISA_AVAILABILITY; +#pragma clang diagnostic pop +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-load-method" ++ (void)load; +#pragma clang diagnostic pop + ++ (void)initialize; +- (instancetype)init +#if NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER + NS_DESIGNATED_INITIALIZER +#endif + ; + ++ (instancetype)new OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); ++ (instancetype)allocWithZone:(struct _NSZone *)zone OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); ++ (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); +- (void)dealloc OBJC_SWIFT_UNAVAILABLE("use 'deinit' to define a de-initializer"); + +- (void)finalize OBJC_DEPRECATED("Objective-C garbage collection is no longer supported"); + +- (id)copy; +- (id)mutableCopy; + ++ (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; ++ (id)mutableCopyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; + ++ (BOOL)instancesRespondToSelector:(SEL)aSelector; ++ (BOOL)conformsToProtocol:(Protocol *)protocol; +- (IMP)methodForSelector:(SEL)aSelector; ++ (IMP)instanceMethodForSelector:(SEL)aSelector; +- (void)doesNotRecognizeSelector:(SEL)aSelector; + +- (id)forwardingTargetForSelector:(SEL)aSelector OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); +- (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE(""); +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""); + ++ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""); + +- (BOOL)allowsWeakReference UNAVAILABLE_ATTRIBUTE; +- (BOOL)retainWeakReference UNAVAILABLE_ATTRIBUTE; + ++ (BOOL)isSubclassOfClass:(Class)aClass; + ++ (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); ++ (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + ++ (NSUInteger)hash; ++ (Class)superclass; ++ (Class)class OBJC_SWIFT_UNAVAILABLE("use 'aClass.self' instead"); ++ (NSString *)description; ++ (NSString *)debugDescription; + +@end + +#endif + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/objc/runtime.h b/lib/libc/include/any-macos.13-any/objc/runtime.h index 5d8cf96e06..f65b458bf9 100644 --- a/lib/libc/include/any-macos.13-any/objc/runtime.h +++ b/lib/libc/include/any-macos.13-any/objc/runtime.h @@ -542,7 +542,7 @@ class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name) * * @return A pointer to the \c Method data structure that corresponds to the implementation of the * selector specified by aSelector for the class specified by aClass, or NULL if the specified - * class or its superclasses do not contain an instance method with the specified selector. + * class or its superclasses do not contain a class method with the specified selector. * * @note Note that this function searches superclasses for implementations, * whereas \c class_copyMethodList does not. @@ -1898,6 +1898,17 @@ _objc_realizeClassFromSwift(Class _Nullable cls, void * _Nullable previously) struct objc_method_list; +/* Used for testing only */ + +OBJC_EXPORT void +_objc_flush_caches(Class _Nullable cls) + __OSX_DEPRECATED(10.0, 10.5, "not recommended") + __IOS_DEPRECATED(2.0, 2.0, "not recommended") + __TVOS_DEPRECATED(9.0, 9.0, "not recommended") + __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended") + +; + /* Obsolete functions */ #if !0 @@ -1919,15 +1930,6 @@ class_respondsToMethod(Class _Nullable cls, SEL _Nonnull sel) ; -OBJC_EXPORT void -_objc_flush_caches(Class _Nullable cls) - __OSX_DEPRECATED(10.0, 10.5, "not recommended") - __IOS_DEPRECATED(2.0, 2.0, "not recommended") - __TVOS_DEPRECATED(9.0, 9.0, "not recommended") - __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended") - -; - OBJC_EXPORT id _Nullable object_copyFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z) OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.0, 10.5, "use object_copy instead"); diff --git a/lib/libc/include/any-macos.13-any/simd/simd.h b/lib/libc/include/any-macos.13-any/simd/simd.h new file mode 100644 index 0000000000..f6aff16f46 --- /dev/null +++ b/lib/libc/include/any-macos.13-any/simd/simd.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2014 Apple, Inc. All rights reserved. + * + * This header provides small vector (simd) and matrix types, and basic + * arithmetic and mathematical functions for them. The vast majority of these + * operations are implemented as header inlines, as they can be performed + * using just a few instructions on most processors. + * + * These functions are broken into two groups; vector and matrix. This header + * includes all of them, but these may also be included separately. Consult + * these two headers for detailed documentation of what types and operations + * are available. + */ + +#ifndef __SIMD_HEADER__ +#define __SIMD_HEADER__ + +#if __has_include() +#include +REALTIME_SAFE_BEGIN +#endif + +#include +#include +#include + +#if __has_include() +REALTIME_SAFE_END +#endif + +#endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h b/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h index 1212cd91dd..6437f61b04 100644 --- a/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h +++ b/lib/libc/include/any-macos.13-any/sys/_symbol_aliasing.h @@ -389,6 +389,18 @@ #define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_2(x) #endif +#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 160300 +#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_3(x) x +#else +#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_3(x) +#endif + +#if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 160400 +#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_4(x) x +#else +#define __DARWIN_ALIAS_STARTING_IPHONE___IPHONE_16_4(x) +#endif + #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1000 #define __DARWIN_ALIAS_STARTING_MAC___MAC_10_0(x) x #else @@ -645,4 +657,16 @@ #define __DARWIN_ALIAS_STARTING_MAC___MAC_13_1(x) x #else #define __DARWIN_ALIAS_STARTING_MAC___MAC_13_1(x) +#endif + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 130200 +#define __DARWIN_ALIAS_STARTING_MAC___MAC_13_2(x) x +#else +#define __DARWIN_ALIAS_STARTING_MAC___MAC_13_2(x) +#endif + +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 130300 +#define __DARWIN_ALIAS_STARTING_MAC___MAC_13_3(x) x +#else +#define __DARWIN_ALIAS_STARTING_MAC___MAC_13_3(x) #endif \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/sys/attr.h b/lib/libc/include/any-macos.13-any/sys/attr.h new file mode 100644 index 0000000000..07edaeea34 --- /dev/null +++ b/lib/libc/include/any-macos.13-any/sys/attr.h @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2000-2018 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* + * attr.h - attribute data structures and interfaces + * + * Copyright (c) 1998, Apple Computer, Inc. All Rights Reserved. + */ + +#ifndef _SYS_ATTR_H_ +#define _SYS_ATTR_H_ + +#include + +#ifdef __APPLE_API_UNSTABLE +#include +#include +#include +#include + +#define FSOPT_NOFOLLOW 0x00000001 +#define FSOPT_NOINMEMUPDATE 0x00000002 +#define FSOPT_REPORT_FULLSIZE 0x00000004 +/* The following option only valid when requesting ATTR_CMN_RETURNED_ATTRS */ +#define FSOPT_PACK_INVAL_ATTRS 0x00000008 + + +#define FSOPT_ATTR_CMN_EXTENDED 0x00000020 +#define FSOPT_RETURN_REALDEV 0x00000200 +#define FSOPT_NOFOLLOW_ANY 0x00000800 + +/* we currently aren't anywhere near this amount for a valid + * fssearchblock.sizeofsearchparams1 or fssearchblock.sizeofsearchparams2 + * but we put a sanity check in to avoid abuse of the value passed in from + * user land. + */ +#define SEARCHFS_MAX_SEARCHPARMS 4096 + +typedef u_int32_t text_encoding_t; + +typedef u_int32_t fsobj_type_t; + +typedef u_int32_t fsobj_tag_t; + +typedef u_int32_t fsfile_type_t; + +typedef u_int32_t fsvolid_t; + +#include /* file object id type */ + +typedef u_int32_t attrgroup_t; + +struct attrlist { + u_short bitmapcount; /* number of attr. bit sets in list (should be 5) */ + u_int16_t reserved; /* (to maintain 4-byte alignment) */ + attrgroup_t commonattr; /* common attribute group */ + attrgroup_t volattr; /* Volume attribute group */ + attrgroup_t dirattr; /* directory attribute group */ + attrgroup_t fileattr; /* file attribute group */ + attrgroup_t forkattr; /* fork attribute group */ +}; + +#define ATTR_BIT_MAP_COUNT 5 + +typedef struct attribute_set { + attrgroup_t commonattr; /* common attribute group */ + attrgroup_t volattr; /* Volume attribute group */ + attrgroup_t dirattr; /* directory attribute group */ + attrgroup_t fileattr; /* file attribute group */ + attrgroup_t forkattr; /* fork attribute group */ +} attribute_set_t; + +#define ATTRIBUTE_SET_INIT(a) do {(a)->commonattr = (a)->volattr = (a)->dirattr = (a)->fileattr = (a)->forkattr = 0; } while(0) + + +typedef struct attrreference { + int32_t attr_dataoffset; + u_int32_t attr_length; +} attrreference_t; + +/* XXX PPD This is derived from HFSVolumePriv.h and should perhaps be referenced from there? */ + +struct diskextent { + u_int32_t startblock; /* first block allocated */ + u_int32_t blockcount; /* number of blocks allocated */ +}; + +typedef struct diskextent extentrecord[8]; + +typedef u_int32_t vol_capabilities_set_t[4]; + +#define VOL_CAPABILITIES_FORMAT 0 +#define VOL_CAPABILITIES_INTERFACES 1 +#define VOL_CAPABILITIES_RESERVED1 2 +#define VOL_CAPABILITIES_RESERVED2 3 + +typedef struct vol_capabilities_attr { + vol_capabilities_set_t capabilities; + vol_capabilities_set_t valid; +} vol_capabilities_attr_t; + +/* + * XXX this value needs to be raised - 3893388 + */ +#define ATTR_MAX_BUFFER 8192 + +/* + * VOL_CAP_FMT_PERSISTENTOBJECTIDS: When set, the volume has object IDs + * that are persistent (retain their values even when the volume is + * unmounted and remounted), and a file or directory can be looked up + * by ID. Volumes that support VolFS and can support Carbon File ID + * references should set this bit. + * + * VOL_CAP_FMT_SYMBOLICLINKS: When set, the volume supports symbolic + * links. The symlink(), readlink(), and lstat() calls all use this + * symbolic link. + * + * VOL_CAP_FMT_HARDLINKS: When set, the volume supports hard links. + * The link() call creates hard links. + * + * VOL_CAP_FMT_JOURNAL: When set, the volume is capable of supporting + * a journal used to speed recovery in case of unplanned shutdown + * (such as a power outage or crash). This bit does not necessarily + * mean the volume is actively using a journal for recovery. + * + * VOL_CAP_FMT_JOURNAL_ACTIVE: When set, the volume is currently using + * a journal for use in speeding recovery after an unplanned shutdown. + * This bit can be set only if VOL_CAP_FMT_JOURNAL is also set. + * + * VOL_CAP_FMT_NO_ROOT_TIMES: When set, the volume format does not + * store reliable times for the root directory, so you should not + * depend on them to detect changes, etc. + * + * VOL_CAP_FMT_SPARSE_FILES: When set, the volume supports sparse files. + * That is, files which can have "holes" that have never been written + * to, and are not allocated on disk. Sparse files may have an + * allocated size that is less than the file's logical length. + * + * VOL_CAP_FMT_ZERO_RUNS: For security reasons, parts of a file (runs) + * that have never been written to must appear to contain zeroes. When + * this bit is set, the volume keeps track of allocated but unwritten + * runs of a file so that it can substitute zeroes without actually + * writing zeroes to the media. This provides performance similar to + * sparse files, but not the space savings. + * + * VOL_CAP_FMT_CASE_SENSITIVE: When set, file and directory names are + * case sensitive (upper and lower case are different). When clear, + * an upper case character is equivalent to a lower case character, + * and you can't have two names that differ solely in the case of + * the characters. + * + * VOL_CAP_FMT_CASE_PRESERVING: When set, file and directory names + * preserve the difference between upper and lower case. If clear, + * the volume may change the case of some characters (typically + * making them all upper or all lower case). A volume that sets + * VOL_CAP_FMT_CASE_SENSITIVE should also set VOL_CAP_FMT_CASE_PRESERVING. + * + * VOL_CAP_FMT_FAST_STATFS: This bit is used as a hint to upper layers + * (especially Carbon) that statfs() is fast enough that its results + * need not be cached by those upper layers. A volume that caches + * the statfs information in its in-memory structures should set this bit. + * A volume that must always read from disk or always perform a network + * transaction should not set this bit. + * + * VOL_CAP_FMT_2TB_FILESIZE: If this bit is set the volume format supports + * file sizes larger than 4GB, and potentially up to 2TB; it does not + * indicate whether the filesystem supports files larger than that. + * + * VOL_CAP_FMT_OPENDENYMODES: When set, the volume supports open deny + * modes (e.g. "open for read write, deny write"; effectively, mandatory + * file locking based on open modes). + * + * VOL_CAP_FMT_HIDDEN_FILES: When set, the volume supports the UF_HIDDEN + * file flag, and the UF_HIDDEN flag is mapped to that volume's native + * "hidden" or "invisible" bit (which may be the invisible bit from the + * Finder Info extended attribute). + * + * VOL_CAP_FMT_PATH_FROM_ID: When set, the volume supports the ability + * to derive a pathname to the root of the file system given only the + * id of an object. This also implies that object ids on this file + * system are persistent and not recycled. This is a very specialized + * capability and it is assumed that most file systems will not support + * it. Its use is for legacy non-posix APIs like ResolveFileIDRef. + * + * VOL_CAP_FMT_NO_VOLUME_SIZES: When set, the volume does not support + * returning values for total data blocks, available blocks, or free blocks + * (as in f_blocks, f_bavail, or f_bfree in "struct statfs"). Historically, + * those values were set to 0xFFFFFFFF for volumes that did not support them. + * + * VOL_CAP_FMT_DECMPFS_COMPRESSION: When set, the volume supports transparent + * decompression of compressed files using decmpfs. + * + * VOL_CAP_FMT_64BIT_OBJECT_IDS: When set, the volume uses object IDs that + * are 64-bit. This means that ATTR_CMN_FILEID and ATTR_CMN_PARENTID are the + * only legitimate attributes for obtaining object IDs from this volume and the + * 32-bit fid_objno fields of the fsobj_id_t returned by ATTR_CMN_OBJID, + * ATTR_CMN_OBJPERMID, and ATTR_CMN_PAROBJID are undefined. + * + * VOL_CAP_FMT_DIR_HARDLINKS: When set, the volume supports directory + * hard links. + * + * VOL_CAP_FMT_DOCUMENT_ID: When set, the volume supports document IDs + * (an ID which persists across object ID changes) for document revisions. + * + * VOL_CAP_FMT_WRITE_GENERATION_COUNT: When set, the volume supports write + * generation counts (a count of how many times an object has been modified) + * + * VOL_CAP_FMT_NO_IMMUTABLE_FILES: When set, the volume does not support + * setting the UF_IMMUTABLE flag. + * + * VOL_CAP_FMT_NO_PERMISSIONS: When set, the volume does not support setting + * permissions. + * + * VOL_CAP_FMT_SHARED_SPACE: When set, the volume supports sharing space with + * other filesystems i.e. multiple logical filesystems can exist in the same + * "partition". An implication of this is that the filesystem which sets + * this capability treats waitfor arguments to VFS_SYNC as bit flags. + * + * VOL_CAP_FMT_VOL_GROUPS: When set, this volume is part of a volume-group + * that implies multiple volumes must be mounted in order to boot and root the + * operating system. Typically, this means a read-only system volume and a + * writable data volume. + * + * VOL_CAP_FMT_SEALED: When set, this volume is cryptographically sealed. + * Any modifications to volume data or metadata will be detected and may + * render the volume unusable. + */ +#define VOL_CAP_FMT_PERSISTENTOBJECTIDS 0x00000001 +#define VOL_CAP_FMT_SYMBOLICLINKS 0x00000002 +#define VOL_CAP_FMT_HARDLINKS 0x00000004 +#define VOL_CAP_FMT_JOURNAL 0x00000008 +#define VOL_CAP_FMT_JOURNAL_ACTIVE 0x00000010 +#define VOL_CAP_FMT_NO_ROOT_TIMES 0x00000020 +#define VOL_CAP_FMT_SPARSE_FILES 0x00000040 +#define VOL_CAP_FMT_ZERO_RUNS 0x00000080 +#define VOL_CAP_FMT_CASE_SENSITIVE 0x00000100 +#define VOL_CAP_FMT_CASE_PRESERVING 0x00000200 +#define VOL_CAP_FMT_FAST_STATFS 0x00000400 +#define VOL_CAP_FMT_2TB_FILESIZE 0x00000800 +#define VOL_CAP_FMT_OPENDENYMODES 0x00001000 +#define VOL_CAP_FMT_HIDDEN_FILES 0x00002000 +#define VOL_CAP_FMT_PATH_FROM_ID 0x00004000 +#define VOL_CAP_FMT_NO_VOLUME_SIZES 0x00008000 +#define VOL_CAP_FMT_DECMPFS_COMPRESSION 0x00010000 +#define VOL_CAP_FMT_64BIT_OBJECT_IDS 0x00020000 +#define VOL_CAP_FMT_DIR_HARDLINKS 0x00040000 +#define VOL_CAP_FMT_DOCUMENT_ID 0x00080000 +#define VOL_CAP_FMT_WRITE_GENERATION_COUNT 0x00100000 +#define VOL_CAP_FMT_NO_IMMUTABLE_FILES 0x00200000 +#define VOL_CAP_FMT_NO_PERMISSIONS 0x00400000 +#define VOL_CAP_FMT_SHARED_SPACE 0x00800000 +#define VOL_CAP_FMT_VOL_GROUPS 0x01000000 +#define VOL_CAP_FMT_SEALED 0x02000000 + +/* + * VOL_CAP_INT_SEARCHFS: When set, the volume implements the + * searchfs() system call (the vnop_searchfs vnode operation). + * + * VOL_CAP_INT_ATTRLIST: When set, the volume implements the + * getattrlist() and setattrlist() system calls (vnop_getattrlist + * and vnop_setattrlist vnode operations) for the volume, files, + * and directories. The volume may or may not implement the + * readdirattr() system call. XXX Is there any minimum set + * of attributes that should be supported? To determine the + * set of supported attributes, get the ATTR_VOL_ATTRIBUTES + * attribute of the volume. + * + * VOL_CAP_INT_NFSEXPORT: When set, the volume implements exporting + * of NFS volumes. + * + * VOL_CAP_INT_READDIRATTR: When set, the volume implements the + * readdirattr() system call (vnop_readdirattr vnode operation). + * + * VOL_CAP_INT_EXCHANGEDATA: When set, the volume implements the + * exchangedata() system call (VNOP_EXCHANGE vnode operation). + * + * VOL_CAP_INT_COPYFILE: When set, the volume implements the + * VOP_COPYFILE vnode operation. (XXX There should be a copyfile() + * system call in .) + * + * VOL_CAP_INT_ALLOCATE: When set, the volume implements the + * VNOP_ALLOCATE vnode operation, which means it implements the + * F_PREALLOCATE selector of fcntl(2). + * + * VOL_CAP_INT_VOL_RENAME: When set, the volume implements the + * ATTR_VOL_NAME attribute for both getattrlist() and setattrlist(). + * The volume can be renamed by setting ATTR_VOL_NAME with setattrlist(). + * + * VOL_CAP_INT_ADVLOCK: When set, the volume implements POSIX style + * byte range locks via vnop_advlock (accessible from fcntl(2)). + * + * VOL_CAP_INT_FLOCK: When set, the volume implements whole-file flock(2) + * style locks via vnop_advlock. This includes the O_EXLOCK and O_SHLOCK + * flags of the open(2) call. + * + * VOL_CAP_INT_EXTENDED_SECURITY: When set, the volume implements + * extended security (ACLs). + * + * VOL_CAP_INT_USERACCESS: When set, the volume supports the + * ATTR_CMN_USERACCESS attribute (used to get the user's access + * mode to the file). + * + * VOL_CAP_INT_MANLOCK: When set, the volume supports AFP-style + * mandatory byte range locks via an ioctl(). + * + * VOL_CAP_INT_EXTENDED_ATTR: When set, the volume implements + * native extended attribues. + * + * VOL_CAP_INT_NAMEDSTREAMS: When set, the volume supports + * native named streams. + * + * VOL_CAP_INT_CLONE: When set, the volume supports clones. + * + * VOL_CAP_INT_SNAPSHOT: When set, the volume supports snapshots. + * + * VOL_CAP_INT_RENAME_SWAP: When set, the volume supports swapping + * file system objects. + * + * VOL_CAP_INT_RENAME_EXCL: When set, the volume supports an + * exclusive rename operation. + * + * VOL_CAP_INT_RENAME_OPENFAIL: When set, the volume may fail rename + * operations on files that are open. + */ +#define VOL_CAP_INT_SEARCHFS 0x00000001 +#define VOL_CAP_INT_ATTRLIST 0x00000002 +#define VOL_CAP_INT_NFSEXPORT 0x00000004 +#define VOL_CAP_INT_READDIRATTR 0x00000008 +#define VOL_CAP_INT_EXCHANGEDATA 0x00000010 +#define VOL_CAP_INT_COPYFILE 0x00000020 +#define VOL_CAP_INT_ALLOCATE 0x00000040 +#define VOL_CAP_INT_VOL_RENAME 0x00000080 +#define VOL_CAP_INT_ADVLOCK 0x00000100 +#define VOL_CAP_INT_FLOCK 0x00000200 +#define VOL_CAP_INT_EXTENDED_SECURITY 0x00000400 +#define VOL_CAP_INT_USERACCESS 0x00000800 +#define VOL_CAP_INT_MANLOCK 0x00001000 +#define VOL_CAP_INT_NAMEDSTREAMS 0x00002000 +#define VOL_CAP_INT_EXTENDED_ATTR 0x00004000 +#define VOL_CAP_INT_CLONE 0x00010000 +#define VOL_CAP_INT_SNAPSHOT 0x00020000 +#define VOL_CAP_INT_RENAME_SWAP 0x00040000 +#define VOL_CAP_INT_RENAME_EXCL 0x00080000 +#define VOL_CAP_INT_RENAME_OPENFAIL 0x00100000 + +typedef struct vol_attributes_attr { + attribute_set_t validattr; + attribute_set_t nativeattr; +} vol_attributes_attr_t; + +#define ATTR_CMN_NAME 0x00000001 +#define ATTR_CMN_DEVID 0x00000002 +#define ATTR_CMN_FSID 0x00000004 +#define ATTR_CMN_OBJTYPE 0x00000008 +#define ATTR_CMN_OBJTAG 0x00000010 +#define ATTR_CMN_OBJID 0x00000020 +#define ATTR_CMN_OBJPERMANENTID 0x00000040 +#define ATTR_CMN_PAROBJID 0x00000080 +#define ATTR_CMN_SCRIPT 0x00000100 +#define ATTR_CMN_CRTIME 0x00000200 +#define ATTR_CMN_MODTIME 0x00000400 +#define ATTR_CMN_CHGTIME 0x00000800 +#define ATTR_CMN_ACCTIME 0x00001000 +#define ATTR_CMN_BKUPTIME 0x00002000 +#define ATTR_CMN_FNDRINFO 0x00004000 +#define ATTR_CMN_OWNERID 0x00008000 +#define ATTR_CMN_GRPID 0x00010000 +#define ATTR_CMN_ACCESSMASK 0x00020000 +#define ATTR_CMN_FLAGS 0x00040000 + +/* The following were defined as: */ +/* #define ATTR_CMN_NAMEDATTRCOUNT 0x00080000 */ +/* #define ATTR_CMN_NAMEDATTRLIST 0x00100000 */ +/* These bits have been salvaged for use as: */ +/* #define ATTR_CMN_GEN_COUNT 0x00080000 */ +/* #define ATTR_CMN_DOCUMENT_ID 0x00100000 */ +/* They can only be used with the FSOPT_ATTR_CMN_EXTENDED */ +/* option flag. */ + +#define ATTR_CMN_GEN_COUNT 0x00080000 +#define ATTR_CMN_DOCUMENT_ID 0x00100000 + +#define ATTR_CMN_USERACCESS 0x00200000 +#define ATTR_CMN_EXTENDED_SECURITY 0x00400000 +#define ATTR_CMN_UUID 0x00800000 +#define ATTR_CMN_GRPUUID 0x01000000 +#define ATTR_CMN_FILEID 0x02000000 +#define ATTR_CMN_PARENTID 0x04000000 +#define ATTR_CMN_FULLPATH 0x08000000 +#define ATTR_CMN_ADDEDTIME 0x10000000 +#define ATTR_CMN_ERROR 0x20000000 +#define ATTR_CMN_DATA_PROTECT_FLAGS 0x40000000 + +/* + * ATTR_CMN_RETURNED_ATTRS is only valid with getattrlist(2) and + * getattrlistbulk(2). It is always the first attribute in the return buffer. + */ +#define ATTR_CMN_RETURNED_ATTRS 0x80000000 + +#define ATTR_CMN_VALIDMASK 0xFFFFFFFF +/* + * The settable ATTR_CMN_* attributes include the following: + * ATTR_CMN_SCRIPT + * ATTR_CMN_CRTIME + * ATTR_CMN_MODTIME + * ATTR_CMN_CHGTIME + * + * ATTR_CMN_ACCTIME + * ATTR_CMN_BKUPTIME + * ATTR_CMN_FNDRINFO + * ATTR_CMN_OWNERID + * + * ATTR_CMN_GRPID + * ATTR_CMN_ACCESSMASK + * ATTR_CMN_FLAGS + * + * ATTR_CMN_EXTENDED_SECURITY + * ATTR_CMN_UUID + * + * ATTR_CMN_GRPUUID + * + * ATTR_CMN_DATA_PROTECT_FLAGS + */ +#define ATTR_CMN_SETMASK 0x51C7FF00 +#define ATTR_CMN_VOLSETMASK 0x00006700 + +#define ATTR_VOL_FSTYPE 0x00000001 +#define ATTR_VOL_SIGNATURE 0x00000002 +#define ATTR_VOL_SIZE 0x00000004 +#define ATTR_VOL_SPACEFREE 0x00000008 +#define ATTR_VOL_SPACEAVAIL 0x00000010 +#define ATTR_VOL_MINALLOCATION 0x00000020 +#define ATTR_VOL_ALLOCATIONCLUMP 0x00000040 +#define ATTR_VOL_IOBLOCKSIZE 0x00000080 +#define ATTR_VOL_OBJCOUNT 0x00000100 +#define ATTR_VOL_FILECOUNT 0x00000200 +#define ATTR_VOL_DIRCOUNT 0x00000400 +#define ATTR_VOL_MAXOBJCOUNT 0x00000800 +#define ATTR_VOL_MOUNTPOINT 0x00001000 +#define ATTR_VOL_NAME 0x00002000 +#define ATTR_VOL_MOUNTFLAGS 0x00004000 +#define ATTR_VOL_MOUNTEDDEVICE 0x00008000 +#define ATTR_VOL_ENCODINGSUSED 0x00010000 +#define ATTR_VOL_CAPABILITIES 0x00020000 +#define ATTR_VOL_UUID 0x00040000 +#define ATTR_VOL_FSTYPENAME 0x00100000 +#define ATTR_VOL_FSSUBTYPE 0x00200000 +#define ATTR_VOL_SPACEUSED 0x00800000 +#define ATTR_VOL_QUOTA_SIZE 0x10000000 +#define ATTR_VOL_RESERVED_SIZE 0x20000000 +#define ATTR_VOL_ATTRIBUTES 0x40000000 +#define ATTR_VOL_INFO 0x80000000 + +#define ATTR_VOL_VALIDMASK 0xF0B7FFFF + +/* + * The list of settable ATTR_VOL_* attributes include the following: + * ATTR_VOL_NAME + * ATTR_VOL_INFO + */ +#define ATTR_VOL_SETMASK 0x80002000 + + +/* File/directory attributes: */ +#define ATTR_DIR_LINKCOUNT 0x00000001 +#define ATTR_DIR_ENTRYCOUNT 0x00000002 +#define ATTR_DIR_MOUNTSTATUS 0x00000004 +#define ATTR_DIR_ALLOCSIZE 0x00000008 +#define ATTR_DIR_IOBLOCKSIZE 0x00000010 +#define ATTR_DIR_DATALENGTH 0x00000020 + +/* ATTR_DIR_MOUNTSTATUS Flags: */ +#define DIR_MNTSTATUS_MNTPOINT 0x00000001 +#define DIR_MNTSTATUS_TRIGGER 0x00000002 + +#define ATTR_DIR_VALIDMASK 0x0000003f +#define ATTR_DIR_SETMASK 0x00000000 + +#define ATTR_FILE_LINKCOUNT 0x00000001 +#define ATTR_FILE_TOTALSIZE 0x00000002 +#define ATTR_FILE_ALLOCSIZE 0x00000004 +#define ATTR_FILE_IOBLOCKSIZE 0x00000008 +#define ATTR_FILE_DEVTYPE 0x00000020 +#define ATTR_FILE_FORKCOUNT 0x00000080 +#define ATTR_FILE_FORKLIST 0x00000100 +#define ATTR_FILE_DATALENGTH 0x00000200 +#define ATTR_FILE_DATAALLOCSIZE 0x00000400 +#define ATTR_FILE_RSRCLENGTH 0x00001000 +#define ATTR_FILE_RSRCALLOCSIZE 0x00002000 + +#define ATTR_FILE_VALIDMASK 0x000037FF +/* + * Settable ATTR_FILE_* attributes include: + * ATTR_FILE_DEVTYPE + */ +#define ATTR_FILE_SETMASK 0x00000020 + +/* CMNEXT attributes extend the common attributes, but in the forkattr field */ +#define ATTR_CMNEXT_RELPATH 0x00000004 +#define ATTR_CMNEXT_PRIVATESIZE 0x00000008 +#define ATTR_CMNEXT_LINKID 0x00000010 +#define ATTR_CMNEXT_NOFIRMLINKPATH 0x00000020 +#define ATTR_CMNEXT_REALDEVID 0x00000040 +#define ATTR_CMNEXT_REALFSID 0x00000080 +#define ATTR_CMNEXT_CLONEID 0x00000100 +#define ATTR_CMNEXT_EXT_FLAGS 0x00000200 +#define ATTR_CMNEXT_RECURSIVE_GENCOUNT 0x00000400 + +#define ATTR_CMNEXT_VALIDMASK 0x000007fc +#define ATTR_CMNEXT_SETMASK 0x00000000 + +/* Deprecated fork attributes */ +#define ATTR_FORK_TOTALSIZE 0x00000001 +#define ATTR_FORK_ALLOCSIZE 0x00000002 +#define ATTR_FORK_RESERVED 0xffffffff + +#define ATTR_FORK_VALIDMASK 0x00000003 +#define ATTR_FORK_SETMASK 0x00000000 + +/* Obsolete, implemented, not supported */ +#define ATTR_CMN_NAMEDATTRCOUNT 0x00080000 +#define ATTR_CMN_NAMEDATTRLIST 0x00100000 +#define ATTR_FILE_CLUMPSIZE 0x00000010 /* obsolete */ +#define ATTR_FILE_FILETYPE 0x00000040 /* always zero */ +#define ATTR_FILE_DATAEXTENTS 0x00000800 /* obsolete, HFS-specific */ +#define ATTR_FILE_RSRCEXTENTS 0x00004000 /* obsolete, HFS-specific */ + +/* Required attributes for getattrlistbulk(2) */ +#define ATTR_BULK_REQUIRED (ATTR_CMN_NAME | ATTR_CMN_RETURNED_ATTRS) + +/* + * Searchfs + */ +#define SRCHFS_START 0x00000001 +#define SRCHFS_MATCHPARTIALNAMES 0x00000002 +#define SRCHFS_MATCHDIRS 0x00000004 +#define SRCHFS_MATCHFILES 0x00000008 +#define SRCHFS_SKIPLINKS 0x00000010 +#define SRCHFS_SKIPINVISIBLE 0x00000020 +#define SRCHFS_SKIPPACKAGES 0x00000040 +#define SRCHFS_SKIPINAPPROPRIATE 0x00000080 + +#define SRCHFS_NEGATEPARAMS 0x80000000 +#define SRCHFS_VALIDOPTIONSMASK 0x800000FF + +struct fssearchblock { + struct attrlist *returnattrs; + void *returnbuffer; + size_t returnbuffersize; + u_long maxmatches; + struct timeval timelimit; + void *searchparams1; + size_t sizeofsearchparams1; + void *searchparams2; + size_t sizeofsearchparams2; + struct attrlist searchattrs; +}; + + +struct searchstate { + uint32_t ss_union_flags; // for SRCHFS_START + uint32_t ss_union_layer; // 0 = top + u_char ss_fsstate[548]; // fs private +} __attribute__((packed)); + +#define FST_EOF (-1) /* end-of-file offset */ + +#endif /* __APPLE_API_UNSTABLE */ +#endif /* !_SYS_ATTR_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/sys/mman.h b/lib/libc/include/any-macos.13-any/sys/mman.h new file mode 100644 index 0000000000..e1f72a0c7f --- /dev/null +++ b/lib/libc/include/any-macos.13-any/sys/mman.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2000-2020 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ +/*- + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)mman.h 8.1 (Berkeley) 6/2/93 + */ + +/* + * Currently unsupported: + * + * [TYM] POSIX_TYPED_MEM_ALLOCATE + * [TYM] POSIX_TYPED_MEM_ALLOCATE_CONTIG + * [TYM] POSIX_TYPED_MEM_MAP_ALLOCATABLE + * [TYM] struct posix_typed_mem_info + * [TYM] posix_mem_offset() + * [TYM] posix_typed_mem_get_info() + * [TYM] posix_typed_mem_open() + */ + +#ifndef _SYS_MMAN_H_ +#define _SYS_MMAN_H_ + +#include +#include + +#include + +/* + * [various] The mode_t, off_t, and size_t types shall be defined as + * described in + */ +#include +#include +#include + +#if __DARWIN_C_LEVEL >= 200809L +#include +#endif /* __DARWIN_C_LEVEL */ + +/* + * Protections are chosen from these bits, or-ed together + */ +#define PROT_NONE 0x00 /* [MC2] no permissions */ +#define PROT_READ 0x01 /* [MC2] pages can be read */ +#define PROT_WRITE 0x02 /* [MC2] pages can be written */ +#define PROT_EXEC 0x04 /* [MC2] pages can be executed */ + +/* + * Flags contain sharing type and options. + * Sharing types; choose one. + */ +#define MAP_SHARED 0x0001 /* [MF|SHM] share changes */ +#define MAP_PRIVATE 0x0002 /* [MF|SHM] changes are private */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define MAP_COPY MAP_PRIVATE /* Obsolete */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * Other flags + */ +#define MAP_FIXED 0x0010 /* [MF|SHM] interpret addr exactly */ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define MAP_RENAME 0x0020 /* Sun: rename private pages to file */ +#define MAP_NORESERVE 0x0040 /* Sun: don't reserve needed swap area */ +#define MAP_RESERVED0080 0x0080 /* previously unimplemented MAP_INHERIT */ +#define MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change file size */ +#define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */ +#define MAP_NOCACHE 0x0400 /* don't cache pages for this mapping */ +#define MAP_JIT 0x0800 /* Allocate a region that will be used for JIT purposes */ + +/* + * Mapping type + */ +#define MAP_FILE 0x0000 /* map from file (default) */ +#define MAP_ANON 0x1000 /* allocated from memory, swap space */ +#define MAP_ANONYMOUS MAP_ANON + +/* + * The MAP_RESILIENT_* flags can be used when the caller wants to map some + * possibly unreliable memory and be able to access it safely, possibly + * getting the wrong contents rather than raising any exception. + * For safety reasons, such mappings have to be read-only (PROT_READ access + * only). + * + * MAP_RESILIENT_CODESIGN: + * accessing this mapping will not generate code-signing violations, + * even if the contents are tainted. + * MAP_RESILIENT_MEDIA: + * accessing this mapping will not generate an exception if the contents + * are not available (unreachable removable or remote media, access beyond + * end-of-file, ...). Missing contents will be replaced with zeroes. + */ +#define MAP_RESILIENT_CODESIGN 0x2000 /* no code-signing failures */ +#define MAP_RESILIENT_MEDIA 0x4000 /* no backing-store failures */ + +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500 +#define MAP_32BIT 0x8000 /* Return virtual addresses <4G only */ +#endif /* defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500 */ + + +/* + * Flags used to support translated processes. + */ +#define MAP_TRANSLATED_ALLOW_EXECUTE 0x20000 /* allow execute in translated processes */ + +#define MAP_UNIX03 0x40000 /* UNIX03 compliance */ + +#define MAP_TPRO 0x80000 /* Allocate a region that will be protected by TPRO */ + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +/* + * Process memory locking + */ +#define MCL_CURRENT 0x0001 /* [ML] Lock only current memory */ +#define MCL_FUTURE 0x0002 /* [ML] Lock all future memory as well */ + +/* + * Error return from mmap() + */ +#define MAP_FAILED ((void *)-1) /* [MF|SHM] mmap failed */ + +/* + * msync() flags + */ +#define MS_ASYNC 0x0001 /* [MF|SIO] return immediately */ +#define MS_INVALIDATE 0x0002 /* [MF|SIO] invalidate all cached data */ +#define MS_SYNC 0x0010 /* [MF|SIO] msync synchronously */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define MS_KILLPAGES 0x0004 /* invalidate pages, leave mapped */ +#define MS_DEACTIVATE 0x0008 /* deactivate pages, leave mapped */ + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + + +/* + * Advice to madvise + */ +#define POSIX_MADV_NORMAL 0 /* [MC1] no further special treatment */ +#define POSIX_MADV_RANDOM 1 /* [MC1] expect random page refs */ +#define POSIX_MADV_SEQUENTIAL 2 /* [MC1] expect sequential page refs */ +#define POSIX_MADV_WILLNEED 3 /* [MC1] will need these pages */ +#define POSIX_MADV_DONTNEED 4 /* [MC1] dont need these pages */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define MADV_NORMAL POSIX_MADV_NORMAL +#define MADV_RANDOM POSIX_MADV_RANDOM +#define MADV_SEQUENTIAL POSIX_MADV_SEQUENTIAL +#define MADV_WILLNEED POSIX_MADV_WILLNEED +#define MADV_DONTNEED POSIX_MADV_DONTNEED +#define MADV_FREE 5 /* pages unneeded, discard contents */ +#define MADV_ZERO_WIRED_PAGES 6 /* zero the wired pages that have not been unwired before the entry is deleted */ +#define MADV_FREE_REUSABLE 7 /* pages can be reused (by anyone) */ +#define MADV_FREE_REUSE 8 /* caller wants to reuse those pages */ +#define MADV_CAN_REUSE 9 +#define MADV_PAGEOUT 10 /* page out now (internal only) */ + +/* + * Return bits from mincore + */ +#define MINCORE_INCORE 0x1 /* Page is incore */ +#define MINCORE_REFERENCED 0x2 /* Page has been referenced by us */ +#define MINCORE_MODIFIED 0x4 /* Page has been modified by us */ +#define MINCORE_REFERENCED_OTHER 0x8 /* Page has been referenced */ +#define MINCORE_MODIFIED_OTHER 0x10 /* Page has been modified */ +#define MINCORE_PAGED_OUT 0x20 /* Page has been paged out */ +#define MINCORE_COPIED 0x40 /* Page has been copied */ +#define MINCORE_ANONYMOUS 0x80 /* Page belongs to an anonymous object */ +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + + + + +__BEGIN_DECLS +/* [ML] */ +int mlockall(int); +int munlockall(void); +/* [MR] */ +int mlock(const void *, size_t); +#ifndef _MMAP +#define _MMAP +/* [MC3]*/ +void * mmap(void *, size_t, int, int, int, off_t) __DARWIN_ALIAS(mmap); +#endif +/* [MPR] */ +int mprotect(void *, size_t, int) __DARWIN_ALIAS(mprotect); +/* [MF|SIO] */ +int msync(void *, size_t, int) __DARWIN_ALIAS_C(msync); +/* [MR] */ +int munlock(const void *, size_t); +/* [MC3]*/ +int munmap(void *, size_t) __DARWIN_ALIAS(munmap); +/* [SHM] */ +int shm_open(const char *, int, ...); +int shm_unlink(const char *); +/* [ADV] */ +int posix_madvise(void *, size_t, int); + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +int madvise(void *, size_t, int); +int mincore(const void *, size_t, char *); +int minherit(void *, size_t, int); +#endif + + +__END_DECLS + +#endif /* !_SYS_MMAN_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/sys/mount.h b/lib/libc/include/any-macos.13-any/sys/mount.h index 21b9bf3c12..ed19e82456 100644 --- a/lib/libc/include/any-macos.13-any/sys/mount.h +++ b/lib/libc/include/any-macos.13-any/sys/mount.h @@ -404,12 +404,27 @@ struct fhandle { }; typedef struct fhandle fhandle_t; +/* + * Cryptex authentication + * Note: these 2 enums are used in conjunction, graftdmg_type is used for authentication while grafting + * cryptexes and cryptex_auth_type is currently used for authentication while mounting generic + * cryptexes. We need to make sure we do not use the reserved values in each for a new authentication type. + */ + OS_ENUM(graftdmg_type, uint32_t, GRAFTDMG_CRYPTEX_BOOT = 1, GRAFTDMG_CRYPTEX_PREBOOT = 2, - GRAFTDMG_CRYPTEX_DOWNLEVEL = 3); - + GRAFTDMG_CRYPTEX_DOWNLEVEL = 3 + // Reserved: CRYPTEX1_AUTH_ENV_GENERIC = 4, + // Reserved: CRYPTEX1_AUTH_ENV_GENERIC_SUPPLEMENTAL = 5 + ); +OS_ENUM(cryptex_auth_type, uint32_t, + // Reserved: GRAFTDMG_CRYPTEX_BOOT = 1, + // Reserved: GRAFTDMG_CRYPTEX_PREBOOT = 2, + // Reserved: GRAFTDMG_CRYPTEX_DOWNLEVEL = 3, + CRYPTEX1_AUTH_ENV_GENERIC = 4, + CRYPTEX1_AUTH_ENV_GENERIC_SUPPLEMENTAL = 5); __BEGIN_DECLS diff --git a/lib/libc/include/any-macos.13-any/tgmath.h b/lib/libc/include/any-macos.13-any/tgmath.h new file mode 100644 index 0000000000..850374aa74 --- /dev/null +++ b/lib/libc/include/any-macos.13-any/tgmath.h @@ -0,0 +1,1381 @@ +/* + * Copyright (c) 2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __TGMATH_H +#define __TGMATH_H + +/* C99 7.22 Type-generic math . */ +#include + +/* C++ handles type genericity with overloading in math.h. */ +#ifndef __cplusplus +#include + +#if __has_include() +#include +REALTIME_SAFE_BEGIN +#endif + +#define _TG_ATTRSp __attribute__((__overloadable__)) +#define _TG_ATTRS __attribute__((__overloadable__, __always_inline__)) + +// promotion + +typedef void _Argument_type_is_not_arithmetic; +static _Argument_type_is_not_arithmetic __tg_promote(...) + __attribute__((__unavailable__,__overloadable__)); +static double _TG_ATTRSp __tg_promote(int); +static double _TG_ATTRSp __tg_promote(unsigned int); +static double _TG_ATTRSp __tg_promote(long); +static double _TG_ATTRSp __tg_promote(unsigned long); +static double _TG_ATTRSp __tg_promote(long long); +static double _TG_ATTRSp __tg_promote(unsigned long long); +static float _TG_ATTRSp __tg_promote(float); +static double _TG_ATTRSp __tg_promote(double); +static long double _TG_ATTRSp __tg_promote(long double); +static float _Complex _TG_ATTRSp __tg_promote(float _Complex); +static double _Complex _TG_ATTRSp __tg_promote(double _Complex); +static long double _Complex _TG_ATTRSp __tg_promote(long double _Complex); + +#define __tg_promote1(__x) (__typeof__(__tg_promote(__x))) +#define __tg_promote2(__x, __y) (__typeof__(__tg_promote(__x) + \ + __tg_promote(__y))) +#define __tg_promote3(__x, __y, __z) (__typeof__(__tg_promote(__x) + \ + __tg_promote(__y) + \ + __tg_promote(__z))) + +// acos + +static float + _TG_ATTRS + __tg_acos(float __x) {return acosf(__x);} + +static double + _TG_ATTRS + __tg_acos(double __x) {return acos(__x);} + +static long double + _TG_ATTRS + __tg_acos(long double __x) {return acosl(__x);} + +static float _Complex + _TG_ATTRS + __tg_acos(float _Complex __x) {return cacosf(__x);} + +static double _Complex + _TG_ATTRS + __tg_acos(double _Complex __x) {return cacos(__x);} + +static long double _Complex + _TG_ATTRS + __tg_acos(long double _Complex __x) {return cacosl(__x);} + +#undef acos +#define acos(__x) __tg_acos(__tg_promote1((__x))(__x)) + +// asin + +static float + _TG_ATTRS + __tg_asin(float __x) {return asinf(__x);} + +static double + _TG_ATTRS + __tg_asin(double __x) {return asin(__x);} + +static long double + _TG_ATTRS + __tg_asin(long double __x) {return asinl(__x);} + +static float _Complex + _TG_ATTRS + __tg_asin(float _Complex __x) {return casinf(__x);} + +static double _Complex + _TG_ATTRS + __tg_asin(double _Complex __x) {return casin(__x);} + +static long double _Complex + _TG_ATTRS + __tg_asin(long double _Complex __x) {return casinl(__x);} + +#undef asin +#define asin(__x) __tg_asin(__tg_promote1((__x))(__x)) + +// atan + +static float + _TG_ATTRS + __tg_atan(float __x) {return atanf(__x);} + +static double + _TG_ATTRS + __tg_atan(double __x) {return atan(__x);} + +static long double + _TG_ATTRS + __tg_atan(long double __x) {return atanl(__x);} + +static float _Complex + _TG_ATTRS + __tg_atan(float _Complex __x) {return catanf(__x);} + +static double _Complex + _TG_ATTRS + __tg_atan(double _Complex __x) {return catan(__x);} + +static long double _Complex + _TG_ATTRS + __tg_atan(long double _Complex __x) {return catanl(__x);} + +#undef atan +#define atan(__x) __tg_atan(__tg_promote1((__x))(__x)) + +// acosh + +static float + _TG_ATTRS + __tg_acosh(float __x) {return acoshf(__x);} + +static double + _TG_ATTRS + __tg_acosh(double __x) {return acosh(__x);} + +static long double + _TG_ATTRS + __tg_acosh(long double __x) {return acoshl(__x);} + +static float _Complex + _TG_ATTRS + __tg_acosh(float _Complex __x) {return cacoshf(__x);} + +static double _Complex + _TG_ATTRS + __tg_acosh(double _Complex __x) {return cacosh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_acosh(long double _Complex __x) {return cacoshl(__x);} + +#undef acosh +#define acosh(__x) __tg_acosh(__tg_promote1((__x))(__x)) + +// asinh + +static float + _TG_ATTRS + __tg_asinh(float __x) {return asinhf(__x);} + +static double + _TG_ATTRS + __tg_asinh(double __x) {return asinh(__x);} + +static long double + _TG_ATTRS + __tg_asinh(long double __x) {return asinhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_asinh(float _Complex __x) {return casinhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_asinh(double _Complex __x) {return casinh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_asinh(long double _Complex __x) {return casinhl(__x);} + +#undef asinh +#define asinh(__x) __tg_asinh(__tg_promote1((__x))(__x)) + +// atanh + +static float + _TG_ATTRS + __tg_atanh(float __x) {return atanhf(__x);} + +static double + _TG_ATTRS + __tg_atanh(double __x) {return atanh(__x);} + +static long double + _TG_ATTRS + __tg_atanh(long double __x) {return atanhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_atanh(float _Complex __x) {return catanhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_atanh(double _Complex __x) {return catanh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_atanh(long double _Complex __x) {return catanhl(__x);} + +#undef atanh +#define atanh(__x) __tg_atanh(__tg_promote1((__x))(__x)) + +// cos + +static float + _TG_ATTRS + __tg_cos(float __x) {return cosf(__x);} + +static double + _TG_ATTRS + __tg_cos(double __x) {return cos(__x);} + +static long double + _TG_ATTRS + __tg_cos(long double __x) {return cosl(__x);} + +static float _Complex + _TG_ATTRS + __tg_cos(float _Complex __x) {return ccosf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cos(double _Complex __x) {return ccos(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cos(long double _Complex __x) {return ccosl(__x);} + +#undef cos +#define cos(__x) __tg_cos(__tg_promote1((__x))(__x)) + +// sin + +static float + _TG_ATTRS + __tg_sin(float __x) {return sinf(__x);} + +static double + _TG_ATTRS + __tg_sin(double __x) {return sin(__x);} + +static long double + _TG_ATTRS + __tg_sin(long double __x) {return sinl(__x);} + +static float _Complex + _TG_ATTRS + __tg_sin(float _Complex __x) {return csinf(__x);} + +static double _Complex + _TG_ATTRS + __tg_sin(double _Complex __x) {return csin(__x);} + +static long double _Complex + _TG_ATTRS + __tg_sin(long double _Complex __x) {return csinl(__x);} + +#undef sin +#define sin(__x) __tg_sin(__tg_promote1((__x))(__x)) + +// tan + +static float + _TG_ATTRS + __tg_tan(float __x) {return tanf(__x);} + +static double + _TG_ATTRS + __tg_tan(double __x) {return tan(__x);} + +static long double + _TG_ATTRS + __tg_tan(long double __x) {return tanl(__x);} + +static float _Complex + _TG_ATTRS + __tg_tan(float _Complex __x) {return ctanf(__x);} + +static double _Complex + _TG_ATTRS + __tg_tan(double _Complex __x) {return ctan(__x);} + +static long double _Complex + _TG_ATTRS + __tg_tan(long double _Complex __x) {return ctanl(__x);} + +#undef tan +#define tan(__x) __tg_tan(__tg_promote1((__x))(__x)) + +// cosh + +static float + _TG_ATTRS + __tg_cosh(float __x) {return coshf(__x);} + +static double + _TG_ATTRS + __tg_cosh(double __x) {return cosh(__x);} + +static long double + _TG_ATTRS + __tg_cosh(long double __x) {return coshl(__x);} + +static float _Complex + _TG_ATTRS + __tg_cosh(float _Complex __x) {return ccoshf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cosh(double _Complex __x) {return ccosh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cosh(long double _Complex __x) {return ccoshl(__x);} + +#undef cosh +#define cosh(__x) __tg_cosh(__tg_promote1((__x))(__x)) + +// sinh + +static float + _TG_ATTRS + __tg_sinh(float __x) {return sinhf(__x);} + +static double + _TG_ATTRS + __tg_sinh(double __x) {return sinh(__x);} + +static long double + _TG_ATTRS + __tg_sinh(long double __x) {return sinhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_sinh(float _Complex __x) {return csinhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_sinh(double _Complex __x) {return csinh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_sinh(long double _Complex __x) {return csinhl(__x);} + +#undef sinh +#define sinh(__x) __tg_sinh(__tg_promote1((__x))(__x)) + +// tanh + +static float + _TG_ATTRS + __tg_tanh(float __x) {return tanhf(__x);} + +static double + _TG_ATTRS + __tg_tanh(double __x) {return tanh(__x);} + +static long double + _TG_ATTRS + __tg_tanh(long double __x) {return tanhl(__x);} + +static float _Complex + _TG_ATTRS + __tg_tanh(float _Complex __x) {return ctanhf(__x);} + +static double _Complex + _TG_ATTRS + __tg_tanh(double _Complex __x) {return ctanh(__x);} + +static long double _Complex + _TG_ATTRS + __tg_tanh(long double _Complex __x) {return ctanhl(__x);} + +#undef tanh +#define tanh(__x) __tg_tanh(__tg_promote1((__x))(__x)) + +// exp + +static float + _TG_ATTRS + __tg_exp(float __x) {return expf(__x);} + +static double + _TG_ATTRS + __tg_exp(double __x) {return exp(__x);} + +static long double + _TG_ATTRS + __tg_exp(long double __x) {return expl(__x);} + +static float _Complex + _TG_ATTRS + __tg_exp(float _Complex __x) {return cexpf(__x);} + +static double _Complex + _TG_ATTRS + __tg_exp(double _Complex __x) {return cexp(__x);} + +static long double _Complex + _TG_ATTRS + __tg_exp(long double _Complex __x) {return cexpl(__x);} + +#undef exp +#define exp(__x) __tg_exp(__tg_promote1((__x))(__x)) + +// log + +static float + _TG_ATTRS + __tg_log(float __x) {return logf(__x);} + +static double + _TG_ATTRS + __tg_log(double __x) {return log(__x);} + +static long double + _TG_ATTRS + __tg_log(long double __x) {return logl(__x);} + +static float _Complex + _TG_ATTRS + __tg_log(float _Complex __x) {return clogf(__x);} + +static double _Complex + _TG_ATTRS + __tg_log(double _Complex __x) {return clog(__x);} + +static long double _Complex + _TG_ATTRS + __tg_log(long double _Complex __x) {return clogl(__x);} + +#undef log +#define log(__x) __tg_log(__tg_promote1((__x))(__x)) + +// pow + +static float + _TG_ATTRS + __tg_pow(float __x, float __y) {return powf(__x, __y);} + +static double + _TG_ATTRS + __tg_pow(double __x, double __y) {return pow(__x, __y);} + +static long double + _TG_ATTRS + __tg_pow(long double __x, long double __y) {return powl(__x, __y);} + +static float _Complex + _TG_ATTRS + __tg_pow(float _Complex __x, float _Complex __y) {return cpowf(__x, __y);} + +static double _Complex + _TG_ATTRS + __tg_pow(double _Complex __x, double _Complex __y) {return cpow(__x, __y);} + +static long double _Complex + _TG_ATTRS + __tg_pow(long double _Complex __x, long double _Complex __y) + {return cpowl(__x, __y);} + +#undef pow +#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// sqrt + +static float + _TG_ATTRS + __tg_sqrt(float __x) {return sqrtf(__x);} + +static double + _TG_ATTRS + __tg_sqrt(double __x) {return sqrt(__x);} + +static long double + _TG_ATTRS + __tg_sqrt(long double __x) {return sqrtl(__x);} + +static float _Complex + _TG_ATTRS + __tg_sqrt(float _Complex __x) {return csqrtf(__x);} + +static double _Complex + _TG_ATTRS + __tg_sqrt(double _Complex __x) {return csqrt(__x);} + +static long double _Complex + _TG_ATTRS + __tg_sqrt(long double _Complex __x) {return csqrtl(__x);} + +#undef sqrt +#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x)) + +// fabs + +static float + _TG_ATTRS + __tg_fabs(float __x) {return fabsf(__x);} + +static double + _TG_ATTRS + __tg_fabs(double __x) {return fabs(__x);} + +static long double + _TG_ATTRS + __tg_fabs(long double __x) {return fabsl(__x);} + +static float + _TG_ATTRS + __tg_fabs(float _Complex __x) {return cabsf(__x);} + +static double + _TG_ATTRS + __tg_fabs(double _Complex __x) {return cabs(__x);} + +static long double + _TG_ATTRS + __tg_fabs(long double _Complex __x) {return cabsl(__x);} + +#undef fabs +#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x)) + +// atan2 + +static float + _TG_ATTRS + __tg_atan2(float __x, float __y) {return atan2f(__x, __y);} + +static double + _TG_ATTRS + __tg_atan2(double __x, double __y) {return atan2(__x, __y);} + +static long double + _TG_ATTRS + __tg_atan2(long double __x, long double __y) {return atan2l(__x, __y);} + +#undef atan2 +#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// cbrt + +static float + _TG_ATTRS + __tg_cbrt(float __x) {return cbrtf(__x);} + +static double + _TG_ATTRS + __tg_cbrt(double __x) {return cbrt(__x);} + +static long double + _TG_ATTRS + __tg_cbrt(long double __x) {return cbrtl(__x);} + +#undef cbrt +#define cbrt(__x) __tg_cbrt(__tg_promote1((__x))(__x)) + +// ceil + +static float + _TG_ATTRS + __tg_ceil(float __x) {return ceilf(__x);} + +static double + _TG_ATTRS + __tg_ceil(double __x) {return ceil(__x);} + +static long double + _TG_ATTRS + __tg_ceil(long double __x) {return ceill(__x);} + +#undef ceil +#define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x)) + +// copysign + +static float + _TG_ATTRS + __tg_copysign(float __x, float __y) {return copysignf(__x, __y);} + +static double + _TG_ATTRS + __tg_copysign(double __x, double __y) {return copysign(__x, __y);} + +static long double + _TG_ATTRS + __tg_copysign(long double __x, long double __y) {return copysignl(__x, __y);} + +#undef copysign +#define copysign(__x, __y) __tg_copysign(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// erf + +static float + _TG_ATTRS + __tg_erf(float __x) {return erff(__x);} + +static double + _TG_ATTRS + __tg_erf(double __x) {return erf(__x);} + +static long double + _TG_ATTRS + __tg_erf(long double __x) {return erfl(__x);} + +#undef erf +#define erf(__x) __tg_erf(__tg_promote1((__x))(__x)) + +// erfc + +static float + _TG_ATTRS + __tg_erfc(float __x) {return erfcf(__x);} + +static double + _TG_ATTRS + __tg_erfc(double __x) {return erfc(__x);} + +static long double + _TG_ATTRS + __tg_erfc(long double __x) {return erfcl(__x);} + +#undef erfc +#define erfc(__x) __tg_erfc(__tg_promote1((__x))(__x)) + +// exp2 + +static float + _TG_ATTRS + __tg_exp2(float __x) {return exp2f(__x);} + +static double + _TG_ATTRS + __tg_exp2(double __x) {return exp2(__x);} + +static long double + _TG_ATTRS + __tg_exp2(long double __x) {return exp2l(__x);} + +#undef exp2 +#define exp2(__x) __tg_exp2(__tg_promote1((__x))(__x)) + +// expm1 + +static float + _TG_ATTRS + __tg_expm1(float __x) {return expm1f(__x);} + +static double + _TG_ATTRS + __tg_expm1(double __x) {return expm1(__x);} + +static long double + _TG_ATTRS + __tg_expm1(long double __x) {return expm1l(__x);} + +#undef expm1 +#define expm1(__x) __tg_expm1(__tg_promote1((__x))(__x)) + +// fdim + +static float + _TG_ATTRS + __tg_fdim(float __x, float __y) {return fdimf(__x, __y);} + +static double + _TG_ATTRS + __tg_fdim(double __x, double __y) {return fdim(__x, __y);} + +static long double + _TG_ATTRS + __tg_fdim(long double __x, long double __y) {return fdiml(__x, __y);} + +#undef fdim +#define fdim(__x, __y) __tg_fdim(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// floor + +static float + _TG_ATTRS + __tg_floor(float __x) {return floorf(__x);} + +static double + _TG_ATTRS + __tg_floor(double __x) {return floor(__x);} + +static long double + _TG_ATTRS + __tg_floor(long double __x) {return floorl(__x);} + +#undef floor +#define floor(__x) __tg_floor(__tg_promote1((__x))(__x)) + +// fma + +static float + _TG_ATTRS + __tg_fma(float __x, float __y, float __z) + {return fmaf(__x, __y, __z);} + +static double + _TG_ATTRS + __tg_fma(double __x, double __y, double __z) + {return fma(__x, __y, __z);} + +static long double + _TG_ATTRS + __tg_fma(long double __x,long double __y, long double __z) + {return fmal(__x, __y, __z);} + +#undef fma +#define fma(__x, __y, __z) \ + __tg_fma(__tg_promote3((__x), (__y), (__z))(__x), \ + __tg_promote3((__x), (__y), (__z))(__y), \ + __tg_promote3((__x), (__y), (__z))(__z)) + +// fmax + +static float + _TG_ATTRS + __tg_fmax(float __x, float __y) {return fmaxf(__x, __y);} + +static double + _TG_ATTRS + __tg_fmax(double __x, double __y) {return fmax(__x, __y);} + +static long double + _TG_ATTRS + __tg_fmax(long double __x, long double __y) {return fmaxl(__x, __y);} + +#undef fmax +#define fmax(__x, __y) __tg_fmax(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// fmin + +static float + _TG_ATTRS + __tg_fmin(float __x, float __y) {return fminf(__x, __y);} + +static double + _TG_ATTRS + __tg_fmin(double __x, double __y) {return fmin(__x, __y);} + +static long double + _TG_ATTRS + __tg_fmin(long double __x, long double __y) {return fminl(__x, __y);} + +#undef fmin +#define fmin(__x, __y) __tg_fmin(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// fmod + +static float + _TG_ATTRS + __tg_fmod(float __x, float __y) {return fmodf(__x, __y);} + +static double + _TG_ATTRS + __tg_fmod(double __x, double __y) {return fmod(__x, __y);} + +static long double + _TG_ATTRS + __tg_fmod(long double __x, long double __y) {return fmodl(__x, __y);} + +#undef fmod +#define fmod(__x, __y) __tg_fmod(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// frexp + +static float + _TG_ATTRS + __tg_frexp(float __x, int* __y) {return frexpf(__x, __y);} + +static double + _TG_ATTRS + __tg_frexp(double __x, int* __y) {return frexp(__x, __y);} + +static long double + _TG_ATTRS + __tg_frexp(long double __x, int* __y) {return frexpl(__x, __y);} + +#undef frexp +#define frexp(__x, __y) __tg_frexp(__tg_promote1((__x))(__x), __y) + +// hypot + +static float + _TG_ATTRS + __tg_hypot(float __x, float __y) {return hypotf(__x, __y);} + +static double + _TG_ATTRS + __tg_hypot(double __x, double __y) {return hypot(__x, __y);} + +static long double + _TG_ATTRS + __tg_hypot(long double __x, long double __y) {return hypotl(__x, __y);} + +#undef hypot +#define hypot(__x, __y) __tg_hypot(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// ilogb + +static int + _TG_ATTRS + __tg_ilogb(float __x) {return ilogbf(__x);} + +static int + _TG_ATTRS + __tg_ilogb(double __x) {return ilogb(__x);} + +static int + _TG_ATTRS + __tg_ilogb(long double __x) {return ilogbl(__x);} + +#undef ilogb +#define ilogb(__x) __tg_ilogb(__tg_promote1((__x))(__x)) + +// ldexp + +static float + _TG_ATTRS + __tg_ldexp(float __x, int __y) {return ldexpf(__x, __y);} + +static double + _TG_ATTRS + __tg_ldexp(double __x, int __y) {return ldexp(__x, __y);} + +static long double + _TG_ATTRS + __tg_ldexp(long double __x, int __y) {return ldexpl(__x, __y);} + +#undef ldexp +#define ldexp(__x, __y) __tg_ldexp(__tg_promote1((__x))(__x), __y) + +// lgamma + +static float + _TG_ATTRS + __tg_lgamma(float __x) {return lgammaf(__x);} + +static double + _TG_ATTRS + __tg_lgamma(double __x) {return lgamma(__x);} + +static long double + _TG_ATTRS + __tg_lgamma(long double __x) {return lgammal(__x);} + +#undef lgamma +#define lgamma(__x) __tg_lgamma(__tg_promote1((__x))(__x)) + +// llrint + +static long long + _TG_ATTRS + __tg_llrint(float __x) {return llrintf(__x);} + +static long long + _TG_ATTRS + __tg_llrint(double __x) {return llrint(__x);} + +static long long + _TG_ATTRS + __tg_llrint(long double __x) {return llrintl(__x);} + +#undef llrint +#define llrint(__x) __tg_llrint(__tg_promote1((__x))(__x)) + +// llround + +static long long + _TG_ATTRS + __tg_llround(float __x) {return llroundf(__x);} + +static long long + _TG_ATTRS + __tg_llround(double __x) {return llround(__x);} + +static long long + _TG_ATTRS + __tg_llround(long double __x) {return llroundl(__x);} + +#undef llround +#define llround(__x) __tg_llround(__tg_promote1((__x))(__x)) + +// log10 + +static float + _TG_ATTRS + __tg_log10(float __x) {return log10f(__x);} + +static double + _TG_ATTRS + __tg_log10(double __x) {return log10(__x);} + +static long double + _TG_ATTRS + __tg_log10(long double __x) {return log10l(__x);} + +#undef log10 +#define log10(__x) __tg_log10(__tg_promote1((__x))(__x)) + +// log1p + +static float + _TG_ATTRS + __tg_log1p(float __x) {return log1pf(__x);} + +static double + _TG_ATTRS + __tg_log1p(double __x) {return log1p(__x);} + +static long double + _TG_ATTRS + __tg_log1p(long double __x) {return log1pl(__x);} + +#undef log1p +#define log1p(__x) __tg_log1p(__tg_promote1((__x))(__x)) + +// log2 + +static float + _TG_ATTRS + __tg_log2(float __x) {return log2f(__x);} + +static double + _TG_ATTRS + __tg_log2(double __x) {return log2(__x);} + +static long double + _TG_ATTRS + __tg_log2(long double __x) {return log2l(__x);} + +#undef log2 +#define log2(__x) __tg_log2(__tg_promote1((__x))(__x)) + +// logb + +static float + _TG_ATTRS + __tg_logb(float __x) {return logbf(__x);} + +static double + _TG_ATTRS + __tg_logb(double __x) {return logb(__x);} + +static long double + _TG_ATTRS + __tg_logb(long double __x) {return logbl(__x);} + +#undef logb +#define logb(__x) __tg_logb(__tg_promote1((__x))(__x)) + +// lrint + +static long + _TG_ATTRS + __tg_lrint(float __x) {return lrintf(__x);} + +static long + _TG_ATTRS + __tg_lrint(double __x) {return lrint(__x);} + +static long + _TG_ATTRS + __tg_lrint(long double __x) {return lrintl(__x);} + +#undef lrint +#define lrint(__x) __tg_lrint(__tg_promote1((__x))(__x)) + +// lround + +static long + _TG_ATTRS + __tg_lround(float __x) {return lroundf(__x);} + +static long + _TG_ATTRS + __tg_lround(double __x) {return lround(__x);} + +static long + _TG_ATTRS + __tg_lround(long double __x) {return lroundl(__x);} + +#undef lround +#define lround(__x) __tg_lround(__tg_promote1((__x))(__x)) + +// nearbyint + +static float + _TG_ATTRS + __tg_nearbyint(float __x) {return nearbyintf(__x);} + +static double + _TG_ATTRS + __tg_nearbyint(double __x) {return nearbyint(__x);} + +static long double + _TG_ATTRS + __tg_nearbyint(long double __x) {return nearbyintl(__x);} + +#undef nearbyint +#define nearbyint(__x) __tg_nearbyint(__tg_promote1((__x))(__x)) + +// nextafter + +static float + _TG_ATTRS + __tg_nextafter(float __x, float __y) {return nextafterf(__x, __y);} + +static double + _TG_ATTRS + __tg_nextafter(double __x, double __y) {return nextafter(__x, __y);} + +static long double + _TG_ATTRS + __tg_nextafter(long double __x, long double __y) {return nextafterl(__x, __y);} + +#undef nextafter +#define nextafter(__x, __y) __tg_nextafter(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// nexttoward + +static float + _TG_ATTRS + __tg_nexttoward(float __x, long double __y) {return nexttowardf(__x, __y);} + +static double + _TG_ATTRS + __tg_nexttoward(double __x, long double __y) {return nexttoward(__x, __y);} + +static long double + _TG_ATTRS + __tg_nexttoward(long double __x, long double __y) {return nexttowardl(__x, __y);} + +#undef nexttoward +#define nexttoward(__x, __y) __tg_nexttoward(__tg_promote1((__x))(__x), (__y)) + +// remainder + +static float + _TG_ATTRS + __tg_remainder(float __x, float __y) {return remainderf(__x, __y);} + +static double + _TG_ATTRS + __tg_remainder(double __x, double __y) {return remainder(__x, __y);} + +static long double + _TG_ATTRS + __tg_remainder(long double __x, long double __y) {return remainderl(__x, __y);} + +#undef remainder +#define remainder(__x, __y) __tg_remainder(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y)) + +// remquo + +static float + _TG_ATTRS + __tg_remquo(float __x, float __y, int* __z) + {return remquof(__x, __y, __z);} + +static double + _TG_ATTRS + __tg_remquo(double __x, double __y, int* __z) + {return remquo(__x, __y, __z);} + +static long double + _TG_ATTRS + __tg_remquo(long double __x,long double __y, int* __z) + {return remquol(__x, __y, __z);} + +#undef remquo +#define remquo(__x, __y, __z) \ + __tg_remquo(__tg_promote2((__x), (__y))(__x), \ + __tg_promote2((__x), (__y))(__y), \ + (__z)) + +// rint + +static float + _TG_ATTRS + __tg_rint(float __x) {return rintf(__x);} + +static double + _TG_ATTRS + __tg_rint(double __x) {return rint(__x);} + +static long double + _TG_ATTRS + __tg_rint(long double __x) {return rintl(__x);} + +#undef rint +#define rint(__x) __tg_rint(__tg_promote1((__x))(__x)) + +// round + +static float + _TG_ATTRS + __tg_round(float __x) {return roundf(__x);} + +static double + _TG_ATTRS + __tg_round(double __x) {return round(__x);} + +static long double + _TG_ATTRS + __tg_round(long double __x) {return roundl(__x);} + +#undef round +#define round(__x) __tg_round(__tg_promote1((__x))(__x)) + +// scalbn + +static float + _TG_ATTRS + __tg_scalbn(float __x, int __y) {return scalbnf(__x, __y);} + +static double + _TG_ATTRS + __tg_scalbn(double __x, int __y) {return scalbn(__x, __y);} + +static long double + _TG_ATTRS + __tg_scalbn(long double __x, int __y) {return scalbnl(__x, __y);} + +#undef scalbn +#define scalbn(__x, __y) __tg_scalbn(__tg_promote1((__x))(__x), __y) + +// scalbln + +static float + _TG_ATTRS + __tg_scalbln(float __x, long __y) {return scalblnf(__x, __y);} + +static double + _TG_ATTRS + __tg_scalbln(double __x, long __y) {return scalbln(__x, __y);} + +static long double + _TG_ATTRS + __tg_scalbln(long double __x, long __y) {return scalblnl(__x, __y);} + +#undef scalbln +#define scalbln(__x, __y) __tg_scalbln(__tg_promote1((__x))(__x), __y) + +// tgamma + +static float + _TG_ATTRS + __tg_tgamma(float __x) {return tgammaf(__x);} + +static double + _TG_ATTRS + __tg_tgamma(double __x) {return tgamma(__x);} + +static long double + _TG_ATTRS + __tg_tgamma(long double __x) {return tgammal(__x);} + +#undef tgamma +#define tgamma(__x) __tg_tgamma(__tg_promote1((__x))(__x)) + +// trunc + +static float + _TG_ATTRS + __tg_trunc(float __x) {return truncf(__x);} + +static double + _TG_ATTRS + __tg_trunc(double __x) {return trunc(__x);} + +static long double + _TG_ATTRS + __tg_trunc(long double __x) {return truncl(__x);} + +#undef trunc +#define trunc(__x) __tg_trunc(__tg_promote1((__x))(__x)) + +// carg + +static float + _TG_ATTRS + __tg_carg(float __x) {return atan2f(0.F, __x);} + +static double + _TG_ATTRS + __tg_carg(double __x) {return atan2(0., __x);} + +static long double + _TG_ATTRS + __tg_carg(long double __x) {return atan2l(0.L, __x);} + +static float + _TG_ATTRS + __tg_carg(float _Complex __x) {return cargf(__x);} + +static double + _TG_ATTRS + __tg_carg(double _Complex __x) {return carg(__x);} + +static long double + _TG_ATTRS + __tg_carg(long double _Complex __x) {return cargl(__x);} + +#undef carg +#define carg(__x) __tg_carg(__tg_promote1((__x))(__x)) + +// cimag + +static float + _TG_ATTRS + __tg_cimag(float __x) {return 0;} + +static double + _TG_ATTRS + __tg_cimag(double __x) {return 0;} + +static long double + _TG_ATTRS + __tg_cimag(long double __x) {return 0;} + +static float + _TG_ATTRS + __tg_cimag(float _Complex __x) {return cimagf(__x);} + +static double + _TG_ATTRS + __tg_cimag(double _Complex __x) {return cimag(__x);} + +static long double + _TG_ATTRS + __tg_cimag(long double _Complex __x) {return cimagl(__x);} + +#undef cimag +#define cimag(__x) __tg_cimag(__tg_promote1((__x))(__x)) + +// conj + +static float _Complex + _TG_ATTRS + __tg_conj(float __x) {return __x;} + +static double _Complex + _TG_ATTRS + __tg_conj(double __x) {return __x;} + +static long double _Complex + _TG_ATTRS + __tg_conj(long double __x) {return __x;} + +static float _Complex + _TG_ATTRS + __tg_conj(float _Complex __x) {return conjf(__x);} + +static double _Complex + _TG_ATTRS + __tg_conj(double _Complex __x) {return conj(__x);} + +static long double _Complex + _TG_ATTRS + __tg_conj(long double _Complex __x) {return conjl(__x);} + +#undef conj +#define conj(__x) __tg_conj(__tg_promote1((__x))(__x)) + +// cproj + +static float _Complex + _TG_ATTRS + __tg_cproj(float __x) {return cprojf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cproj(double __x) {return cproj(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cproj(long double __x) {return cprojl(__x);} + +static float _Complex + _TG_ATTRS + __tg_cproj(float _Complex __x) {return cprojf(__x);} + +static double _Complex + _TG_ATTRS + __tg_cproj(double _Complex __x) {return cproj(__x);} + +static long double _Complex + _TG_ATTRS + __tg_cproj(long double _Complex __x) {return cprojl(__x);} + +#undef cproj +#define cproj(__x) __tg_cproj(__tg_promote1((__x))(__x)) + +// creal + +static float + _TG_ATTRS + __tg_creal(float __x) {return __x;} + +static double + _TG_ATTRS + __tg_creal(double __x) {return __x;} + +static long double + _TG_ATTRS + __tg_creal(long double __x) {return __x;} + +static float + _TG_ATTRS + __tg_creal(float _Complex __x) {return crealf(__x);} + +static double + _TG_ATTRS + __tg_creal(double _Complex __x) {return creal(__x);} + +static long double + _TG_ATTRS + __tg_creal(long double _Complex __x) {return creall(__x);} + +#undef creal +#define creal(__x) __tg_creal(__tg_promote1((__x))(__x)) + +#undef _TG_ATTRSp +#undef _TG_ATTRS + +#if __has_include() +REALTIME_SAFE_END +#endif + +#endif /* __cplusplus */ +#endif /* __TGMATH_H */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/unistd.h b/lib/libc/include/any-macos.13-any/unistd.h new file mode 100644 index 0000000000..9828b1ba2d --- /dev/null +++ b/lib/libc/include/any-macos.13-any/unistd.h @@ -0,0 +1,791 @@ +/* + * Copyright (c) 2000, 2002-2006, 2008-2010, 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1998-1999 Apple Computer, Inc. All Rights Reserved + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)unistd.h 8.12 (Berkeley) 4/27/95 + * + * Copyright (c) 1998 Apple Compter, Inc. + * All Rights Reserved + */ + +/* History: + 7/14/99 EKN at Apple fixed getdirentriesattr from getdirentryattr + 3/26/98 CHW at Apple added real interface to searchfs call + 3/5/98 CHW at Apple added hfs semantic system calls headers +*/ + +#ifndef _UNISTD_H_ +#define _UNISTD_H_ + +#include <_types.h> +#include +#include +#include +#include +#include +#include +/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: + * _GCC_SIZE_T */ +#include +#include +#include +#include +#include + +#define STDIN_FILENO 0 /* standard input file descriptor */ +#define STDOUT_FILENO 1 /* standard output file descriptor */ +#define STDERR_FILENO 2 /* standard error file descriptor */ + + +/* Version test macros */ +/* _POSIX_VERSION and _POSIX2_VERSION from sys/unistd.h */ +#define _XOPEN_VERSION 600 /* [XSI] */ +#define _XOPEN_XCU_VERSION 4 /* Older standard */ + + +/* Please keep this list in the same order as the applicable standard */ +#define _POSIX_ADVISORY_INFO (-1) /* [ADV] */ +#define _POSIX_ASYNCHRONOUS_IO (-1) /* [AIO] */ +#define _POSIX_BARRIERS (-1) /* [BAR] */ +#define _POSIX_CHOWN_RESTRICTED 200112L +#define _POSIX_CLOCK_SELECTION (-1) /* [CS] */ +#define _POSIX_CPUTIME (-1) /* [CPT] */ +#define _POSIX_FSYNC 200112L /* [FSC] */ +#define _POSIX_IPV6 200112L +#define _POSIX_JOB_CONTROL 200112L +#define _POSIX_MAPPED_FILES 200112L /* [MF] */ +#define _POSIX_MEMLOCK (-1) /* [ML] */ +#define _POSIX_MEMLOCK_RANGE (-1) /* [MR] */ +#define _POSIX_MEMORY_PROTECTION 200112L /* [MPR] */ +#define _POSIX_MESSAGE_PASSING (-1) /* [MSG] */ +#define _POSIX_MONOTONIC_CLOCK (-1) /* [MON] */ +#define _POSIX_NO_TRUNC 200112L +#define _POSIX_PRIORITIZED_IO (-1) /* [PIO] */ +#define _POSIX_PRIORITY_SCHEDULING (-1) /* [PS] */ +#define _POSIX_RAW_SOCKETS (-1) /* [RS] */ +#define _POSIX_READER_WRITER_LOCKS 200112L /* [THR] */ +#define _POSIX_REALTIME_SIGNALS (-1) /* [RTS] */ +#define _POSIX_REGEXP 200112L +#define _POSIX_SAVED_IDS 200112L /* XXX required */ +#define _POSIX_SEMAPHORES (-1) /* [SEM] */ +#define _POSIX_SHARED_MEMORY_OBJECTS (-1) /* [SHM] */ +#define _POSIX_SHELL 200112L +#define _POSIX_SPAWN 200112L /* [SPN] */ +#define _POSIX_SPIN_LOCKS (-1) /* [SPI] */ +#define _POSIX_SPORADIC_SERVER (-1) /* [SS] */ +#define _POSIX_SYNCHRONIZED_IO (-1) /* [SIO] */ +#define _POSIX_THREAD_ATTR_STACKADDR 200112L /* [TSA] */ +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L /* [TSS] */ +#define _POSIX_THREAD_CPUTIME (-1) /* [TCT] */ +#define _POSIX_THREAD_PRIO_INHERIT (-1) /* [TPI] */ +#define _POSIX_THREAD_PRIO_PROTECT (-1) /* [TPP] */ +#define _POSIX_THREAD_PRIORITY_SCHEDULING (-1) /* [TPS] */ +#define _POSIX_THREAD_PROCESS_SHARED 200112L /* [TSH] */ +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L /* [TSF] */ +#define _POSIX_THREAD_SPORADIC_SERVER (-1) /* [TSP] */ +#define _POSIX_THREADS 200112L /* [THR] */ +#define _POSIX_TIMEOUTS (-1) /* [TMO] */ +#define _POSIX_TIMERS (-1) /* [TMR] */ +#define _POSIX_TRACE (-1) /* [TRC] */ +#define _POSIX_TRACE_EVENT_FILTER (-1) /* [TEF] */ +#define _POSIX_TRACE_INHERIT (-1) /* [TRI] */ +#define _POSIX_TRACE_LOG (-1) /* [TRL] */ +#define _POSIX_TYPED_MEMORY_OBJECTS (-1) /* [TYM] */ +#ifndef _POSIX_VDISABLE +#define _POSIX_VDISABLE 0xff /* same as sys/termios.h */ +#endif /* _POSIX_VDISABLE */ + +#if __DARWIN_C_LEVEL >= 199209L +#define _POSIX2_C_BIND 200112L +#define _POSIX2_C_DEV 200112L /* c99 command */ +#define _POSIX2_CHAR_TERM 200112L +#define _POSIX2_FORT_DEV (-1) /* fort77 command */ +#define _POSIX2_FORT_RUN 200112L +#define _POSIX2_LOCALEDEF 200112L /* localedef command */ +#define _POSIX2_PBS (-1) +#define _POSIX2_PBS_ACCOUNTING (-1) +#define _POSIX2_PBS_CHECKPOINT (-1) +#define _POSIX2_PBS_LOCATE (-1) +#define _POSIX2_PBS_MESSAGE (-1) +#define _POSIX2_PBS_TRACK (-1) +#define _POSIX2_SW_DEV 200112L +#define _POSIX2_UPE 200112L /* XXXX no fc, newgrp, tabs */ +#endif /* __DARWIN_C_LEVEL */ + +#define __ILP32_OFF32 (-1) +#define __ILP32_OFFBIG (-1) + +#define __LP64_OFF64 (1) +#define __LPBIG_OFFBIG (1) + +#if __DARWIN_C_LEVEL >= 200112L +#define _POSIX_V6_ILP32_OFF32 __ILP32_OFF32 +#define _POSIX_V6_ILP32_OFFBIG __ILP32_OFFBIG +#define _POSIX_V6_LP64_OFF64 __LP64_OFF64 +#define _POSIX_V6_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 200809L +#define _POSIX_V7_ILP32_OFF32 __ILP32_OFF32 +#define _POSIX_V7_ILP32_OFFBIG __ILP32_OFFBIG +#define _POSIX_V7_LP64_OFF64 __LP64_OFF64 +#define _POSIX_V7_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= 200809L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _V6_ILP32_OFF32 __ILP32_OFF32 +#define _V6_ILP32_OFFBIG __ILP32_OFFBIG +#define _V6_LP64_OFF64 __LP64_OFF64 +#define _V6_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _XBS5_ILP32_OFF32 __ILP32_OFF32 +#define _XBS5_ILP32_OFFBIG __ILP32_OFFBIG +#define _XBS5_LP64_OFF64 __LP64_OFF64 +#define _XBS5_LPBIG_OFFBIG __LPBIG_OFFBIG +#endif /* __DARWIN_C_LEVEL < 200809L */ + +#if __DARWIN_C_LEVEL >= 199506L /* This really should be XSI */ +#define _XOPEN_CRYPT (1) +#define _XOPEN_ENH_I18N (1) /* XXX required */ +#define _XOPEN_LEGACY (-1) /* no ftime gcvt, wcswcs */ +#define _XOPEN_REALTIME (-1) /* no q'ed signals, mq_* */ +#define _XOPEN_REALTIME_THREADS (-1) /* no posix_spawn, et. al. */ +#define _XOPEN_SHM (1) +#define _XOPEN_STREAMS (-1) /* Issue 6 */ +#define _XOPEN_UNIX (1) +#endif /* XSI */ + +/* configurable system variables */ +#define _SC_ARG_MAX 1 +#define _SC_CHILD_MAX 2 +#define _SC_CLK_TCK 3 +#define _SC_NGROUPS_MAX 4 +#define _SC_OPEN_MAX 5 +#define _SC_JOB_CONTROL 6 +#define _SC_SAVED_IDS 7 +#define _SC_VERSION 8 +#define _SC_BC_BASE_MAX 9 +#define _SC_BC_DIM_MAX 10 +#define _SC_BC_SCALE_MAX 11 +#define _SC_BC_STRING_MAX 12 +#define _SC_COLL_WEIGHTS_MAX 13 +#define _SC_EXPR_NEST_MAX 14 +#define _SC_LINE_MAX 15 +#define _SC_RE_DUP_MAX 16 +#define _SC_2_VERSION 17 +#define _SC_2_C_BIND 18 +#define _SC_2_C_DEV 19 +#define _SC_2_CHAR_TERM 20 +#define _SC_2_FORT_DEV 21 +#define _SC_2_FORT_RUN 22 +#define _SC_2_LOCALEDEF 23 +#define _SC_2_SW_DEV 24 +#define _SC_2_UPE 25 +#define _SC_STREAM_MAX 26 +#define _SC_TZNAME_MAX 27 + +#if __DARWIN_C_LEVEL >= 199309L +#define _SC_ASYNCHRONOUS_IO 28 +#define _SC_PAGESIZE 29 +#define _SC_MEMLOCK 30 +#define _SC_MEMLOCK_RANGE 31 +#define _SC_MEMORY_PROTECTION 32 +#define _SC_MESSAGE_PASSING 33 +#define _SC_PRIORITIZED_IO 34 +#define _SC_PRIORITY_SCHEDULING 35 +#define _SC_REALTIME_SIGNALS 36 +#define _SC_SEMAPHORES 37 +#define _SC_FSYNC 38 +#define _SC_SHARED_MEMORY_OBJECTS 39 +#define _SC_SYNCHRONIZED_IO 40 +#define _SC_TIMERS 41 +#define _SC_AIO_LISTIO_MAX 42 +#define _SC_AIO_MAX 43 +#define _SC_AIO_PRIO_DELTA_MAX 44 +#define _SC_DELAYTIMER_MAX 45 +#define _SC_MQ_OPEN_MAX 46 +#define _SC_MAPPED_FILES 47 /* swap _SC_PAGESIZE vs. BSD */ +#define _SC_RTSIG_MAX 48 +#define _SC_SEM_NSEMS_MAX 49 +#define _SC_SEM_VALUE_MAX 50 +#define _SC_SIGQUEUE_MAX 51 +#define _SC_TIMER_MAX 52 +#endif /* __DARWIN_C_LEVEL >= 199309L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _SC_NPROCESSORS_CONF 57 +#define _SC_NPROCESSORS_ONLN 58 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if __DARWIN_C_LEVEL >= 200112L +#define _SC_2_PBS 59 +#define _SC_2_PBS_ACCOUNTING 60 +#define _SC_2_PBS_CHECKPOINT 61 +#define _SC_2_PBS_LOCATE 62 +#define _SC_2_PBS_MESSAGE 63 +#define _SC_2_PBS_TRACK 64 +#define _SC_ADVISORY_INFO 65 +#define _SC_BARRIERS 66 +#define _SC_CLOCK_SELECTION 67 +#define _SC_CPUTIME 68 +#define _SC_FILE_LOCKING 69 +#define _SC_GETGR_R_SIZE_MAX 70 +#define _SC_GETPW_R_SIZE_MAX 71 +#define _SC_HOST_NAME_MAX 72 +#define _SC_LOGIN_NAME_MAX 73 +#define _SC_MONOTONIC_CLOCK 74 +#define _SC_MQ_PRIO_MAX 75 +#define _SC_READER_WRITER_LOCKS 76 +#define _SC_REGEXP 77 +#define _SC_SHELL 78 +#define _SC_SPAWN 79 +#define _SC_SPIN_LOCKS 80 +#define _SC_SPORADIC_SERVER 81 +#define _SC_THREAD_ATTR_STACKADDR 82 +#define _SC_THREAD_ATTR_STACKSIZE 83 +#define _SC_THREAD_CPUTIME 84 +#define _SC_THREAD_DESTRUCTOR_ITERATIONS 85 +#define _SC_THREAD_KEYS_MAX 86 +#define _SC_THREAD_PRIO_INHERIT 87 +#define _SC_THREAD_PRIO_PROTECT 88 +#define _SC_THREAD_PRIORITY_SCHEDULING 89 +#define _SC_THREAD_PROCESS_SHARED 90 +#define _SC_THREAD_SAFE_FUNCTIONS 91 +#define _SC_THREAD_SPORADIC_SERVER 92 +#define _SC_THREAD_STACK_MIN 93 +#define _SC_THREAD_THREADS_MAX 94 +#define _SC_TIMEOUTS 95 +#define _SC_THREADS 96 +#define _SC_TRACE 97 +#define _SC_TRACE_EVENT_FILTER 98 +#define _SC_TRACE_INHERIT 99 +#define _SC_TRACE_LOG 100 +#define _SC_TTY_NAME_MAX 101 +#define _SC_TYPED_MEMORY_OBJECTS 102 +#define _SC_V6_ILP32_OFF32 103 +#define _SC_V6_ILP32_OFFBIG 104 +#define _SC_V6_LP64_OFF64 105 +#define _SC_V6_LPBIG_OFFBIG 106 +#define _SC_IPV6 118 +#define _SC_RAW_SOCKETS 119 +#define _SC_SYMLOOP_MAX 120 +#endif /* __DARWIN_C_LEVEL >= 200112L */ + +#if __DARWIN_C_LEVEL >= 199506L /* Really XSI */ +#define _SC_ATEXIT_MAX 107 +#define _SC_IOV_MAX 56 +#define _SC_PAGE_SIZE _SC_PAGESIZE +#define _SC_XOPEN_CRYPT 108 +#define _SC_XOPEN_ENH_I18N 109 +#define _SC_XOPEN_LEGACY 110 /* Issue 6 */ +#define _SC_XOPEN_REALTIME 111 /* Issue 6 */ +#define _SC_XOPEN_REALTIME_THREADS 112 /* Issue 6 */ +#define _SC_XOPEN_SHM 113 +#define _SC_XOPEN_STREAMS 114 /* Issue 6 */ +#define _SC_XOPEN_UNIX 115 +#define _SC_XOPEN_VERSION 116 +#define _SC_XOPEN_XCU_VERSION 121 +#endif /* XSI */ + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _SC_XBS5_ILP32_OFF32 122 +#define _SC_XBS5_ILP32_OFFBIG 123 +#define _SC_XBS5_LP64_OFF64 124 +#define _SC_XBS5_LPBIG_OFFBIG 125 +#endif /* __DARWIN_C_LEVEL <= 200809L */ + +#if __DARWIN_C_LEVEL >= 200112L +#define _SC_SS_REPL_MAX 126 +#define _SC_TRACE_EVENT_NAME_MAX 127 +#define _SC_TRACE_NAME_MAX 128 +#define _SC_TRACE_SYS_MAX 129 +#define _SC_TRACE_USER_EVENT_MAX 130 +#endif + +#if __DARWIN_C_LEVEL < 200112L || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 6 */ +#define _SC_PASS_MAX 131 +#endif + +/* 132-199 available for future use */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _SC_PHYS_PAGES 200 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#if __DARWIN_C_LEVEL >= 199209L +#ifndef _CS_PATH /* Defined in */ +#define _CS_PATH 1 +#endif +#endif + +#if __DARWIN_C_LEVEL >= 200112 +#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2 +#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3 +#define _CS_POSIX_V6_ILP32_OFF32_LIBS 4 +#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5 +#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6 +#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7 +#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8 +#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9 +#define _CS_POSIX_V6_LP64_OFF64_LIBS 10 +#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11 +#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12 +#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13 +#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14 +#endif + +#if (__DARWIN_C_LEVEL >= 199506L && __DARWIN_C_LEVEL < 200809L) || __DARWIN_C_LEVEL >= __DARWIN_C_FULL +/* Removed in Issue 7 */ +#define _CS_XBS5_ILP32_OFF32_CFLAGS 20 +#define _CS_XBS5_ILP32_OFF32_LDFLAGS 21 +#define _CS_XBS5_ILP32_OFF32_LIBS 22 +#define _CS_XBS5_ILP32_OFF32_LINTFLAGS 23 +#define _CS_XBS5_ILP32_OFFBIG_CFLAGS 24 +#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS 25 +#define _CS_XBS5_ILP32_OFFBIG_LIBS 26 +#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 27 +#define _CS_XBS5_LP64_OFF64_CFLAGS 28 +#define _CS_XBS5_LP64_OFF64_LDFLAGS 29 +#define _CS_XBS5_LP64_OFF64_LIBS 30 +#define _CS_XBS5_LP64_OFF64_LINTFLAGS 31 +#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS 32 +#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 33 +#define _CS_XBS5_LPBIG_OFFBIG_LIBS 34 +#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 35 +#endif + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _CS_DARWIN_USER_DIR 65536 +#define _CS_DARWIN_USER_TEMP_DIR 65537 +#define _CS_DARWIN_USER_CACHE_DIR 65538 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + + +#ifdef _DARWIN_UNLIMITED_GETGROUPS +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 +#error "_DARWIN_UNLIMITED_GETGROUPS specified, but -miphoneos-version-min version does not support it." +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6 +#error "_DARWIN_UNLIMITED_GETGROUPS specified, but -mmacosx-version-min version does not support it." +#endif +#endif + +/* POSIX.1-1990 */ + +__BEGIN_DECLS +void _exit(int) __dead2; +int access(const char *, int); +unsigned int + alarm(unsigned int); +int chdir(const char *); +int chown(const char *, uid_t, gid_t); + +int close(int) __DARWIN_ALIAS_C(close); + +int dup(int); +int dup2(int, int); +int execl(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execle(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execlp(const char * __file, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execv(const char * __path, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execve(const char * __file, char * const * __argv, char * const * __envp) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execvp(const char * __file, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +pid_t fork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +long fpathconf(int, int); +char *getcwd(char *, size_t); +gid_t getegid(void); +uid_t geteuid(void); +gid_t getgid(void); +#if defined(_DARWIN_UNLIMITED_GETGROUPS) || defined(_DARWIN_C_SOURCE) +int getgroups(int, gid_t []) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(getgroups)); +#else /* !_DARWIN_UNLIMITED_GETGROUPS && !_DARWIN_C_SOURCE */ +int getgroups(int, gid_t []); +#endif /* _DARWIN_UNLIMITED_GETGROUPS || _DARWIN_C_SOURCE */ +char *getlogin(void); +pid_t getpgrp(void); +pid_t getpid(void); +pid_t getppid(void); +uid_t getuid(void); +int isatty(int); +int link(const char *, const char *); +off_t lseek(int, off_t, int); +long pathconf(const char *, int); + +int pause(void) __DARWIN_ALIAS_C(pause); + +int pipe(int [2]); + +ssize_t read(int, void *, size_t) __DARWIN_ALIAS_C(read); + +int rmdir(const char *); +int setgid(gid_t); +int setpgid(pid_t, pid_t); +pid_t setsid(void); +int setuid(uid_t); + +unsigned int + sleep(unsigned int) __DARWIN_ALIAS_C(sleep); + +long sysconf(int); +pid_t tcgetpgrp(int); +int tcsetpgrp(int, pid_t); +char *ttyname(int); + +#if __DARWIN_UNIX03 +int ttyname_r(int, char *, size_t) __DARWIN_ALIAS(ttyname_r); +#else /* !__DARWIN_UNIX03 */ +char *ttyname_r(int, char *, size_t); +#endif /* __DARWIN_UNIX03 */ + +int unlink(const char *); + +ssize_t write(int __fd, const void * __buf, size_t __nbyte) __DARWIN_ALIAS_C(write); +__END_DECLS + + + +/* Additional functionality provided by: + * POSIX.2-1992 C Language Binding Option + */ + +#if __DARWIN_C_LEVEL >= 199209L +__BEGIN_DECLS +size_t confstr(int, char *, size_t) __DARWIN_ALIAS(confstr); + +int getopt(int, char * const [], const char *) __DARWIN_ALIAS(getopt); + +extern char *optarg; /* getopt(3) external variables */ +extern int optind, opterr, optopt; +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199209L */ + + + +/* Additional functionality provided by: + * POSIX.1c-1995, + * POSIX.1i-1995, + * and the omnibus ISO/IEC 9945-1: 1996 + */ + +#if __DARWIN_C_LEVEL >= 199506L +#include <_ctermid.h> + /* These F_* are really XSI or Issue 6 */ +#define F_ULOCK 0 /* unlock locked section */ +#define F_LOCK 1 /* lock a section for exclusive use */ +#define F_TLOCK 2 /* test and lock a section for exclusive use */ +#define F_TEST 3 /* test a section for locks by other procs */ + + __BEGIN_DECLS + +/* Begin XSI */ +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +#if !defined(_POSIX_C_SOURCE) +__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED +#endif +void *brk(const void *); +int chroot(const char *) __POSIX_C_DEPRECATED(199506L); +#endif + +char *crypt(const char *, const char *); +#if __DARWIN_UNIX03 +void encrypt(char *, int) __DARWIN_ALIAS(encrypt); +#else /* !__DARWIN_UNIX03 */ +int encrypt(char *, int); +#endif /* __DARWIN_UNIX03 */ +int fchdir(int); +long gethostid(void); +pid_t getpgid(pid_t); +pid_t getsid(pid_t); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +int getdtablesize(void) __POSIX_C_DEPRECATED(199506L); +int getpagesize(void) __pure2 __POSIX_C_DEPRECATED(199506L); +char *getpass(const char *) __POSIX_C_DEPRECATED(199506L); +#endif + +/* Removed in Issue 7 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L +char *getwd(char *) __POSIX_C_DEPRECATED(200112L); /* obsoleted by getcwd() */ +#endif + +int lchown(const char *, uid_t, gid_t) __DARWIN_ALIAS(lchown); + +int lockf(int, int, off_t) __DARWIN_ALIAS_C(lockf); + +int nice(int) __DARWIN_ALIAS(nice); + +ssize_t pread(int __fd, void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pread); + +ssize_t pwrite(int __fd, const void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pwrite); + +/* Removed in Issue 6 */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +/* Note that Issue 5 changed the argument as intprt_t, + * but we keep it as int for binary compatability. */ +#if !defined(_POSIX_C_SOURCE) +__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED +#endif +void *sbrk(int); +#endif + +#if __DARWIN_UNIX03 +pid_t setpgrp(void) __DARWIN_ALIAS(setpgrp); +#else /* !__DARWIN_UNIX03 */ +int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */ +#endif /* __DARWIN_UNIX03 */ + +int setregid(gid_t, gid_t) __DARWIN_ALIAS(setregid); + +int setreuid(uid_t, uid_t) __DARWIN_ALIAS(setreuid); + +void swab(const void * __restrict, void * __restrict, ssize_t); +void sync(void); +int truncate(const char *, off_t); +useconds_t ualarm(useconds_t, useconds_t); +int usleep(useconds_t) __DARWIN_ALIAS_C(usleep); + +#if !defined(_POSIX_C_SOURCE) +__deprecated_msg("Use posix_spawn or fork") +#endif +pid_t vfork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +/* End XSI */ + +int fsync(int) __DARWIN_ALIAS_C(fsync); + +int ftruncate(int, off_t); +int getlogin_r(char *, size_t); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 199506L */ + + + +/* Additional functionality provided by: + * POSIX.1-2001 + * ISO C99 + */ + +#if __DARWIN_C_LEVEL >= 200112L +__BEGIN_DECLS +int fchown(int, uid_t, gid_t); +int gethostname(char *, size_t); +ssize_t readlink(const char * __restrict, char * __restrict, size_t); +int setegid(gid_t); +int seteuid(uid_t); +int symlink(const char *, const char *); +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= 200112L */ + + + +/* Darwin extensions */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#include + +#include +#include +#include + +__BEGIN_DECLS +void _Exit(int) __dead2; +int accessx_np(const struct accessx_descriptor *, size_t, int *, uid_t); +int acct(const char *); +int add_profil(char *, size_t, unsigned long, unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +void endusershell(void); +int execvP(const char * __file, const char * __searchpath, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +char *fflagstostr(unsigned long); +int getdomainname(char *, int); +int getgrouplist(const char *, int, int *, int *); +#if defined(__has_include) +#if __has_include() +#include +#else +#include +#endif +#else +#include +#endif +mode_t getmode(const void *, mode_t); +int getpeereid(int, uid_t *, gid_t *); +int getsgroups_np(int *, uuid_t); +char *getusershell(void); +int getwgroups_np(int *, uuid_t); +int initgroups(const char *, int); +int issetugid(void); +char *mkdtemp(char *); +int mknod(const char *, mode_t, dev_t); +int mkpath_np(const char *path, mode_t omode) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); /* returns errno */ +int mkpathat_np(int dfd, const char *path, mode_t omode) /* returns errno */ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +int mkstemp(char *); +int mkstemps(char *, int); +char *mktemp(char *); +int mkostemp(char *path, int oflags) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +int mkostemps(char *path, int slen, int oflags) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +/* Non-portable mkstemp that uses open_dprotected_np */ +int mkstemp_dprotected_np(char *path, int dpclass, int dpflags) + __OSX_UNAVAILABLE __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +char *mkdtempat_np(int dfd, char *path) + __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) + __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +int mkstempsat_np(int dfd, char *path, int slen) + __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) + __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +int mkostempsat_np(int dfd, char *path, int slen, int oflags) + __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) + __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +int nfssvc(int, void *); +int profil(char *, size_t, unsigned long, unsigned int); + +__deprecated_msg("Use of per-thread security contexts is error-prone and discouraged.") +int pthread_setugid_np(uid_t, gid_t); +int pthread_getugid_np( uid_t *, gid_t *); + +int reboot(int); +int revoke(const char *); + +__deprecated int rcmd(char **, int, const char *, const char *, const char *, int *); +__deprecated int rcmd_af(char **, int, const char *, const char *, const char *, int *, + int); +__deprecated int rresvport(int *); +__deprecated int rresvport_af(int *, int); +__deprecated int iruserok(unsigned long, int, const char *, const char *); +__deprecated int iruserok_sa(const void *, int, int, const char *, const char *); +__deprecated int ruserok(const char *, int, const char *, const char *); + +int setdomainname(const char *, int); +int setgroups(int, const gid_t *); +void sethostid(long); +int sethostname(const char *, int); +#if __DARWIN_UNIX03 +void setkey(const char *) __DARWIN_ALIAS(setkey); +#else /* !__DARWIN_UNIX03 */ +int setkey(const char *); +#endif /* __DARWIN_UNIX03 */ +int setlogin(const char *); +void *setmode(const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(setmode)); +int setrgid(gid_t); +int setruid(uid_t); +int setsgroups_np(int, const uuid_t); +void setusershell(void); +int setwgroups_np(int, const uuid_t); +int strtofflags(char **, unsigned long *, unsigned long *); +int swapon(const char *); +int ttyslot(void); +int undelete(const char *); +int unwhiteout(const char *); +void *valloc(size_t); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +__OS_AVAILABILITY_MSG(ios,deprecated=10.0,"syscall(2) is unsupported; " + "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") +__OS_AVAILABILITY_MSG(macosx,deprecated=10.12,"syscall(2) is unsupported; " + "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") +int syscall(int, ...); + +extern char *suboptarg; /* getsubopt(3) external variable */ +int getsubopt(char **, char * const *, char **); + +/* HFS & HFS Plus semantics system calls go here */ +#ifdef __LP64__ +int fgetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int fsetattrlist(int,void*,void*,size_t,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int getattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(getattrlist); +int setattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(setattrlist); +int exchangedata(const char*,const char*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; + +#else /* __LP64__ */ +int fgetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int fsetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +int getattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(getattrlist); +int setattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(setattrlist); +int exchangedata(const char*,const char*,unsigned long) + __OSX_DEPRECATED(10.0, 10.13, "use renamex_np with the RENAME_SWAP flag") + __IOS_DEPRECATED(2.0, 11.0, "use renamex_np with the RENAME_SWAP flag") + __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; + +#endif /* __LP64__ */ + +struct fssearchblock; +struct searchstate; + +int searchfs(const char *, struct fssearchblock *, unsigned long *, unsigned int, unsigned int, struct searchstate *) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int fsctl(const char *,unsigned long,void*,unsigned int); +int ffsctl(int,unsigned long,void*,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); + +#define SYNC_VOLUME_FULLSYNC 0x01 /* Flush data and metadata to platter, not just to disk cache */ +#define SYNC_VOLUME_WAIT 0x02 /* Wait for sync to complete */ + +int fsync_volume_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); +int sync_volume_np(const char *, int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); + +extern int optreset; + +__END_DECLS +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + +#endif /* _UNISTD_H_ */ \ No newline at end of file diff --git a/lib/libc/include/any-macos.13-any/xpc/availability.h b/lib/libc/include/any-macos.13-any/xpc/availability.h new file mode 100644 index 0000000000..3197cfb652 --- /dev/null +++ b/lib/libc/include/any-macos.13-any/xpc/availability.h @@ -0,0 +1,134 @@ +#ifndef __XPC_AVAILABILITY_H__ +#define __XPC_AVAILABILITY_H__ + +#include + +// Certain parts of the project use all the project's headers but have to build +// against newer OSX SDKs than ebuild uses -- liblaunch_host being the example. +// So we need to define these. +#ifndef __MAC_10_16 +#define __MAC_10_16 101600 +#endif // __MAC_10_16 + +#ifndef __MAC_10_15 +#define __MAC_10_15 101500 +#define __AVAILABILITY_INTERNAL__MAC_10_15 \ +__attribute__((availability(macosx, introduced=10.15))) +#endif // __MAC_10_15 + +#ifndef __MAC_10_14 +#define __MAC_10_14 101400 +#define __AVAILABILITY_INTERNAL__MAC_10_14 \ +__attribute__((availability(macosx, introduced=10.14))) +#endif // __MAC_10_14 + +#ifndef __MAC_10_13 +#define __MAC_10_13 101300 +#define __AVAILABILITY_INTERNAL__MAC_10_13 \ + __attribute__((availability(macosx, introduced=10.13))) +#endif // __MAC_10_13 + +#ifndef __MAC_10_12 +#define __MAC_10_12 101200 +#define __AVAILABILITY_INTERNAL__MAC_10_12 \ + __attribute__((availability(macosx, introduced=10.12))) +#endif // __MAC_10_12 + +#ifndef __MAC_10_11 +#define __MAC_10_11 101100 +#define __AVAILABILITY_INTERNAL__MAC_10_11 \ + __attribute__((availability(macosx, introduced=10.11))) +#endif // __MAC_10_11 + +#ifndef __MAC_12_0 +#define __MAC_12_0 120000 +#define __AVAILABILITY_INTERNAL__MAC_12_0 \ + __attribute__((availability(macosx, introduced=12.0))) +#endif // __MAC_12_0 + +#ifndef __MAC_13_3 +#define __MAC_13_3 130300 +#endif // __MAC_13_3 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 +#define __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 +#endif // __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 + +#ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 +#define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 +#endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 + +#if __has_include() +#include +#else // __has_include() +#ifndef IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED +#define IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 999999 +#endif // IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED +#endif // __has_include() + +#ifndef __WATCHOS_UNAVAILABLE +#define __WATCHOS_UNAVAILABLE +#endif + +#ifndef __TVOS_UNAVAILABLE +#define __TVOS_UNAVAILABLE +#endif + +// simulator host-side bits build against SDKs not having __*_AVAILABLE() yet +#ifndef __OSX_AVAILABLE +#define __OSX_AVAILABLE(...) +#endif + +#ifndef __IOS_AVAILABLE +#define __IOS_AVAILABLE(...) +#endif + +#ifndef __TVOS_AVAILABLE +#define __TVOS_AVAILABLE(...) +#endif + +#ifndef __WATCHOS_AVAILABLE +#define __WATCHOS_AVAILABLE(...) +#endif + +#ifndef __API_AVAILABLE +#define __API_AVAILABLE(...) +#endif + +#endif // __XPC_AVAILABILITY_H__ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos.13-none/mach/i386/thread_status.h b/lib/libc/include/x86_64-macos.13-none/mach/i386/thread_status.h index d401a11fd0..a3fd3e8244 100644 --- a/lib/libc/include/x86_64-macos.13-none/mach/i386/thread_status.h +++ b/lib/libc/include/x86_64-macos.13-none/mach/i386/thread_status.h @@ -132,6 +132,12 @@ */ #define THREAD_MACHINE_STATE_MAX THREAD_STATE_MAX +#define FLAVOR_MODIFIES_CORE_CPU_REGISTERS(x) \ +((x == x86_THREAD_STATE) || \ + (x == x86_THREAD_STATE32) || \ + (x == x86_THREAD_STATE64) || \ + (x == x86_THREAD_FULL_STATE64)) + /* * VALID_THREAD_STATE_FLAVOR is a platform specific macro that when passed * an exception flavor will return if that is a defined flavor for that From f6845bbbc6bca3b351955ba312755355474a7d82 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 21:22:30 +0200 Subject: [PATCH 166/216] std: bump max macOS version to 13.3 --- lib/std/target.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/target.zig b/lib/std/target.zig index 52f41a0563..9391d590ef 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -280,13 +280,13 @@ pub const Target = struct { .aarch64 => VersionRange{ .semver = .{ .min = .{ .major = 11, .minor = 7, .patch = 1 }, - .max = .{ .major = 13, .minor = 0 }, + .max = .{ .major = 13, .minor = 3 }, }, }, .x86_64 => VersionRange{ .semver = .{ .min = .{ .major = 11, .minor = 7, .patch = 1 }, - .max = .{ .major = 13, .minor = 0 }, + .max = .{ .major = 13, .minor = 3 }, }, }, else => unreachable, From 0bbc1ec2061b116093d3a85e955c5e6c1e7a28cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20=C3=85stholm?= Date: Fri, 31 Mar 2023 22:48:32 +0200 Subject: [PATCH 167/216] std.mem.reverseIterator: accept pointer to array --- lib/std/mem.zig | 77 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/lib/std/mem.zig b/lib/std/mem.zig index a486713e1c..b4aea4e0c8 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -2989,32 +2989,35 @@ test "reverse" { } fn ReverseIterator(comptime T: type) type { - const info: struct { Child: type, Pointer: type } = blk: { + const Pointer = blk: { switch (@typeInfo(T)) { - .Pointer => |info| switch (info.size) { - .Slice => break :blk .{ - .Child = info.child, - .Pointer = @Type(.{ .Pointer = .{ - .size = .Many, - .is_const = info.is_const, - .is_volatile = info.is_volatile, - .alignment = info.alignment, - .address_space = info.address_space, - .child = info.child, - .is_allowzero = info.is_allowzero, - .sentinel = info.sentinel, - } }), + .Pointer => |ptr_info| switch (ptr_info.size) { + .One => switch (@typeInfo(ptr_info.child)) { + .Array => |array_info| { + var new_ptr_info = ptr_info; + new_ptr_info.size = .Many; + new_ptr_info.child = array_info.child; + new_ptr_info.sentinel = array_info.sentinel; + break :blk @Type(.{ .Pointer = new_ptr_info }); + }, + else => {}, + }, + .Slice => { + var new_ptr_info = ptr_info; + new_ptr_info.size = .Many; + break :blk @Type(.{ .Pointer = new_ptr_info }); }, else => {}, }, else => {}, } - @compileError("reverse iterator expects slice, found " ++ @typeName(T)); + @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"); }; + const Element = std.meta.Elem(Pointer); return struct { - ptr: info.Pointer, + ptr: Pointer, index: usize, - pub fn next(self: *@This()) ?info.Child { + pub fn next(self: *@This()) ?Element { if (self.index == 0) return null; self.index -= 1; return self.ptr[self.index]; @@ -3022,19 +3025,41 @@ fn ReverseIterator(comptime T: type) type { }; } -/// Iterate over a slice in reverse. +/// Iterates over a slice in reverse. pub fn reverseIterator(slice: anytype) ReverseIterator(@TypeOf(slice)) { - return .{ .ptr = slice.ptr, .index = slice.len }; + const T = @TypeOf(slice); + if (comptime trait.isPtrTo(.Array)(T)) { + return .{ .ptr = slice, .index = slice.len }; + } else { + comptime assert(trait.isSlice(T)); + return .{ .ptr = slice.ptr, .index = slice.len }; + } } test "reverseIterator" { - const slice: []const i32 = &[_]i32{ 5, 3, 1, 2 }; - var it = reverseIterator(slice); - try testing.expectEqual(@as(?i32, 2), it.next()); - try testing.expectEqual(@as(?i32, 1), it.next()); - try testing.expectEqual(@as(?i32, 3), it.next()); - try testing.expectEqual(@as(?i32, 5), it.next()); - try testing.expectEqual(@as(?i32, null), it.next()); + { + var it = reverseIterator("abc"); + try testing.expectEqual(@as(?u8, 'c'), it.next()); + try testing.expectEqual(@as(?u8, 'b'), it.next()); + try testing.expectEqual(@as(?u8, 'a'), it.next()); + try testing.expectEqual(@as(?u8, null), it.next()); + } + { + var array = [2]i32{ 3, 7 }; + const slice: []const i32 = &array; + var it = reverseIterator(slice); + try testing.expectEqual(@as(?i32, 7), it.next()); + try testing.expectEqual(@as(?i32, 3), it.next()); + try testing.expectEqual(@as(?i32, null), it.next()); + } + { + var array = [2]i32{ 3, 7 }; + const ptr_to_array: *const [2]i32 = &array; + var it = reverseIterator(ptr_to_array); + try testing.expectEqual(@as(?i32, 7), it.next()); + try testing.expectEqual(@as(?i32, 3), it.next()); + try testing.expectEqual(@as(?i32, null), it.next()); + } } /// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1) From 3cd72951c037db69645a634fb063621512091ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20=C3=85stholm?= Date: Fri, 31 Mar 2023 22:50:31 +0200 Subject: [PATCH 168/216] std.mem.reverseIterator: add nextPtr() --- lib/std/mem.zig | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/std/mem.zig b/lib/std/mem.zig index b4aea4e0c8..fcdcc71282 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -3014,6 +3014,7 @@ fn ReverseIterator(comptime T: type) type { @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"); }; const Element = std.meta.Elem(Pointer); + const ElementPointer = @TypeOf(&@as(Pointer, undefined)[0]); return struct { ptr: Pointer, index: usize, @@ -3022,6 +3023,11 @@ fn ReverseIterator(comptime T: type) type { self.index -= 1; return self.ptr[self.index]; } + pub fn nextPtr(self: *@This()) ?ElementPointer { + if (self.index == 0) return null; + self.index -= 1; + return &self.ptr[self.index]; + } }; } @@ -3051,6 +3057,18 @@ test "reverseIterator" { try testing.expectEqual(@as(?i32, 7), it.next()); try testing.expectEqual(@as(?i32, 3), it.next()); try testing.expectEqual(@as(?i32, null), it.next()); + + it = reverseIterator(slice); + try testing.expect(trait.isConstPtr(@TypeOf(it.nextPtr().?))); + try testing.expectEqual(@as(?i32, 7), it.nextPtr().?.*); + try testing.expectEqual(@as(?i32, 3), it.nextPtr().?.*); + try testing.expectEqual(@as(?*const i32, null), it.nextPtr()); + + var mut_slice: []i32 = &array; + var mut_it = reverseIterator(mut_slice); + mut_it.nextPtr().?.* += 1; + mut_it.nextPtr().?.* += 2; + try testing.expectEqual([2]i32{ 5, 8 }, array); } { var array = [2]i32{ 3, 7 }; @@ -3059,6 +3077,18 @@ test "reverseIterator" { try testing.expectEqual(@as(?i32, 7), it.next()); try testing.expectEqual(@as(?i32, 3), it.next()); try testing.expectEqual(@as(?i32, null), it.next()); + + it = reverseIterator(ptr_to_array); + try testing.expect(trait.isConstPtr(@TypeOf(it.nextPtr().?))); + try testing.expectEqual(@as(?i32, 7), it.nextPtr().?.*); + try testing.expectEqual(@as(?i32, 3), it.nextPtr().?.*); + try testing.expectEqual(@as(?*const i32, null), it.nextPtr()); + + var mut_ptr_to_array: *[2]i32 = &array; + var mut_it = reverseIterator(mut_ptr_to_array); + mut_it.nextPtr().?.* += 1; + mut_it.nextPtr().?.* += 2; + try testing.expectEqual([2]i32{ 5, 8 }, array); } } From 9ea04f4f1ca2507c75f1d276c37028aa53bfa201 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 22:12:22 +0200 Subject: [PATCH 169/216] tapi: update yaml parser https://github.com/kubkon/zig-yaml/commit/5de8b0b3a2cdb86f9a173118efa7e5e0747cca14 --- src/link/tapi/Tokenizer.zig | 555 ++++++++++++++++----------- src/link/tapi/parse.zig | 721 +++++++++++++++++++---------------- src/link/tapi/parse/test.zig | 556 ++++++++++++++++++--------- src/link/tapi/yaml.zig | 580 +++++++++------------------- src/link/tapi/yaml/test.zig | 475 +++++++++++++++++++++++ 5 files changed, 1759 insertions(+), 1128 deletions(-) create mode 100644 src/link/tapi/yaml/test.zig diff --git a/src/link/tapi/Tokenizer.zig b/src/link/tapi/Tokenizer.zig index d28700a02c..df46bb7d83 100644 --- a/src/link/tapi/Tokenizer.zig +++ b/src/link/tapi/Tokenizer.zig @@ -1,7 +1,7 @@ const Tokenizer = @This(); const std = @import("std"); -const log = std.log.scoped(.tapi); +const log = std.log.scoped(.yaml); const testing = std.testing; buffer: []const u8, @@ -13,29 +13,31 @@ pub const Token = struct { end: usize, pub const Id = enum { - Eof, + // zig fmt: off + eof, - NewLine, - DocStart, // --- - DocEnd, // ... - SeqItemInd, // - - MapValueInd, // : - FlowMapStart, // { - FlowMapEnd, // } - FlowSeqStart, // [ - FlowSeqEnd, // ] + new_line, + doc_start, // --- + doc_end, // ... + seq_item_ind, // - + map_value_ind, // : + flow_map_start, // { + flow_map_end, // } + flow_seq_start, // [ + flow_seq_end, // ] - Comma, - Space, - Tab, - Comment, // # - Alias, // * - Anchor, // & - Tag, // ! - SingleQuote, // ' - DoubleQuote, // " + comma, + space, + tab, + comment, // # + alias, // * + anchor, // & + tag, // ! - Literal, + single_quoted, // '...' + double_quoted, // "..." + literal, + // zig fmt: on }; }; @@ -45,8 +47,8 @@ pub const TokenIterator = struct { buffer: []const Token, pos: TokenIndex = 0, - pub fn next(self: *TokenIterator) Token { - const token = self.buffer[self.pos]; + pub fn next(self: *TokenIterator) ?Token { + const token = self.peek() orelse return null; self.pos += 1; return token; } @@ -74,180 +76,212 @@ pub const TokenIterator = struct { } }; +fn stringMatchesPattern(comptime pattern: []const u8, slice: []const u8) bool { + comptime var count: usize = 0; + inline while (count < pattern.len) : (count += 1) { + if (count >= slice.len) return false; + const c = slice[count]; + if (pattern[count] != c) return false; + } + return true; +} + +fn matchesPattern(self: Tokenizer, comptime pattern: []const u8) bool { + return stringMatchesPattern(pattern, self.buffer[self.index..]); +} + pub fn next(self: *Tokenizer) Token { var result = Token{ - .id = .Eof, + .id = .eof, .start = self.index, .end = undefined, }; - var state: union(enum) { - Start, - NewLine, - Space, - Tab, - Hyphen: usize, - Dot: usize, - Literal, - } = .Start; + var state: enum { + start, + new_line, + space, + tab, + comment, + single_quoted, + double_quoted, + literal, + } = .start; while (self.index < self.buffer.len) : (self.index += 1) { const c = self.buffer[self.index]; switch (state) { - .Start => switch (c) { + .start => switch (c) { ' ' => { - state = .Space; + state = .space; }, '\t' => { - state = .Tab; + state = .tab; }, '\n' => { - result.id = .NewLine; + result.id = .new_line; self.index += 1; break; }, '\r' => { - state = .NewLine; + state = .new_line; }, - '-' => { - state = .{ .Hyphen = 1 }; + + '-' => if (self.matchesPattern("---")) { + result.id = .doc_start; + self.index += "---".len; + break; + } else if (self.matchesPattern("- ")) { + result.id = .seq_item_ind; + self.index += "- ".len; + break; + } else { + state = .literal; }, - '.' => { - state = .{ .Dot = 1 }; + + '.' => if (self.matchesPattern("...")) { + result.id = .doc_end; + self.index += "...".len; + break; + } else { + state = .literal; }, + ',' => { - result.id = .Comma; + result.id = .comma; self.index += 1; break; }, '#' => { - result.id = .Comment; - self.index += 1; - break; + state = .comment; }, '*' => { - result.id = .Alias; + result.id = .alias; self.index += 1; break; }, '&' => { - result.id = .Anchor; + result.id = .anchor; self.index += 1; break; }, '!' => { - result.id = .Tag; - self.index += 1; - break; - }, - '\'' => { - result.id = .SingleQuote; - self.index += 1; - break; - }, - '"' => { - result.id = .DoubleQuote; + result.id = .tag; self.index += 1; break; }, '[' => { - result.id = .FlowSeqStart; + result.id = .flow_seq_start; self.index += 1; break; }, ']' => { - result.id = .FlowSeqEnd; + result.id = .flow_seq_end; self.index += 1; break; }, ':' => { - result.id = .MapValueInd; + result.id = .map_value_ind; self.index += 1; break; }, '{' => { - result.id = .FlowMapStart; + result.id = .flow_map_start; self.index += 1; break; }, '}' => { - result.id = .FlowMapEnd; + result.id = .flow_map_end; self.index += 1; break; }, + '\'' => { + state = .single_quoted; + }, + '"' => { + state = .double_quoted; + }, else => { - state = .Literal; + state = .literal; }, }, - .Space => switch (c) { + + .comment => switch (c) { + '\r', '\n' => { + result.id = .comment; + break; + }, + else => {}, + }, + + .space => switch (c) { ' ' => {}, else => { - result.id = .Space; + result.id = .space; break; }, }, - .Tab => switch (c) { + + .tab => switch (c) { '\t' => {}, else => { - result.id = .Tab; + result.id = .tab; break; }, }, - .NewLine => switch (c) { + + .new_line => switch (c) { '\n' => { - result.id = .NewLine; + result.id = .new_line; self.index += 1; break; }, else => {}, // TODO this should be an error condition }, - .Hyphen => |*count| switch (c) { - ' ' => { - result.id = .SeqItemInd; + + .single_quoted => switch (c) { + '\'' => if (!self.matchesPattern("''")) { + result.id = .single_quoted; self.index += 1; break; + } else { + self.index += "''".len - 1; }, - '-' => { - count.* += 1; + else => {}, + }, - if (count.* == 3) { - result.id = .DocStart; + .double_quoted => switch (c) { + '"' => { + if (stringMatchesPattern("\\", self.buffer[self.index - 1 ..])) { + self.index += 1; + } else { + result.id = .double_quoted; self.index += 1; break; } }, - else => { - state = .Literal; - }, + else => {}, }, - .Dot => |*count| switch (c) { - '.' => { - count.* += 1; - if (count.* == 3) { - result.id = .DocEnd; - self.index += 1; - break; - } - }, - else => { - state = .Literal; - }, - }, - .Literal => switch (c) { + .literal => switch (c) { '\r', '\n', ' ', '\'', '"', ',', ':', ']', '}' => { - result.id = .Literal; + result.id = .literal; break; }, else => { - result.id = .Literal; + result.id = .literal; }, }, } } - if (state == .Literal and result.id == .Eof) { - result.id = .Literal; + if (self.index >= self.buffer.len) { + switch (state) { + .literal => { + result.id = .literal; + }, + else => {}, + } } result.end = self.index; @@ -263,22 +297,24 @@ fn testExpected(source: []const u8, expected: []const Token.Id) !void { .buffer = source, }; - var token_len: usize = 0; - for (expected) |exp| { - token_len += 1; + var given = std.ArrayList(Token.Id).init(testing.allocator); + defer given.deinit(); + + while (true) { const token = tokenizer.next(); - try testing.expectEqual(exp, token.id); + try given.append(token.id); + if (token.id == .eof) break; } - while (tokenizer.next().id != .Eof) { - token_len += 1; // consume all tokens - } + try testing.expectEqualSlices(Token.Id, expected, given.items); +} - try testing.expectEqual(expected.len, token_len); +test { + std.testing.refAllDecls(@This()); } test "empty doc" { - try testExpected("", &[_]Token.Id{.Eof}); + try testExpected("", &[_]Token.Id{.eof}); } test "empty doc with explicit markers" { @@ -286,7 +322,22 @@ test "empty doc with explicit markers" { \\--- \\... , &[_]Token.Id{ - .DocStart, .NewLine, .DocEnd, .Eof, + .doc_start, .new_line, .doc_end, .eof, + }); +} + +test "empty doc with explicit markers and a directive" { + try testExpected( + \\--- !tbd-v1 + \\... + , &[_]Token.Id{ + .doc_start, + .space, + .tag, + .literal, + .new_line, + .doc_end, + .eof, }); } @@ -296,15 +347,15 @@ test "sequence of values" { \\- 1 \\- 2 , &[_]Token.Id{ - .SeqItemInd, - .Literal, - .NewLine, - .SeqItemInd, - .Literal, - .NewLine, - .SeqItemInd, - .Literal, - .Eof, + .seq_item_ind, + .literal, + .new_line, + .seq_item_ind, + .literal, + .new_line, + .seq_item_ind, + .literal, + .eof, }); } @@ -313,24 +364,24 @@ test "sequence of sequences" { \\- [ val1, val2] \\- [val3, val4 ] , &[_]Token.Id{ - .SeqItemInd, - .FlowSeqStart, - .Space, - .Literal, - .Comma, - .Space, - .Literal, - .FlowSeqEnd, - .NewLine, - .SeqItemInd, - .FlowSeqStart, - .Literal, - .Comma, - .Space, - .Literal, - .Space, - .FlowSeqEnd, - .Eof, + .seq_item_ind, + .flow_seq_start, + .space, + .literal, + .comma, + .space, + .literal, + .flow_seq_end, + .new_line, + .seq_item_ind, + .flow_seq_start, + .literal, + .comma, + .space, + .literal, + .space, + .flow_seq_end, + .eof, }); } @@ -339,16 +390,16 @@ test "mappings" { \\key1: value1 \\key2: value2 , &[_]Token.Id{ - .Literal, - .MapValueInd, - .Space, - .Literal, - .NewLine, - .Literal, - .MapValueInd, - .Space, - .Literal, - .Eof, + .literal, + .map_value_ind, + .space, + .literal, + .new_line, + .literal, + .map_value_ind, + .space, + .literal, + .eof, }); } @@ -357,21 +408,21 @@ test "inline mapped sequence of values" { \\key : [ val1, \\ val2 ] , &[_]Token.Id{ - .Literal, - .Space, - .MapValueInd, - .Space, - .FlowSeqStart, - .Space, - .Literal, - .Comma, - .Space, - .NewLine, - .Space, - .Literal, - .Space, - .FlowSeqEnd, - .Eof, + .literal, + .space, + .map_value_ind, + .space, + .flow_seq_start, + .space, + .literal, + .comma, + .space, + .new_line, + .space, + .literal, + .space, + .flow_seq_end, + .eof, }); } @@ -388,52 +439,50 @@ test "part of tbd" { \\install-name: '/usr/lib/libSystem.B.dylib' \\... , &[_]Token.Id{ - .DocStart, - .Space, - .Tag, - .Literal, - .NewLine, - .Literal, - .MapValueInd, - .Space, - .Literal, - .NewLine, - .Literal, - .MapValueInd, - .Space, - .FlowSeqStart, - .Space, - .Literal, - .Space, - .FlowSeqEnd, - .NewLine, - .NewLine, - .Literal, - .MapValueInd, - .NewLine, - .Space, - .SeqItemInd, - .Literal, - .MapValueInd, - .Space, - .Literal, - .NewLine, - .Space, - .Literal, - .MapValueInd, - .Space, - .Literal, - .NewLine, - .NewLine, - .Literal, - .MapValueInd, - .Space, - .SingleQuote, - .Literal, - .SingleQuote, - .NewLine, - .DocEnd, - .Eof, + .doc_start, + .space, + .tag, + .literal, + .new_line, + .literal, + .map_value_ind, + .space, + .literal, + .new_line, + .literal, + .map_value_ind, + .space, + .flow_seq_start, + .space, + .literal, + .space, + .flow_seq_end, + .new_line, + .new_line, + .literal, + .map_value_ind, + .new_line, + .space, + .seq_item_ind, + .literal, + .map_value_ind, + .space, + .literal, + .new_line, + .space, + .literal, + .map_value_ind, + .space, + .literal, + .new_line, + .new_line, + .literal, + .map_value_ind, + .space, + .single_quoted, + .new_line, + .doc_end, + .eof, }); } @@ -443,18 +492,84 @@ test "Unindented list" { \\- foo: 1 \\c: 1 , &[_]Token.Id{ - .Literal, - .MapValueInd, - .NewLine, - .SeqItemInd, - .Literal, - .MapValueInd, - .Space, - .Literal, - .NewLine, - .Literal, - .MapValueInd, - .Space, - .Literal, + .literal, + .map_value_ind, + .new_line, + .seq_item_ind, + .literal, + .map_value_ind, + .space, + .literal, + .new_line, + .literal, + .map_value_ind, + .space, + .literal, + .eof, + }); +} + +test "escape sequences" { + try testExpected( + \\a: 'here''s an apostrophe' + \\b: "a newline\nand a\ttab" + \\c: "\"here\" and there" + , &[_]Token.Id{ + .literal, + .map_value_ind, + .space, + .single_quoted, + .new_line, + .literal, + .map_value_ind, + .space, + .double_quoted, + .new_line, + .literal, + .map_value_ind, + .space, + .double_quoted, + .eof, + }); +} + +test "comments" { + try testExpected( + \\key: # some comment about the key + \\# first value + \\- val1 + \\# second value + \\- val2 + , &[_]Token.Id{ + .literal, + .map_value_ind, + .space, + .comment, + .new_line, + .comment, + .new_line, + .seq_item_ind, + .literal, + .new_line, + .comment, + .new_line, + .seq_item_ind, + .literal, + .eof, + }); +} + +test "quoted literals" { + try testExpected( + \\'#000000' + \\'[000000' + \\"&someString" + , &[_]Token.Id{ + .single_quoted, + .new_line, + .single_quoted, + .new_line, + .double_quoted, + .eof, }); } diff --git a/src/link/tapi/parse.zig b/src/link/tapi/parse.zig index eb7bb2a0cf..09774cf00a 100644 --- a/src/link/tapi/parse.zig +++ b/src/link/tapi/parse.zig @@ -1,8 +1,7 @@ const std = @import("std"); const assert = std.debug.assert; -const log = std.log.scoped(.tapi); +const log = std.log.scoped(.yaml); const mem = std.mem; -const testing = std.testing; const Allocator = mem.Allocator; const Tokenizer = @import("Tokenizer.zig"); @@ -11,9 +10,9 @@ const TokenIndex = Tokenizer.TokenIndex; const TokenIterator = Tokenizer.TokenIterator; pub const ParseError = error{ + InvalidEscapeSequence, MalformedYaml, NestedDocuments, - UnexpectedTag, UnexpectedEof, UnexpectedToken, Unhandled, @@ -22,6 +21,8 @@ pub const ParseError = error{ pub const Node = struct { tag: Tag, tree: *const Tree, + start: TokenIndex, + end: TokenIndex, pub const Tag = enum { doc, @@ -61,9 +62,12 @@ pub const Node = struct { } pub const Doc = struct { - base: Node = Node{ .tag = Tag.doc, .tree = undefined }, - start: ?TokenIndex = null, - end: ?TokenIndex = null, + base: Node = Node{ + .tag = Tag.doc, + .tree = undefined, + .start = undefined, + .end = undefined, + }, directive: ?TokenIndex = null, value: ?*Node = null, @@ -86,10 +90,8 @@ pub const Node = struct { _ = fmt; if (self.directive) |id| { try std.fmt.format(writer, "{{ ", .{}); - const directive = self.base.tree.tokens[id]; - try std.fmt.format(writer, ".directive = {s}, ", .{ - self.base.tree.source[directive.start..directive.end], - }); + const directive = self.base.tree.getRaw(id, id); + try std.fmt.format(writer, ".directive = {s}, ", .{directive}); } if (self.value) |node| { try std.fmt.format(writer, "{}", .{node}); @@ -101,22 +103,27 @@ pub const Node = struct { }; pub const Map = struct { - base: Node = Node{ .tag = Tag.map, .tree = undefined }, - start: ?TokenIndex = null, - end: ?TokenIndex = null, + base: Node = Node{ + .tag = Tag.map, + .tree = undefined, + .start = undefined, + .end = undefined, + }, values: std.ArrayListUnmanaged(Entry) = .{}, pub const base_tag: Node.Tag = .map; pub const Entry = struct { key: TokenIndex, - value: *Node, + value: ?*Node, }; pub fn deinit(self: *Map, allocator: Allocator) void { for (self.values.items) |entry| { - entry.value.deinit(allocator); - allocator.destroy(entry.value); + if (entry.value) |value| { + value.deinit(allocator); + allocator.destroy(value); + } } self.values.deinit(allocator); } @@ -131,20 +138,24 @@ pub const Node = struct { _ = fmt; try std.fmt.format(writer, "{{ ", .{}); for (self.values.items) |entry| { - const key = self.base.tree.tokens[entry.key]; - try std.fmt.format(writer, "{s} => {}, ", .{ - self.base.tree.source[key.start..key.end], - entry.value, - }); + const key = self.base.tree.getRaw(entry.key, entry.key); + if (entry.value) |value| { + try std.fmt.format(writer, "{s} => {}, ", .{ key, value }); + } else { + try std.fmt.format(writer, "{s} => null, ", .{key}); + } } return std.fmt.format(writer, " }}", .{}); } }; pub const List = struct { - base: Node = Node{ .tag = Tag.list, .tree = undefined }, - start: ?TokenIndex = null, - end: ?TokenIndex = null, + base: Node = Node{ + .tag = Tag.list, + .tree = undefined, + .start = undefined, + .end = undefined, + }, values: std.ArrayListUnmanaged(*Node) = .{}, pub const base_tag: Node.Tag = .list; @@ -174,15 +185,18 @@ pub const Node = struct { }; pub const Value = struct { - base: Node = Node{ .tag = Tag.value, .tree = undefined }, - start: ?TokenIndex = null, - end: ?TokenIndex = null, + base: Node = Node{ + .tag = Tag.value, + .tree = undefined, + .start = undefined, + .end = undefined, + }, + string_value: std.ArrayListUnmanaged(u8) = .{}, pub const base_tag: Node.Tag = .value; pub fn deinit(self: *Value, allocator: Allocator) void { - _ = self; - _ = allocator; + self.string_value.deinit(allocator); } pub fn format( @@ -193,11 +207,8 @@ pub const Node = struct { ) !void { _ = options; _ = fmt; - const start = self.base.tree.tokens[self.start.?]; - const end = self.base.tree.tokens[self.end.?]; - return std.fmt.format(writer, "{s}", .{ - self.base.tree.source[start.start..end.end], - }); + const raw = self.base.tree.getRaw(self.base.start, self.base.end); + return std.fmt.format(writer, "{s}", .{raw}); } }; }; @@ -233,6 +244,21 @@ pub const Tree = struct { self.docs.deinit(self.allocator); } + pub fn getDirective(self: Tree, doc_index: usize) ?[]const u8 { + assert(doc_index < self.docs.items.len); + const doc = self.docs.items[doc_index].cast(Node.Doc) orelse return null; + const id = doc.directive orelse return null; + return self.getRaw(id, id); + } + + pub fn getRaw(self: Tree, start: TokenIndex, end: TokenIndex) []const u8 { + assert(start <= end); + assert(start < self.tokens.len and end < self.tokens.len); + const start_token = self.tokens[start]; + const end_token = self.tokens[end]; + return self.source[start_token.start..end_token.end]; + } + pub fn parse(self: *Tree, source: []const u8) !void { var tokenizer = Tokenizer{ .buffer = source }; var tokens = std.ArrayList(Token).init(self.allocator); @@ -252,8 +278,8 @@ pub const Tree = struct { }); switch (token.id) { - .Eof => break, - .NewLine => { + .eof => break, + .new_line => { line += 1; prev_line_last_col = token.end; }, @@ -272,20 +298,20 @@ pub const Tree = struct { .line_cols = &self.line_cols, }; + parser.eatCommentsAndSpace(&.{}); + while (true) { - if (parser.token_it.peek() == null) return; + parser.eatCommentsAndSpace(&.{}); + const token = parser.token_it.next() orelse break; - const pos = parser.token_it.pos; - const token = parser.token_it.next(); - - log.debug("Next token: {}, {}", .{ pos, token }); + log.debug("(main) next {s}@{d}", .{ @tagName(token.id), parser.token_it.pos - 1 }); switch (token.id) { - .Space, .Comment, .NewLine => {}, - .Eof => break, + .eof => break, else => { - const doc = try parser.doc(pos); - try self.docs.append(self.allocator, &doc.base); + parser.token_it.seekBy(-1); + const doc = try parser.doc(); + try self.docs.append(self.allocator, doc); }, } } @@ -298,355 +324,308 @@ const Parser = struct { token_it: *TokenIterator, line_cols: *const std.AutoHashMap(TokenIndex, LineCol), - fn doc(self: *Parser, start: TokenIndex) ParseError!*Node.Doc { + fn value(self: *Parser) ParseError!?*Node { + self.eatCommentsAndSpace(&.{}); + + const pos = self.token_it.pos; + const token = self.token_it.next() orelse return error.UnexpectedEof; + + log.debug(" next {s}@{d}", .{ @tagName(token.id), pos }); + + switch (token.id) { + .literal => if (self.eatToken(.map_value_ind, &.{ .new_line, .comment })) |_| { + // map + self.token_it.seekTo(pos); + return self.map(); + } else { + // leaf value + self.token_it.seekTo(pos); + return self.leaf_value(); + }, + .single_quoted, .double_quoted => { + // leaf value + self.token_it.seekBy(-1); + return self.leaf_value(); + }, + .seq_item_ind => { + // list + self.token_it.seekBy(-1); + return self.list(); + }, + .flow_seq_start => { + // list + self.token_it.seekBy(-1); + return self.list_bracketed(); + }, + else => return null, + } + } + + fn doc(self: *Parser) ParseError!*Node { const node = try self.allocator.create(Node.Doc); errdefer self.allocator.destroy(node); - node.* = .{ .start = start }; + node.* = .{}; node.base.tree = self.tree; + node.base.start = self.token_it.pos; - self.token_it.seekTo(start); + log.debug("(doc) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); - log.debug("Doc start: {}, {}", .{ start, self.tree.tokens[start] }); - - const explicit_doc: bool = if (self.eatToken(.DocStart)) |_| explicit_doc: { - if (self.eatToken(.Tag)) |_| { - node.directive = try self.expectToken(.Literal); + // Parse header + const explicit_doc: bool = if (self.eatToken(.doc_start, &.{})) |doc_pos| explicit_doc: { + if (self.getCol(doc_pos) > 0) return error.MalformedYaml; + if (self.eatToken(.tag, &.{ .new_line, .comment })) |_| { + node.directive = try self.expectToken(.literal, &.{ .new_line, .comment }); } - _ = try self.expectToken(.NewLine); break :explicit_doc true; } else false; - while (true) { - const pos = self.token_it.pos; - const token = self.token_it.next(); + // Parse value + node.value = try self.value(); + if (node.value == null) { + self.token_it.seekBy(-1); + } + errdefer if (node.value) |val| { + val.deinit(self.allocator); + self.allocator.destroy(val); + }; - log.debug("Next token: {}, {}", .{ pos, token }); - - switch (token.id) { - .Tag => { - return error.UnexpectedTag; - }, - .Literal, .SingleQuote, .DoubleQuote => { - _ = try self.expectToken(.MapValueInd); - const map_node = try self.map(pos); - node.value = &map_node.base; - }, - .SeqItemInd => { - const list_node = try self.list(pos); - node.value = &list_node.base; - }, - .FlowSeqStart => { - const list_node = try self.list_bracketed(pos); - node.value = &list_node.base; - }, - .DocEnd => { - if (explicit_doc) break; - return error.UnexpectedToken; - }, - .DocStart, .Eof => { - self.token_it.seekBy(-1); - break; - }, - else => { - return error.UnexpectedToken; - }, + // Parse footer + footer: { + if (self.eatToken(.doc_end, &.{})) |pos| { + if (!explicit_doc) return error.UnexpectedToken; + if (self.getCol(pos) > 0) return error.MalformedYaml; + node.base.end = pos; + break :footer; } + if (self.eatToken(.doc_start, &.{})) |pos| { + if (!explicit_doc) return error.UnexpectedToken; + if (self.getCol(pos) > 0) return error.MalformedYaml; + self.token_it.seekBy(-1); + node.base.end = pos - 1; + break :footer; + } + if (self.eatToken(.eof, &.{})) |pos| { + node.base.end = pos - 1; + break :footer; + } + return error.UnexpectedToken; } - node.end = self.token_it.pos - 1; + log.debug("(doc) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end }); - log.debug("Doc end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); - - return node; + return &node.base; } - fn map(self: *Parser, start: TokenIndex) ParseError!*Node.Map { + fn map(self: *Parser) ParseError!*Node { const node = try self.allocator.create(Node.Map); errdefer self.allocator.destroy(node); - node.* = .{ .start = start }; + node.* = .{}; node.base.tree = self.tree; + node.base.start = self.token_it.pos; + errdefer { + for (node.values.items) |entry| { + if (entry.value) |val| { + val.deinit(self.allocator); + self.allocator.destroy(val); + } + } + node.values.deinit(self.allocator); + } - self.token_it.seekTo(start); + log.debug("(map) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); - log.debug("Map start: {}, {}", .{ start, self.tree.tokens[start] }); - - const col = self.getCol(start); + const col = self.getCol(node.base.start); while (true) { - self.eatCommentsAndSpace(); + self.eatCommentsAndSpace(&.{}); - // Parse key. + // Parse key const key_pos = self.token_it.pos; - if (self.getCol(key_pos) != col) { + if (self.getCol(key_pos) < col) { break; } - const key = self.token_it.next(); + const key = self.token_it.next() orelse return error.UnexpectedEof; switch (key.id) { - .Literal => {}, - else => { + .literal => {}, + .doc_start, .doc_end, .eof => { self.token_it.seekBy(-1); break; }, + else => { + // TODO key not being a literal + return error.Unhandled; + }, } - log.debug("Map key: {}, '{s}'", .{ key, self.tree.source[key.start..key.end] }); + log.debug("(map) key {s}@{d}", .{ self.tree.getRaw(key_pos, key_pos), key_pos }); // Separator - _ = try self.expectToken(.MapValueInd); + _ = try self.expectToken(.map_value_ind, &.{ .new_line, .comment }); - // Parse value. - const value: *Node = value: { - if (self.eatToken(.NewLine)) |_| { - self.eatCommentsAndSpace(); + // Parse value + const val = try self.value(); + errdefer if (val) |v| { + v.deinit(self.allocator); + self.allocator.destroy(v); + }; - // Explicit, complex value such as list or map. - const value_pos = self.token_it.pos; - const value = self.token_it.next(); - switch (value.id) { - .Literal, .SingleQuote, .DoubleQuote => { - // Assume nested map. - const map_node = try self.map(value_pos); - break :value &map_node.base; - }, - .SeqItemInd => { - // Assume list of values. - const list_node = try self.list(value_pos); - break :value &list_node.base; - }, - else => { - log.err("{}", .{key}); - return error.Unhandled; - }, - } - } else { - self.eatCommentsAndSpace(); - - const value_pos = self.token_it.pos; - const value = self.token_it.next(); - switch (value.id) { - .Literal, .SingleQuote, .DoubleQuote => { - // Assume leaf value. - const leaf_node = try self.leaf_value(value_pos); - break :value &leaf_node.base; - }, - .FlowSeqStart => { - const list_node = try self.list_bracketed(value_pos); - break :value &list_node.base; - }, - else => { - log.err("{}", .{key}); - return error.Unhandled; - }, + if (val) |v| { + if (self.getCol(v.start) < self.getCol(key_pos)) { + return error.MalformedYaml; + } + if (v.cast(Node.Value)) |_| { + if (self.getCol(v.start) == self.getCol(key_pos)) { + return error.MalformedYaml; } } - }; - log.debug("Map value: {}", .{value}); + } try node.values.append(self.allocator, .{ .key = key_pos, - .value = value, + .value = val, }); - - _ = self.eatToken(.NewLine); } - node.end = self.token_it.pos - 1; + node.base.end = self.token_it.pos - 1; - log.debug("Map end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); + log.debug("(map) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end }); - return node; + return &node.base; } - fn list(self: *Parser, start: TokenIndex) ParseError!*Node.List { + fn list(self: *Parser) ParseError!*Node { const node = try self.allocator.create(Node.List); errdefer self.allocator.destroy(node); - node.* = .{ - .start = start, - }; + node.* = .{}; node.base.tree = self.tree; + node.base.start = self.token_it.pos; + errdefer { + for (node.values.items) |val| { + val.deinit(self.allocator); + self.allocator.destroy(val); + } + node.values.deinit(self.allocator); + } - self.token_it.seekTo(start); - - log.debug("List start: {}, {}", .{ start, self.tree.tokens[start] }); - - const col = self.getCol(start); + log.debug("(list) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); while (true) { - self.eatCommentsAndSpace(); + self.eatCommentsAndSpace(&.{}); - if (self.getCol(self.token_it.pos) != col) { + _ = self.eatToken(.seq_item_ind, &.{}) orelse break; + + const val = (try self.value()) orelse return error.MalformedYaml; + try node.values.append(self.allocator, val); + } + + node.base.end = self.token_it.pos - 1; + + log.debug("(list) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end }); + + return &node.base; + } + + fn list_bracketed(self: *Parser) ParseError!*Node { + const node = try self.allocator.create(Node.List); + errdefer self.allocator.destroy(node); + node.* = .{}; + node.base.tree = self.tree; + node.base.start = self.token_it.pos; + errdefer { + for (node.values.items) |val| { + val.deinit(self.allocator); + self.allocator.destroy(val); + } + node.values.deinit(self.allocator); + } + + log.debug("(list) begin {s}@{d}", .{ @tagName(self.tree.tokens[node.base.start].id), node.base.start }); + + _ = try self.expectToken(.flow_seq_start, &.{}); + + while (true) { + self.eatCommentsAndSpace(&.{.comment}); + + if (self.eatToken(.flow_seq_end, &.{.comment})) |pos| { + node.base.end = pos; break; } - _ = self.eatToken(.SeqItemInd) orelse { - break; - }; + _ = self.eatToken(.comma, &.{.comment}); - const pos = self.token_it.pos; - const token = self.token_it.next(); - const value: *Node = value: { - switch (token.id) { - .Literal, .SingleQuote, .DoubleQuote => { - if (self.eatToken(.MapValueInd)) |_| { - // nested map - const map_node = try self.map(pos); - break :value &map_node.base; - } else { - // standalone (leaf) value - const leaf_node = try self.leaf_value(pos); - break :value &leaf_node.base; - } - }, - .FlowSeqStart => { - const list_node = try self.list_bracketed(pos); - break :value &list_node.base; - }, - else => { - log.err("{}", .{token}); - return error.Unhandled; - }, - } - }; - try node.values.append(self.allocator, value); - - _ = self.eatToken(.NewLine); + const val = (try self.value()) orelse return error.MalformedYaml; + try node.values.append(self.allocator, val); } - node.end = self.token_it.pos - 1; + log.debug("(list) end {s}@{d}", .{ @tagName(self.tree.tokens[node.base.end].id), node.base.end }); - log.debug("List end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); - - return node; + return &node.base; } - fn list_bracketed(self: *Parser, start: TokenIndex) ParseError!*Node.List { - const node = try self.allocator.create(Node.List); - errdefer self.allocator.destroy(node); - node.* = .{ .start = start }; - node.base.tree = self.tree; - - self.token_it.seekTo(start); - - log.debug("List start: {}, {}", .{ start, self.tree.tokens[start] }); - - _ = try self.expectToken(.FlowSeqStart); - - while (true) { - _ = self.eatToken(.NewLine); - self.eatCommentsAndSpace(); - - const pos = self.token_it.pos; - const token = self.token_it.next(); - - log.debug("Next token: {}, {}", .{ pos, token }); - - const value: *Node = value: { - switch (token.id) { - .FlowSeqStart => { - const list_node = try self.list_bracketed(pos); - break :value &list_node.base; - }, - .FlowSeqEnd => { - break; - }, - .Literal, .SingleQuote, .DoubleQuote => { - const leaf_node = try self.leaf_value(pos); - _ = self.eatToken(.Comma); - // TODO newline - break :value &leaf_node.base; - }, - else => { - log.err("{}", .{token}); - return error.Unhandled; - }, - } - }; - try node.values.append(self.allocator, value); - } - - node.end = self.token_it.pos - 1; - - log.debug("List end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); - - return node; - } - - fn leaf_value(self: *Parser, start: TokenIndex) ParseError!*Node.Value { + fn leaf_value(self: *Parser) ParseError!*Node { const node = try self.allocator.create(Node.Value); errdefer self.allocator.destroy(node); - node.* = .{ .start = start }; + node.* = .{ .string_value = .{} }; node.base.tree = self.tree; + node.base.start = self.token_it.pos; + errdefer node.string_value.deinit(self.allocator); - self.token_it.seekTo(start); - - log.debug("Leaf start: {}, {}", .{ node.start.?, self.tree.tokens[node.start.?] }); - - parse: { - if (self.eatToken(.SingleQuote)) |_| { - node.start = node.start.? + 1; - while (true) { - const tok = self.token_it.next(); - switch (tok.id) { - .SingleQuote => { - node.end = self.token_it.pos - 2; - break :parse; - }, - .NewLine => return error.UnexpectedToken, - else => {}, - } - } - } - - if (self.eatToken(.DoubleQuote)) |_| { - node.start = node.start.? + 1; - while (true) { - const tok = self.token_it.next(); - switch (tok.id) { - .DoubleQuote => { - node.end = self.token_it.pos - 2; - break :parse; - }, - .NewLine => return error.UnexpectedToken, - else => {}, - } - } - } - - // TODO handle multiline strings in new block scope - while (true) { - const tok = self.token_it.next(); - switch (tok.id) { - .Literal => {}, - .Space => { - const trailing = self.token_it.pos - 2; - self.eatCommentsAndSpace(); - if (self.token_it.peek()) |peek| { - if (peek.id != .Literal) { - node.end = trailing; - break; - } + // TODO handle multiline strings in new block scope + while (self.token_it.next()) |tok| { + switch (tok.id) { + .single_quoted => { + node.base.end = self.token_it.pos - 1; + const raw = self.tree.getRaw(node.base.start, node.base.end); + try self.parseSingleQuoted(node, raw); + break; + }, + .double_quoted => { + node.base.end = self.token_it.pos - 1; + const raw = self.tree.getRaw(node.base.start, node.base.end); + try self.parseDoubleQuoted(node, raw); + break; + }, + .literal => {}, + .space => { + const trailing = self.token_it.pos - 2; + self.eatCommentsAndSpace(&.{}); + if (self.token_it.peek()) |peek| { + if (peek.id != .literal) { + node.base.end = trailing; + const raw = self.tree.getRaw(node.base.start, node.base.end); + try node.string_value.appendSlice(self.allocator, raw); + break; } - }, - else => { - self.token_it.seekBy(-1); - node.end = self.token_it.pos - 1; - break; - }, - } + } + }, + else => { + self.token_it.seekBy(-1); + node.base.end = self.token_it.pos - 1; + const raw = self.tree.getRaw(node.base.start, node.base.end); + try node.string_value.appendSlice(self.allocator, raw); + break; + }, } } - log.debug("Leaf end: {}, {}", .{ node.end.?, self.tree.tokens[node.end.?] }); + log.debug("(leaf) {s}", .{self.tree.getRaw(node.base.start, node.base.end)}); - return node; + return &node.base; } - fn eatCommentsAndSpace(self: *Parser) void { - while (true) { - _ = self.token_it.peek() orelse return; - const token = self.token_it.next(); + fn eatCommentsAndSpace(self: *Parser, comptime exclusions: []const Token.Id) void { + log.debug("eatCommentsAndSpace", .{}); + outer: while (self.token_it.next()) |token| { + log.debug(" (token '{s}')", .{@tagName(token.id)}); switch (token.id) { - .Comment, .Space => {}, + .comment, .space, .new_line => |space| { + inline for (exclusions) |excl| { + if (excl == space) { + self.token_it.seekBy(-1); + break :outer; + } + } else continue; + }, else => { self.token_it.seekBy(-1); break; @@ -655,25 +634,24 @@ const Parser = struct { } } - fn eatToken(self: *Parser, id: Token.Id) ?TokenIndex { - while (true) { - const pos = self.token_it.pos; - _ = self.token_it.peek() orelse return null; - const token = self.token_it.next(); - switch (token.id) { - .Comment, .Space => continue, - else => |next_id| if (next_id == id) { - return pos; - } else { - self.token_it.seekTo(pos); - return null; - }, - } + fn eatToken(self: *Parser, id: Token.Id, comptime exclusions: []const Token.Id) ?TokenIndex { + log.debug("eatToken('{s}')", .{@tagName(id)}); + self.eatCommentsAndSpace(exclusions); + const pos = self.token_it.pos; + const token = self.token_it.next() orelse return null; + if (token.id == id) { + log.debug(" (found at {d})", .{pos}); + return pos; + } else { + log.debug(" (not found)", .{}); + self.token_it.seekBy(-1); + return null; } } - fn expectToken(self: *Parser, id: Token.Id) ParseError!TokenIndex { - return self.eatToken(id) orelse error.UnexpectedToken; + fn expectToken(self: *Parser, id: Token.Id, comptime exclusions: []const Token.Id) ParseError!TokenIndex { + log.debug("expectToken('{s}')", .{@tagName(id)}); + return self.eatToken(id, exclusions) orelse error.UnexpectedToken; } fn getLine(self: *Parser, index: TokenIndex) usize { @@ -683,8 +661,85 @@ const Parser = struct { fn getCol(self: *Parser, index: TokenIndex) usize { return self.line_cols.get(index).?.col; } + + fn parseSingleQuoted(self: *Parser, node: *Node.Value, raw: []const u8) ParseError!void { + assert(raw[0] == '\'' and raw[raw.len - 1] == '\''); + + const raw_no_quotes = raw[1 .. raw.len - 1]; + try node.string_value.ensureTotalCapacity(self.allocator, raw_no_quotes.len); + + var state: enum { + start, + escape, + } = .start; + var index: usize = 0; + + while (index < raw_no_quotes.len) : (index += 1) { + const c = raw_no_quotes[index]; + switch (state) { + .start => switch (c) { + '\'' => { + state = .escape; + }, + else => { + node.string_value.appendAssumeCapacity(c); + }, + }, + .escape => switch (c) { + '\'' => { + state = .start; + node.string_value.appendAssumeCapacity(c); + }, + else => return error.InvalidEscapeSequence, + }, + } + } + } + + fn parseDoubleQuoted(self: *Parser, node: *Node.Value, raw: []const u8) ParseError!void { + assert(raw[0] == '"' and raw[raw.len - 1] == '"'); + + const raw_no_quotes = raw[1 .. raw.len - 1]; + try node.string_value.ensureTotalCapacity(self.allocator, raw_no_quotes.len); + + var state: enum { + start, + escape, + } = .start; + + var index: usize = 0; + while (index < raw_no_quotes.len) : (index += 1) { + const c = raw_no_quotes[index]; + switch (state) { + .start => switch (c) { + '\\' => { + state = .escape; + }, + else => { + node.string_value.appendAssumeCapacity(c); + }, + }, + .escape => switch (c) { + 'n' => { + state = .start; + node.string_value.appendAssumeCapacity('\n'); + }, + 't' => { + state = .start; + node.string_value.appendAssumeCapacity('\t'); + }, + '"' => { + state = .start; + node.string_value.appendAssumeCapacity('"'); + }, + else => return error.InvalidEscapeSequence, + }, + } + } + } }; test { + std.testing.refAllDecls(@This()); _ = @import("parse/test.zig"); } diff --git a/src/link/tapi/parse/test.zig b/src/link/tapi/parse/test.zig index b310a5c0bd..2906801f23 100644 --- a/src/link/tapi/parse/test.zig +++ b/src/link/tapi/parse/test.zig @@ -21,45 +21,45 @@ test "explicit doc" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); const directive = tree.tokens[doc.directive.?]; - try testing.expectEqual(directive.id, .Literal); - try testing.expect(mem.eql(u8, "tapi-tbd", tree.source[directive.start..directive.end])); + try testing.expectEqual(directive.id, .literal); + try testing.expectEqualStrings("tapi-tbd", tree.source[directive.start..directive.end]); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .map); const map = doc.value.?.cast(Node.Map).?; - try testing.expectEqual(map.start.?, 5); - try testing.expectEqual(map.end.?, 14); + try testing.expectEqual(map.base.start, 5); + try testing.expectEqual(map.base.end, 14); try testing.expectEqual(map.values.items.len, 2); { const entry = map.values.items[0]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "tbd-version", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("tbd-version", tree.source[key.start..key.end]); - const value = entry.value.cast(Node.Value).?; - const value_tok = tree.tokens[value.start.?]; - try testing.expectEqual(value_tok.id, .Literal); - try testing.expect(mem.eql(u8, "4", tree.source[value_tok.start..value_tok.end])); + const value = entry.value.?.cast(Node.Value).?; + const value_tok = tree.tokens[value.base.start]; + try testing.expectEqual(value_tok.id, .literal); + try testing.expectEqualStrings("4", tree.source[value_tok.start..value_tok.end]); } { const entry = map.values.items[1]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "abc-version", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("abc-version", tree.source[key.start..key.end]); - const value = entry.value.cast(Node.Value).?; - const value_tok = tree.tokens[value.start.?]; - try testing.expectEqual(value_tok.id, .Literal); - try testing.expect(mem.eql(u8, "5", tree.source[value_tok.start..value_tok.end])); + const value = entry.value.?.cast(Node.Value).?; + const value_tok = tree.tokens[value.base.start]; + try testing.expectEqual(value_tok.id, .literal); + try testing.expectEqualStrings("5", tree.source[value_tok.start..value_tok.end]); } } @@ -77,39 +77,31 @@ test "leaf in quotes" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.directive == null); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .map); const map = doc.value.?.cast(Node.Map).?; - try testing.expectEqual(map.start.?, 0); - try testing.expectEqual(map.end.?, tree.tokens.len - 2); + try testing.expectEqual(map.base.start, 0); + try testing.expectEqual(map.base.end, tree.tokens.len - 2); try testing.expectEqual(map.values.items.len, 3); { const entry = map.values.items[0]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql( - u8, - "key1", - tree.source[key.start..key.end], - )); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("key1", tree.source[key.start..key.end]); - const value = entry.value.cast(Node.Value).?; - const start = tree.tokens[value.start.?]; - const end = tree.tokens[value.end.?]; - try testing.expectEqual(start.id, .Literal); - try testing.expectEqual(end.id, .Literal); - try testing.expect(mem.eql( - u8, - "no quotes", - tree.source[start.start..end.end], - )); + const value = entry.value.?.cast(Node.Value).?; + const start = tree.tokens[value.base.start]; + const end = tree.tokens[value.base.end]; + try testing.expectEqual(start.id, .literal); + try testing.expectEqual(end.id, .literal); + try testing.expectEqualStrings("no quotes", tree.source[start.start..end.end]); } } @@ -128,70 +120,60 @@ test "nested maps" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.directive == null); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .map); const map = doc.value.?.cast(Node.Map).?; - try testing.expectEqual(map.start.?, 0); - try testing.expectEqual(map.end.?, tree.tokens.len - 2); + try testing.expectEqual(map.base.start, 0); + try testing.expectEqual(map.base.end, tree.tokens.len - 2); try testing.expectEqual(map.values.items.len, 2); { const entry = map.values.items[0]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "key1", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("key1", tree.source[key.start..key.end]); - const nested_map = entry.value.cast(Node.Map).?; - try testing.expectEqual(nested_map.start.?, 4); - try testing.expectEqual(nested_map.end.?, 16); + const nested_map = entry.value.?.cast(Node.Map).?; + try testing.expectEqual(nested_map.base.start, 4); + try testing.expectEqual(nested_map.base.end, 16); try testing.expectEqual(nested_map.values.items.len, 2); { const nested_entry = nested_map.values.items[0]; const nested_key = tree.tokens[nested_entry.key]; - try testing.expectEqual(nested_key.id, .Literal); - try testing.expect(mem.eql( - u8, - "key1_1", - tree.source[nested_key.start..nested_key.end], - )); + try testing.expectEqual(nested_key.id, .literal); + try testing.expectEqualStrings("key1_1", tree.source[nested_key.start..nested_key.end]); - const nested_value = nested_entry.value.cast(Node.Value).?; - const nested_value_tok = tree.tokens[nested_value.start.?]; - try testing.expectEqual(nested_value_tok.id, .Literal); - try testing.expect(mem.eql( - u8, + const nested_value = nested_entry.value.?.cast(Node.Value).?; + const nested_value_tok = tree.tokens[nested_value.base.start]; + try testing.expectEqual(nested_value_tok.id, .literal); + try testing.expectEqualStrings( "value1_1", tree.source[nested_value_tok.start..nested_value_tok.end], - )); + ); } { const nested_entry = nested_map.values.items[1]; const nested_key = tree.tokens[nested_entry.key]; - try testing.expectEqual(nested_key.id, .Literal); - try testing.expect(mem.eql( - u8, - "key1_2", - tree.source[nested_key.start..nested_key.end], - )); + try testing.expectEqual(nested_key.id, .literal); + try testing.expectEqualStrings("key1_2", tree.source[nested_key.start..nested_key.end]); - const nested_value = nested_entry.value.cast(Node.Value).?; - const nested_value_tok = tree.tokens[nested_value.start.?]; - try testing.expectEqual(nested_value_tok.id, .Literal); - try testing.expect(mem.eql( - u8, + const nested_value = nested_entry.value.?.cast(Node.Value).?; + const nested_value_tok = tree.tokens[nested_value.base.start]; + try testing.expectEqual(nested_value_tok.id, .literal); + try testing.expectEqualStrings( "value1_2", tree.source[nested_value_tok.start..nested_value_tok.end], - )); + ); } } @@ -199,17 +181,13 @@ test "nested maps" { const entry = map.values.items[1]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "key2", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("key2", tree.source[key.start..key.end]); - const value = entry.value.cast(Node.Value).?; - const value_tok = tree.tokens[value.start.?]; - try testing.expectEqual(value_tok.id, .Literal); - try testing.expect(mem.eql( - u8, - "value2", - tree.source[value_tok.start..value_tok.end], - )); + const value = entry.value.?.cast(Node.Value).?; + const value_tok = tree.tokens[value.base.start]; + try testing.expectEqual(value_tok.id, .literal); + try testing.expectEqualStrings("value2", tree.source[value_tok.start..value_tok.end]); } } @@ -227,46 +205,46 @@ test "map of list of values" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .map); const map = doc.value.?.cast(Node.Map).?; - try testing.expectEqual(map.start.?, 0); - try testing.expectEqual(map.end.?, tree.tokens.len - 2); + try testing.expectEqual(map.base.start, 0); + try testing.expectEqual(map.base.end, tree.tokens.len - 2); try testing.expectEqual(map.values.items.len, 1); const entry = map.values.items[0]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "ints", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("ints", tree.source[key.start..key.end]); - const value = entry.value.cast(Node.List).?; - try testing.expectEqual(value.start.?, 4); - try testing.expectEqual(value.end.?, tree.tokens.len - 2); + const value = entry.value.?.cast(Node.List).?; + try testing.expectEqual(value.base.start, 4); + try testing.expectEqual(value.base.end, tree.tokens.len - 2); try testing.expectEqual(value.values.items.len, 3); { const elem = value.values.items[0].cast(Node.Value).?; - const leaf = tree.tokens[elem.start.?]; - try testing.expectEqual(leaf.id, .Literal); - try testing.expect(mem.eql(u8, "0", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[elem.base.start]; + try testing.expectEqual(leaf.id, .literal); + try testing.expectEqualStrings("0", tree.source[leaf.start..leaf.end]); } { const elem = value.values.items[1].cast(Node.Value).?; - const leaf = tree.tokens[elem.start.?]; - try testing.expectEqual(leaf.id, .Literal); - try testing.expect(mem.eql(u8, "1", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[elem.base.start]; + try testing.expectEqual(leaf.id, .literal); + try testing.expectEqualStrings("1", tree.source[leaf.start..leaf.end]); } { const elem = value.values.items[2].cast(Node.Value).?; - const leaf = tree.tokens[elem.start.?]; - try testing.expectEqual(leaf.id, .Literal); - try testing.expect(mem.eql(u8, "2", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[elem.base.start]; + try testing.expectEqual(leaf.id, .literal); + try testing.expectEqualStrings("2", tree.source[leaf.start..leaf.end]); } } @@ -285,64 +263,64 @@ test "map of list of maps" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .map); const map = doc.value.?.cast(Node.Map).?; - try testing.expectEqual(map.start.?, 0); - try testing.expectEqual(map.end.?, tree.tokens.len - 2); + try testing.expectEqual(map.base.start, 0); + try testing.expectEqual(map.base.end, tree.tokens.len - 2); try testing.expectEqual(map.values.items.len, 1); const entry = map.values.items[0]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "key1", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("key1", tree.source[key.start..key.end]); - const value = entry.value.cast(Node.List).?; - try testing.expectEqual(value.start.?, 3); - try testing.expectEqual(value.end.?, tree.tokens.len - 2); + const value = entry.value.?.cast(Node.List).?; + try testing.expectEqual(value.base.start, 3); + try testing.expectEqual(value.base.end, tree.tokens.len - 2); try testing.expectEqual(value.values.items.len, 3); { const elem = value.values.items[0].cast(Node.Map).?; const nested = elem.values.items[0]; const nested_key = tree.tokens[nested.key]; - try testing.expectEqual(nested_key.id, .Literal); - try testing.expect(mem.eql(u8, "key2", tree.source[nested_key.start..nested_key.end])); + try testing.expectEqual(nested_key.id, .literal); + try testing.expectEqualStrings("key2", tree.source[nested_key.start..nested_key.end]); - const nested_v = nested.value.cast(Node.Value).?; - const leaf = tree.tokens[nested_v.start.?]; - try testing.expectEqual(leaf.id, .Literal); - try testing.expect(mem.eql(u8, "value2", tree.source[leaf.start..leaf.end])); + const nested_v = nested.value.?.cast(Node.Value).?; + const leaf = tree.tokens[nested_v.base.start]; + try testing.expectEqual(leaf.id, .literal); + try testing.expectEqualStrings("value2", tree.source[leaf.start..leaf.end]); } { const elem = value.values.items[1].cast(Node.Map).?; const nested = elem.values.items[0]; const nested_key = tree.tokens[nested.key]; - try testing.expectEqual(nested_key.id, .Literal); - try testing.expect(mem.eql(u8, "key3", tree.source[nested_key.start..nested_key.end])); + try testing.expectEqual(nested_key.id, .literal); + try testing.expectEqualStrings("key3", tree.source[nested_key.start..nested_key.end]); - const nested_v = nested.value.cast(Node.Value).?; - const leaf = tree.tokens[nested_v.start.?]; - try testing.expectEqual(leaf.id, .Literal); - try testing.expect(mem.eql(u8, "value3", tree.source[leaf.start..leaf.end])); + const nested_v = nested.value.?.cast(Node.Value).?; + const leaf = tree.tokens[nested_v.base.start]; + try testing.expectEqual(leaf.id, .literal); + try testing.expectEqualStrings("value3", tree.source[leaf.start..leaf.end]); } { const elem = value.values.items[2].cast(Node.Map).?; const nested = elem.values.items[0]; const nested_key = tree.tokens[nested.key]; - try testing.expectEqual(nested_key.id, .Literal); - try testing.expect(mem.eql(u8, "key4", tree.source[nested_key.start..nested_key.end])); + try testing.expectEqual(nested_key.id, .literal); + try testing.expectEqualStrings("key4", tree.source[nested_key.start..nested_key.end]); - const nested_v = nested.value.cast(Node.Value).?; - const leaf = tree.tokens[nested_v.start.?]; - try testing.expectEqual(leaf.id, .Literal); - try testing.expect(mem.eql(u8, "value4", tree.source[leaf.start..leaf.end])); + const nested_v = nested.value.?.cast(Node.Value).?; + const leaf = tree.tokens[nested_v.base.start]; + try testing.expectEqual(leaf.id, .literal); + try testing.expectEqualStrings("value4", tree.source[leaf.start..leaf.end]); } } @@ -360,15 +338,15 @@ test "list of lists" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .list); const list = doc.value.?.cast(Node.List).?; - try testing.expectEqual(list.start.?, 0); - try testing.expectEqual(list.end.?, tree.tokens.len - 2); + try testing.expectEqual(list.base.start, 0); + try testing.expectEqual(list.base.end, tree.tokens.len - 2); try testing.expectEqual(list.values.items.len, 3); { @@ -379,22 +357,22 @@ test "list of lists" { { try testing.expectEqual(nested.values.items[0].tag, .value); const value = nested.values.items[0].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "name", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("name", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(nested.values.items[1].tag, .value); const value = nested.values.items[1].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "hr", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("hr", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(nested.values.items[2].tag, .value); const value = nested.values.items[2].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "avg", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("avg", tree.source[leaf.start..leaf.end]); } } @@ -406,23 +384,23 @@ test "list of lists" { { try testing.expectEqual(nested.values.items[0].tag, .value); const value = nested.values.items[0].cast(Node.Value).?; - const start = tree.tokens[value.start.?]; - const end = tree.tokens[value.end.?]; - try testing.expect(mem.eql(u8, "Mark McGwire", tree.source[start.start..end.end])); + const start = tree.tokens[value.base.start]; + const end = tree.tokens[value.base.end]; + try testing.expectEqualStrings("Mark McGwire", tree.source[start.start..end.end]); } { try testing.expectEqual(nested.values.items[1].tag, .value); const value = nested.values.items[1].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "65", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("65", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(nested.values.items[2].tag, .value); const value = nested.values.items[2].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "0.278", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("0.278", tree.source[leaf.start..leaf.end]); } } @@ -434,23 +412,23 @@ test "list of lists" { { try testing.expectEqual(nested.values.items[0].tag, .value); const value = nested.values.items[0].cast(Node.Value).?; - const start = tree.tokens[value.start.?]; - const end = tree.tokens[value.end.?]; - try testing.expect(mem.eql(u8, "Sammy Sosa", tree.source[start.start..end.end])); + const start = tree.tokens[value.base.start]; + const end = tree.tokens[value.base.end]; + try testing.expectEqualStrings("Sammy Sosa", tree.source[start.start..end.end]); } { try testing.expectEqual(nested.values.items[1].tag, .value); const value = nested.values.items[1].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "63", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("63", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(nested.values.items[2].tag, .value); const value = nested.values.items[2].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "0.288", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("0.288", tree.source[leaf.start..leaf.end]); } } } @@ -467,36 +445,36 @@ test "inline list" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .list); const list = doc.value.?.cast(Node.List).?; - try testing.expectEqual(list.start.?, 0); - try testing.expectEqual(list.end.?, tree.tokens.len - 2); + try testing.expectEqual(list.base.start, 0); + try testing.expectEqual(list.base.end, tree.tokens.len - 2); try testing.expectEqual(list.values.items.len, 3); { try testing.expectEqual(list.values.items[0].tag, .value); const value = list.values.items[0].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "name", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("name", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(list.values.items[1].tag, .value); const value = list.values.items[1].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "hr", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("hr", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(list.values.items[2].tag, .value); const value = list.values.items[2].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "avg", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("avg", tree.source[leaf.start..leaf.end]); } } @@ -514,45 +492,273 @@ test "inline list as mapping value" { try testing.expectEqual(tree.docs.items.len, 1); const doc = tree.docs.items[0].cast(Node.Doc).?; - try testing.expectEqual(doc.start.?, 0); - try testing.expectEqual(doc.end.?, tree.tokens.len - 2); + try testing.expectEqual(doc.base.start, 0); + try testing.expectEqual(doc.base.end, tree.tokens.len - 2); try testing.expect(doc.value != null); try testing.expectEqual(doc.value.?.tag, .map); const map = doc.value.?.cast(Node.Map).?; - try testing.expectEqual(map.start.?, 0); - try testing.expectEqual(map.end.?, tree.tokens.len - 2); + try testing.expectEqual(map.base.start, 0); + try testing.expectEqual(map.base.end, tree.tokens.len - 2); try testing.expectEqual(map.values.items.len, 1); const entry = map.values.items[0]; const key = tree.tokens[entry.key]; - try testing.expectEqual(key.id, .Literal); - try testing.expect(mem.eql(u8, "key", tree.source[key.start..key.end])); + try testing.expectEqual(key.id, .literal); + try testing.expectEqualStrings("key", tree.source[key.start..key.end]); - const list = entry.value.cast(Node.List).?; - try testing.expectEqual(list.start.?, 4); - try testing.expectEqual(list.end.?, tree.tokens.len - 2); + const list = entry.value.?.cast(Node.List).?; + try testing.expectEqual(list.base.start, 4); + try testing.expectEqual(list.base.end, tree.tokens.len - 2); try testing.expectEqual(list.values.items.len, 3); { try testing.expectEqual(list.values.items[0].tag, .value); const value = list.values.items[0].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "name", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("name", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(list.values.items[1].tag, .value); const value = list.values.items[1].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "hr", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("hr", tree.source[leaf.start..leaf.end]); } { try testing.expectEqual(list.values.items[2].tag, .value); const value = list.values.items[2].cast(Node.Value).?; - const leaf = tree.tokens[value.start.?]; - try testing.expect(mem.eql(u8, "avg", tree.source[leaf.start..leaf.end])); + const leaf = tree.tokens[value.base.start]; + try testing.expectEqualStrings("avg", tree.source[leaf.start..leaf.end]); } } + +fn parseSuccess(comptime source: []const u8) !void { + var tree = Tree.init(testing.allocator); + defer tree.deinit(); + try tree.parse(source); +} + +fn parseError(comptime source: []const u8, err: parse.ParseError) !void { + var tree = Tree.init(testing.allocator); + defer tree.deinit(); + try testing.expectError(err, tree.parse(source)); +} + +test "empty doc with spaces and comments" { + try parseSuccess( + \\ + \\ + \\ # this is a comment in a weird place + \\# and this one is too + ); +} + +test "comment between --- and ! in document start" { + try parseError( + \\--- # what is it? + \\! + , error.UnexpectedToken); +} + +test "correct doc start with tag" { + try parseSuccess( + \\--- !some-tag + \\ + ); +} + +test "doc close without explicit doc open" { + try parseError( + \\ + \\ + \\# something cool + \\... + , error.UnexpectedToken); +} + +test "doc open and close are ok" { + try parseSuccess( + \\--- + \\# first doc + \\ + \\ + \\--- + \\# second doc + \\ + \\ + \\... + ); +} + +test "doc with a single string is ok" { + try parseSuccess( + \\a string of some sort + \\ + ); +} + +test "explicit doc with a single string is ok" { + try parseSuccess( + \\--- !anchor + \\# nothing to see here except one string + \\ # not a lot to go on with + \\a single string + \\... + ); +} + +test "doc with two string is bad" { + try parseError( + \\first + \\second + \\# this should fail already + , error.UnexpectedToken); +} + +test "single quote string can have new lines" { + try parseSuccess( + \\'what is this + \\ thing?' + ); +} + +test "single quote string on one line is fine" { + try parseSuccess( + \\'here''s an apostrophe' + ); +} + +test "double quote string can have new lines" { + try parseSuccess( + \\"what is this + \\ thing?" + ); +} + +test "double quote string on one line is fine" { + try parseSuccess( + \\"a newline\nand a\ttab" + ); +} + +test "map with key and value literals" { + try parseSuccess( + \\key1: val1 + \\key2 : val2 + ); +} + +test "map of maps" { + try parseSuccess( + \\ + \\# the first key + \\key1: + \\ # the first subkey + \\ key1_1: 0 + \\ key1_2: 1 + \\# the second key + \\key2: + \\ key2_1: -1 + \\ key2_2: -2 + \\# the end of map + ); +} + +test "map value indicator needs to be on the same line" { + try parseError( + \\a + \\ : b + , error.UnexpectedToken); +} + +test "value needs to be indented" { + try parseError( + \\a: + \\b + , error.MalformedYaml); +} + +test "comment between a key and a value is fine" { + try parseSuccess( + \\a: + \\ # this is a value + \\ b + ); +} + +test "simple list" { + try parseSuccess( + \\# first el + \\- a + \\# second el + \\- b + \\# third el + \\- c + ); +} + +test "list indentation matters" { + try parseSuccess( + \\ - a + \\- b + ); + + try parseSuccess( + \\- a + \\ - b + ); +} + +test "unindented list is fine too" { + try parseSuccess( + \\a: + \\- 0 + \\- 1 + ); +} + +test "empty values in a map" { + try parseSuccess( + \\a: + \\b: + \\- 0 + ); +} + +test "weirdly nested map of maps of lists" { + try parseSuccess( + \\a: + \\ b: + \\ - 0 + \\ - 1 + ); +} + +test "square brackets denote a list" { + try parseSuccess( + \\[ a, + \\ b, c ] + ); +} + +test "empty list" { + try parseSuccess( + \\[ ] + ); +} + +test "comment within a bracketed list is an error" { + try parseError( + \\[ # something + \\] + , error.MalformedYaml); +} + +test "mixed ints with floats in a list" { + try parseSuccess( + \\[0, 1.0] + ); +} diff --git a/src/link/tapi/yaml.zig b/src/link/tapi/yaml.zig index d4136b35d3..0fc165003a 100644 --- a/src/link/tapi/yaml.zig +++ b/src/link/tapi/yaml.zig @@ -2,8 +2,7 @@ const std = @import("std"); const assert = std.debug.assert; const math = std.math; const mem = std.mem; -const testing = std.testing; -const log = std.log.scoped(.tapi); +const log = std.log.scoped(.yaml); const Allocator = mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; @@ -17,22 +16,15 @@ const ParseError = parse.ParseError; pub const YamlError = error{ UnexpectedNodeType, + DuplicateMapKey, OutOfMemory, + CannotEncodeValue, } || ParseError || std.fmt.ParseIntError; -pub const ValueType = enum { - empty, - int, - float, - string, - list, - map, -}; - pub const List = []Value; -pub const Map = std.StringArrayHashMap(Value); +pub const Map = std.StringHashMap(Value); -pub const Value = union(ValueType) { +pub const Value = union(enum) { empty, int: i64, float: f64, @@ -70,9 +62,7 @@ pub const Value = union(ValueType) { should_inline_first_key: bool = false, }; - pub const StringifyError = std.os.WriteError; - - pub fn stringify(self: Value, writer: anytype, args: StringifyArgs) StringifyError!void { + pub fn stringify(self: Value, writer: anytype, args: StringifyArgs) anyerror!void { switch (self) { .empty => return, .int => |int| return writer.print("{}", .{int}), @@ -83,7 +73,7 @@ pub const Value = union(ValueType) { if (len == 0) return; const first = list[0]; - if (first.is_compound()) { + if (first.isCompound()) { for (list, 0..) |elem, i| { try writer.writeByteNTimes(' ', args.indentation); try writer.writeAll("- "); @@ -108,20 +98,23 @@ pub const Value = union(ValueType) { try writer.writeAll(" ]"); }, .map => |map| { - const keys = map.keys(); - const len = keys.len; + const len = map.count(); if (len == 0) return; - for (keys, 0..) |key, i| { + var i: usize = 0; + var it = map.iterator(); + while (it.next()) |entry| { + const key = entry.key_ptr.*; + const value = entry.value_ptr.*; + if (!args.should_inline_first_key or i != 0) { try writer.writeByteNTimes(' ', args.indentation); } try writer.print("{s}: ", .{key}); - const value = map.get(key) orelse unreachable; const should_inline = blk: { - if (!value.is_compound()) break :blk true; - if (value == .list and value.list.len > 0 and !value.list[0].is_compound()) break :blk true; + if (!value.isCompound()) break :blk true; + if (value == .list and value.list.len > 0 and !value.list[0].isCompound()) break :blk true; break :blk false; }; @@ -137,35 +130,44 @@ pub const Value = union(ValueType) { if (i < len - 1) { try writer.writeByte('\n'); } + + i += 1; } }, } } - fn is_compound(self: Value) bool { + fn isCompound(self: Value) bool { return switch (self) { .list, .map => true, else => false, }; } - fn fromNode(arena: Allocator, tree: *const Tree, node: *const Node, type_hint: ?ValueType) YamlError!Value { + fn fromNode(arena: Allocator, tree: *const Tree, node: *const Node) YamlError!Value { if (node.cast(Node.Doc)) |doc| { const inner = doc.value orelse { // empty doc return Value{ .empty = {} }; }; - return Value.fromNode(arena, tree, inner, null); + return Value.fromNode(arena, tree, inner); } else if (node.cast(Node.Map)) |map| { - var out_map = std.StringArrayHashMap(Value).init(arena); - try out_map.ensureUnusedCapacity(map.values.items.len); + // TODO use ContextAdapted HashMap and do not duplicate keys, intern + // in a contiguous string buffer. + var out_map = std.StringHashMap(Value).init(arena); + try out_map.ensureUnusedCapacity(math.cast(u32, map.values.items.len) orelse return error.Overflow); for (map.values.items) |entry| { - const key_tok = tree.tokens[entry.key]; - const key = try arena.dupe(u8, tree.source[key_tok.start..key_tok.end]); - const value = try Value.fromNode(arena, tree, entry.value, null); - - out_map.putAssumeCapacityNoClobber(key, value); + const key = try arena.dupe(u8, tree.getRaw(entry.key, entry.key)); + const gop = out_map.getOrPutAssumeCapacity(key); + if (gop.found_existing) { + return error.DuplicateMapKey; + } + const value = if (entry.value) |value| + try Value.fromNode(arena, tree, value) + else + .empty; + gop.value_ptr.* = value; } return Value{ .map = out_map }; @@ -173,56 +175,124 @@ pub const Value = union(ValueType) { var out_list = std.ArrayList(Value).init(arena); try out_list.ensureUnusedCapacity(list.values.items.len); - if (list.values.items.len > 0) { - const hint = if (list.values.items[0].cast(Node.Value)) |value| hint: { - const start = tree.tokens[value.start.?]; - const end = tree.tokens[value.end.?]; - const raw = tree.source[start.start..end.end]; - _ = std.fmt.parseInt(i64, raw, 10) catch { - _ = std.fmt.parseFloat(f64, raw) catch { - break :hint ValueType.string; - }; - break :hint ValueType.float; - }; - break :hint ValueType.int; - } else null; - - for (list.values.items) |elem| { - const value = try Value.fromNode(arena, tree, elem, hint); - out_list.appendAssumeCapacity(value); - } + for (list.values.items) |elem| { + const value = try Value.fromNode(arena, tree, elem); + out_list.appendAssumeCapacity(value); } return Value{ .list = try out_list.toOwnedSlice() }; } else if (node.cast(Node.Value)) |value| { - const start = tree.tokens[value.start.?]; - const end = tree.tokens[value.end.?]; - const raw = tree.source[start.start..end.end]; - - if (type_hint) |hint| { - return switch (hint) { - .int => Value{ .int = try std.fmt.parseInt(i64, raw, 10) }, - .float => Value{ .float = try std.fmt.parseFloat(f64, raw) }, - .string => Value{ .string = try arena.dupe(u8, raw) }, - else => unreachable, - }; - } + const raw = tree.getRaw(node.start, node.end); try_int: { // TODO infer base for int const int = std.fmt.parseInt(i64, raw, 10) catch break :try_int; return Value{ .int = int }; } + try_float: { const float = std.fmt.parseFloat(f64, raw) catch break :try_float; return Value{ .float = float }; } - return Value{ .string = try arena.dupe(u8, raw) }; + + return Value{ .string = try arena.dupe(u8, value.string_value.items) }; } else { log.err("Unexpected node type: {}", .{node.tag}); return error.UnexpectedNodeType; } } + + fn encode(arena: Allocator, input: anytype) YamlError!?Value { + switch (@typeInfo(@TypeOf(input))) { + .ComptimeInt, + .Int, + => return Value{ .int = math.cast(i64, input) orelse return error.Overflow }, + + .Float => return Value{ .float = math.lossyCast(f64, input) }, + + .Struct => |info| if (info.is_tuple) { + var list = std.ArrayList(Value).init(arena); + errdefer list.deinit(); + try list.ensureTotalCapacityPrecise(info.fields.len); + + inline for (info.fields) |field| { + if (try encode(arena, @field(input, field.name))) |value| { + list.appendAssumeCapacity(value); + } + } + + return Value{ .list = try list.toOwnedSlice() }; + } else { + var map = Map.init(arena); + errdefer map.deinit(); + try map.ensureTotalCapacity(info.fields.len); + + inline for (info.fields) |field| { + if (try encode(arena, @field(input, field.name))) |value| { + const key = try arena.dupe(u8, field.name); + map.putAssumeCapacityNoClobber(key, value); + } + } + + return Value{ .map = map }; + }, + + .Union => |info| if (info.tag_type) |tag_type| { + inline for (info.fields) |field| { + if (@field(tag_type, field.name) == input) { + return try encode(arena, @field(input, field.name)); + } + } else unreachable; + } else return error.UntaggedUnion, + + .Array => return encode(arena, &input), + + .Pointer => |info| switch (info.size) { + .One => switch (@typeInfo(info.child)) { + .Array => |child_info| { + const Slice = []const child_info.child; + return encode(arena, @as(Slice, input)); + }, + else => { + @compileError("Unhandled type: {s}" ++ @typeName(info.child)); + }, + }, + .Slice => { + if (info.child == u8) { + return Value{ .string = try arena.dupe(u8, input) }; + } + + var list = std.ArrayList(Value).init(arena); + errdefer list.deinit(); + try list.ensureTotalCapacityPrecise(input.len); + + for (input) |elem| { + if (try encode(arena, elem)) |value| { + list.appendAssumeCapacity(value); + } else { + log.err("Could not encode value in a list: {any}", .{elem}); + return error.CannotEncodeValue; + } + } + + return Value{ .list = try list.toOwnedSlice() }; + }, + else => { + @compileError("Unhandled type: {s}" ++ @typeName(@TypeOf(input))); + }, + }, + + // TODO we should probably have an option to encode `null` and also + // allow for some default value too. + .Optional => return if (input) |val| encode(arena, val) else null, + + .Null => return null, + + else => { + @compileError("Unhandled type: {s}" ++ @typeName(@TypeOf(input))); + }, + } + } }; pub const Yaml = struct { @@ -234,30 +304,18 @@ pub const Yaml = struct { self.arena.deinit(); } - pub fn stringify(self: Yaml, writer: anytype) !void { - for (self.docs.items) |doc| { - // if (doc.directive) |directive| { - // try writer.print("--- !{s}\n", .{directive}); - // } - try doc.stringify(writer, .{}); - // if (doc.directive != null) { - // try writer.writeAll("...\n"); - // } - } - } - pub fn load(allocator: Allocator, source: []const u8) !Yaml { var arena = ArenaAllocator.init(allocator); - const arena_allocator = arena.allocator(); + errdefer arena.deinit(); - var tree = Tree.init(arena_allocator); + var tree = Tree.init(arena.allocator()); try tree.parse(source); - var docs = std.ArrayList(Value).init(arena_allocator); - try docs.ensureUnusedCapacity(tree.docs.items.len); + var docs = std.ArrayList(Value).init(arena.allocator()); + try docs.ensureTotalCapacityPrecise(tree.docs.items.len); for (tree.docs.items) |node| { - const value = try Value.fromNode(arena_allocator, &tree, node, null); + const value = try Value.fromNode(arena.allocator(), &tree, node); docs.appendAssumeCapacity(value); } @@ -316,17 +374,19 @@ pub const Yaml = struct { fn parseValue(self: *Yaml, comptime T: type, value: Value) Error!T { return switch (@typeInfo(T)) { - .Int => math.cast(T, try value.asInt()) orelse error.Overflow, - .Float => math.lossyCast(T, try value.asFloat()), + .Int => math.cast(T, try value.asInt()) orelse return error.Overflow, + .Float => if (value.asFloat()) |float| { + return math.lossyCast(T, float); + } else |_| { + return math.lossyCast(T, try value.asInt()); + }, .Struct => self.parseStruct(T, try value.asMap()), .Union => self.parseUnion(T, value), .Array => self.parseArray(T, try value.asList()), - .Pointer => { - if (value.asList()) |list| { - return self.parsePointer(T, .{ .list = list }); - } else |_| { - return self.parsePointer(T, .{ .string = try value.asString() }); - } + .Pointer => if (value.asList()) |list| { + return self.parsePointer(T, .{ .list = list }); + } else |_| { + return self.parsePointer(T, .{ .string = try value.asString() }); }, .Void => error.TypeMismatch, .Optional => unreachable, @@ -372,7 +432,7 @@ pub const Yaml = struct { } const unwrapped = value orelse { - log.debug("missing struct field: {s}: {s}", .{ field.name, @typeName(field.type) }); + log.err("missing struct field: {s}: {s}", .{ field.name, @typeName(field.type) }); return error.StructFieldMissing; }; @field(parsed, field.name) = try self.parseValue(field.type, unwrapped); @@ -387,8 +447,7 @@ pub const Yaml = struct { switch (ptr_info.size) { .Slice => { - const child_info = @typeInfo(ptr_info.child); - if (child_info == .Int and child_info.Int.bits == 8) { + if (ptr_info.child == u8) { return value.asString(); } @@ -413,315 +472,36 @@ pub const Yaml = struct { return parsed; } + + pub fn stringify(self: Yaml, writer: anytype) !void { + for (self.docs.items, 0..) |doc, i| { + try writer.writeAll("---"); + if (self.tree.?.getDirective(i)) |directive| { + try writer.print(" !{s}", .{directive}); + } + try writer.writeByte('\n'); + try doc.stringify(writer, .{}); + try writer.writeByte('\n'); + } + try writer.writeAll("...\n"); + } }; +pub fn stringify(allocator: Allocator, input: anytype, writer: anytype) !void { + var arena = ArenaAllocator.init(allocator); + defer arena.deinit(); + + var maybe_value = try Value.encode(arena.allocator(), input); + + if (maybe_value) |value| { + // TODO should we output as an explicit doc? + // How can allow the user to specify? + try value.stringify(writer, .{}); + } +} + test { - testing.refAllDecls(@This()); -} - -test "simple list" { - const source = - \\- a - \\- b - \\- c - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const list = yaml.docs.items[0].list; - try testing.expectEqual(list.len, 3); - - try testing.expect(mem.eql(u8, list[0].string, "a")); - try testing.expect(mem.eql(u8, list[1].string, "b")); - try testing.expect(mem.eql(u8, list[2].string, "c")); -} - -test "simple list typed as array of strings" { - const source = - \\- a - \\- b - \\- c - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const arr = try yaml.parse([3][]const u8); - try testing.expectEqual(arr.len, 3); - try testing.expect(mem.eql(u8, arr[0], "a")); - try testing.expect(mem.eql(u8, arr[1], "b")); - try testing.expect(mem.eql(u8, arr[2], "c")); -} - -test "simple list typed as array of ints" { - const source = - \\- 0 - \\- 1 - \\- 2 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const arr = try yaml.parse([3]u8); - try testing.expectEqual(arr.len, 3); - try testing.expectEqual(arr[0], 0); - try testing.expectEqual(arr[1], 1); - try testing.expectEqual(arr[2], 2); -} - -test "list of mixed sign integer" { - const source = - \\- 0 - \\- -1 - \\- 2 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const arr = try yaml.parse([3]i8); - try testing.expectEqual(arr.len, 3); - try testing.expectEqual(arr[0], 0); - try testing.expectEqual(arr[1], -1); - try testing.expectEqual(arr[2], 2); -} - -test "simple map untyped" { - const source = - \\a: 0 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const map = yaml.docs.items[0].map; - try testing.expect(map.contains("a")); - try testing.expectEqual(map.get("a").?.int, 0); -} - -test "simple map untyped with a list of maps" { - const source = - \\a: 0 - \\b: - \\ - foo: 1 - \\ bar: 2 - \\ - foo: 3 - \\ bar: 4 - \\c: 1 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const map = yaml.docs.items[0].map; - try testing.expect(map.contains("a")); - try testing.expect(map.contains("b")); - try testing.expect(map.contains("c")); - try testing.expectEqual(map.get("a").?.int, 0); - try testing.expectEqual(map.get("c").?.int, 1); - try testing.expectEqual(map.get("b").?.list[0].map.get("foo").?.int, 1); - try testing.expectEqual(map.get("b").?.list[0].map.get("bar").?.int, 2); - try testing.expectEqual(map.get("b").?.list[1].map.get("foo").?.int, 3); - try testing.expectEqual(map.get("b").?.list[1].map.get("bar").?.int, 4); -} - -test "simple map untyped with a list of maps. no indent" { - const source = - \\b: - \\- foo: 1 - \\c: 1 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const map = yaml.docs.items[0].map; - try testing.expect(map.contains("b")); - try testing.expect(map.contains("c")); - try testing.expectEqual(map.get("c").?.int, 1); - try testing.expectEqual(map.get("b").?.list[0].map.get("foo").?.int, 1); -} - -test "simple map untyped with a list of maps. no indent 2" { - const source = - \\a: 0 - \\b: - \\- foo: 1 - \\ bar: 2 - \\- foo: 3 - \\ bar: 4 - \\c: 1 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectEqual(yaml.docs.items.len, 1); - - const map = yaml.docs.items[0].map; - try testing.expect(map.contains("a")); - try testing.expect(map.contains("b")); - try testing.expect(map.contains("c")); - try testing.expectEqual(map.get("a").?.int, 0); - try testing.expectEqual(map.get("c").?.int, 1); - try testing.expectEqual(map.get("b").?.list[0].map.get("foo").?.int, 1); - try testing.expectEqual(map.get("b").?.list[0].map.get("bar").?.int, 2); - try testing.expectEqual(map.get("b").?.list[1].map.get("foo").?.int, 3); - try testing.expectEqual(map.get("b").?.list[1].map.get("bar").?.int, 4); -} - -test "simple map typed" { - const source = - \\a: 0 - \\b: hello there - \\c: 'wait, what?' - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - const simple = try yaml.parse(struct { a: usize, b: []const u8, c: []const u8 }); - try testing.expectEqual(simple.a, 0); - try testing.expect(mem.eql(u8, simple.b, "hello there")); - try testing.expect(mem.eql(u8, simple.c, "wait, what?")); -} - -test "typed nested structs" { - const source = - \\a: - \\ b: hello there - \\ c: 'wait, what?' - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - const simple = try yaml.parse(struct { - a: struct { - b: []const u8, - c: []const u8, - }, - }); - try testing.expect(mem.eql(u8, simple.a.b, "hello there")); - try testing.expect(mem.eql(u8, simple.a.c, "wait, what?")); -} - -test "multidoc typed as a slice of structs" { - const source = - \\--- - \\a: 0 - \\--- - \\a: 1 - \\... - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - { - const result = try yaml.parse([2]struct { a: usize }); - try testing.expectEqual(result.len, 2); - try testing.expectEqual(result[0].a, 0); - try testing.expectEqual(result[1].a, 1); - } - - { - const result = try yaml.parse([]struct { a: usize }); - try testing.expectEqual(result.len, 2); - try testing.expectEqual(result[0].a, 0); - try testing.expectEqual(result[1].a, 1); - } -} - -test "multidoc typed as a struct is an error" { - const source = - \\--- - \\a: 0 - \\--- - \\b: 1 - \\... - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize })); - try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { b: usize })); - try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize, b: usize })); -} - -test "multidoc typed as a slice of structs with optionals" { - const source = - \\--- - \\a: 0 - \\c: 1.0 - \\--- - \\a: 1 - \\b: different field - \\... - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - const result = try yaml.parse([]struct { a: usize, b: ?[]const u8, c: ?f16 }); - try testing.expectEqual(result.len, 2); - - try testing.expectEqual(result[0].a, 0); - try testing.expect(result[0].b == null); - try testing.expect(result[0].c != null); - try testing.expectEqual(result[0].c.?, 1.0); - - try testing.expectEqual(result[1].a, 1); - try testing.expect(result[1].b != null); - try testing.expect(mem.eql(u8, result[1].b.?, "different field")); - try testing.expect(result[1].c == null); -} - -test "empty yaml can be represented as void" { - const source = ""; - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - const result = try yaml.parse(void); - try testing.expect(@TypeOf(result) == void); -} - -test "nonempty yaml cannot be represented as void" { - const source = - \\a: b - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(void)); -} - -test "typed array size mismatch" { - const source = - \\- 0 - \\- 0 - ; - - var yaml = try Yaml.load(testing.allocator, source); - defer yaml.deinit(); - - try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([1]usize)); - try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([5]usize)); + std.testing.refAllDecls(Tokenizer); + std.testing.refAllDecls(parse); + _ = @import("yaml/test.zig"); } diff --git a/src/link/tapi/yaml/test.zig b/src/link/tapi/yaml/test.zig new file mode 100644 index 0000000000..8db9435885 --- /dev/null +++ b/src/link/tapi/yaml/test.zig @@ -0,0 +1,475 @@ +const std = @import("std"); +const mem = std.mem; +const testing = std.testing; + +const yaml_mod = @import("../yaml.zig"); +const Yaml = yaml_mod.Yaml; + +test "simple list" { + const source = + \\- a + \\- b + \\- c + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const list = yaml.docs.items[0].list; + try testing.expectEqual(list.len, 3); + + try testing.expectEqualStrings("a", list[0].string); + try testing.expectEqualStrings("b", list[1].string); + try testing.expectEqualStrings("c", list[2].string); +} + +test "simple list typed as array of strings" { + const source = + \\- a + \\- b + \\- c + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const arr = try yaml.parse([3][]const u8); + try testing.expectEqual(3, arr.len); + try testing.expectEqualStrings("a", arr[0]); + try testing.expectEqualStrings("b", arr[1]); + try testing.expectEqualStrings("c", arr[2]); +} + +test "simple list typed as array of ints" { + const source = + \\- 0 + \\- 1 + \\- 2 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const arr = try yaml.parse([3]u8); + try testing.expectEqualSlices(u8, &[_]u8{ 0, 1, 2 }, &arr); +} + +test "list of mixed sign integer" { + const source = + \\- 0 + \\- -1 + \\- 2 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const arr = try yaml.parse([3]i8); + try testing.expectEqualSlices(i8, &[_]i8{ 0, -1, 2 }, &arr); +} + +test "simple map untyped" { + const source = + \\a: 0 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("a")); + try testing.expectEqual(@as(i64, 0), map.get("a").?.int); +} + +test "simple map untyped with a list of maps" { + const source = + \\a: 0 + \\b: + \\ - foo: 1 + \\ bar: 2 + \\ - foo: 3 + \\ bar: 4 + \\c: 1 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("a")); + try testing.expect(map.contains("b")); + try testing.expect(map.contains("c")); + try testing.expectEqual(@as(i64, 0), map.get("a").?.int); + try testing.expectEqual(@as(i64, 1), map.get("c").?.int); + try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 2), map.get("b").?.list[0].map.get("bar").?.int); + try testing.expectEqual(@as(i64, 3), map.get("b").?.list[1].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 4), map.get("b").?.list[1].map.get("bar").?.int); +} + +test "simple map untyped with a list of maps. no indent" { + const source = + \\b: + \\- foo: 1 + \\c: 1 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("b")); + try testing.expect(map.contains("c")); + try testing.expectEqual(@as(i64, 1), map.get("c").?.int); + try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int); +} + +test "simple map untyped with a list of maps. no indent 2" { + const source = + \\a: 0 + \\b: + \\- foo: 1 + \\ bar: 2 + \\- foo: 3 + \\ bar: 4 + \\c: 1 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("a")); + try testing.expect(map.contains("b")); + try testing.expect(map.contains("c")); + try testing.expectEqual(@as(i64, 0), map.get("a").?.int); + try testing.expectEqual(@as(i64, 1), map.get("c").?.int); + try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 2), map.get("b").?.list[0].map.get("bar").?.int); + try testing.expectEqual(@as(i64, 3), map.get("b").?.list[1].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 4), map.get("b").?.list[1].map.get("bar").?.int); +} + +test "simple map typed" { + const source = + \\a: 0 + \\b: hello there + \\c: 'wait, what?' + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { a: usize, b: []const u8, c: []const u8 }); + try testing.expectEqual(@as(usize, 0), simple.a); + try testing.expectEqualStrings("hello there", simple.b); + try testing.expectEqualStrings("wait, what?", simple.c); +} + +test "typed nested structs" { + const source = + \\a: + \\ b: hello there + \\ c: 'wait, what?' + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { + a: struct { + b: []const u8, + c: []const u8, + }, + }); + try testing.expectEqualStrings("hello there", simple.a.b); + try testing.expectEqualStrings("wait, what?", simple.a.c); +} + +test "single quoted string" { + const source = + \\- 'hello' + \\- 'here''s an escaped quote' + \\- 'newlines and tabs\nare not\tsupported' + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const arr = try yaml.parse([3][]const u8); + try testing.expectEqual(arr.len, 3); + try testing.expectEqualStrings("hello", arr[0]); + try testing.expectEqualStrings("here's an escaped quote", arr[1]); + try testing.expectEqualStrings("newlines and tabs\\nare not\\tsupported", arr[2]); +} + +test "double quoted string" { + const source = + \\- "hello" + \\- "\"here\" are some escaped quotes" + \\- "newlines and tabs\nare\tsupported" + \\- "let's have + \\some fun!" + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const arr = try yaml.parse([4][]const u8); + try testing.expectEqual(arr.len, 4); + try testing.expectEqualStrings("hello", arr[0]); + try testing.expectEqualStrings( + \\"here" are some escaped quotes + , arr[1]); + try testing.expectEqualStrings( + \\newlines and tabs + \\are supported + , arr[2]); + try testing.expectEqualStrings( + \\let's have + \\some fun! + , arr[3]); +} + +test "multidoc typed as a slice of structs" { + const source = + \\--- + \\a: 0 + \\--- + \\a: 1 + \\... + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + { + const result = try yaml.parse([2]struct { a: usize }); + try testing.expectEqual(result.len, 2); + try testing.expectEqual(result[0].a, 0); + try testing.expectEqual(result[1].a, 1); + } + + { + const result = try yaml.parse([]struct { a: usize }); + try testing.expectEqual(result.len, 2); + try testing.expectEqual(result[0].a, 0); + try testing.expectEqual(result[1].a, 1); + } +} + +test "multidoc typed as a struct is an error" { + const source = + \\--- + \\a: 0 + \\--- + \\b: 1 + \\... + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize })); + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { b: usize })); + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize, b: usize })); +} + +test "multidoc typed as a slice of structs with optionals" { + const source = + \\--- + \\a: 0 + \\c: 1.0 + \\--- + \\a: 1 + \\b: different field + \\... + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const result = try yaml.parse([]struct { a: usize, b: ?[]const u8, c: ?f16 }); + try testing.expectEqual(result.len, 2); + + try testing.expectEqual(result[0].a, 0); + try testing.expect(result[0].b == null); + try testing.expect(result[0].c != null); + try testing.expectEqual(result[0].c.?, 1.0); + + try testing.expectEqual(result[1].a, 1); + try testing.expect(result[1].b != null); + try testing.expectEqualStrings("different field", result[1].b.?); + try testing.expect(result[1].c == null); +} + +test "empty yaml can be represented as void" { + const source = ""; + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + const result = try yaml.parse(void); + try testing.expect(@TypeOf(result) == void); +} + +test "nonempty yaml cannot be represented as void" { + const source = + \\a: b + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(void)); +} + +test "typed array size mismatch" { + const source = + \\- 0 + \\- 0 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([1]usize)); + try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([5]usize)); +} + +test "comments" { + const source = + \\ + \\key: # this is the key + \\# first value + \\ + \\- val1 + \\ + \\# second value + \\- val2 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { + key: []const []const u8, + }); + try testing.expect(simple.key.len == 2); + try testing.expectEqualStrings("val1", simple.key[0]); + try testing.expectEqualStrings("val2", simple.key[1]); +} + +test "promote ints to floats in a list mixed numeric types" { + const source = + \\a_list: [0, 1.0] + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { + a_list: []const f64, + }); + try testing.expectEqualSlices(f64, &[_]f64{ 0.0, 1.0 }, simple.a_list); +} + +test "demoting floats to ints in a list is an error" { + const source = + \\a_list: [0, 1.0] + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(error.TypeMismatch, yaml.parse(struct { + a_list: []const u64, + })); +} + +test "duplicate map keys" { + const source = + \\a: b + \\a: c + ; + try testing.expectError(error.DuplicateMapKey, Yaml.load(testing.allocator, source)); +} + +fn testStringify(expected: []const u8, input: anytype) !void { + var output = std.ArrayList(u8).init(testing.allocator); + defer output.deinit(); + + try yaml_mod.stringify(testing.allocator, input, output.writer()); + try testing.expectEqualStrings(expected, output.items); +} + +test "stringify an int" { + try testStringify("128", @as(u32, 128)); +} + +test "stringify a simple struct" { + try testStringify( + \\a: 1 + \\b: 2 + \\c: 2.5 + , struct { a: i64, b: f64, c: f64 }{ .a = 1, .b = 2.0, .c = 2.5 }); +} + +test "stringify a struct with an optional" { + try testStringify( + \\a: 1 + \\b: 2 + \\c: 2.5 + , struct { a: i64, b: ?f64, c: f64 }{ .a = 1, .b = 2.0, .c = 2.5 }); + + try testStringify( + \\a: 1 + \\c: 2.5 + , struct { a: i64, b: ?f64, c: f64 }{ .a = 1, .b = null, .c = 2.5 }); +} + +test "stringify a struct with all optionals" { + try testStringify("", struct { a: ?i64, b: ?f64 }{ .a = null, .b = null }); +} + +test "stringify an optional" { + try testStringify("", null); + try testStringify("", @as(?u64, null)); +} + +test "stringify a union" { + const Dummy = union(enum) { + x: u64, + y: f64, + }; + try testStringify("a: 1", struct { a: Dummy }{ .a = .{ .x = 1 } }); + try testStringify("a: 2.1", struct { a: Dummy }{ .a = .{ .y = 2.1 } }); +} + +test "stringify a string" { + try testStringify("a: name", struct { a: []const u8 }{ .a = "name" }); + try testStringify("name", "name"); +} + +test "stringify a list" { + try testStringify("[ 1, 2, 3 ]", @as([]const u64, &.{ 1, 2, 3 })); + try testStringify("[ 1, 2, 3 ]", .{ @as(i64, 1), 2, 3 }); + try testStringify("[ 1, name, 3 ]", .{ 1, "name", 3 }); + + const arr: [3]i64 = .{ 1, 2, 3 }; + try testStringify("[ 1, 2, 3 ]", arr); +} From ab2b70f6c1f7261ae801be5118cb43e04b7d6a75 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 22:14:26 +0200 Subject: [PATCH 170/216] tapi: update to latest Apple changes --- src/link/tapi.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/tapi.zig b/src/link/tapi.zig index c97332984f..98ee2ed5dd 100644 --- a/src/link/tapi.zig +++ b/src/link/tapi.zig @@ -36,7 +36,7 @@ pub const TbdV3 = struct { pub const TbdV4 = struct { tbd_version: u3, targets: []const []const u8, - uuids: []const struct { + uuids: ?[]const struct { target: []const u8, value: []const u8, }, From a0a854b1fc5e64a07b2026ac0668f8d417ab6bf1 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 1 Apr 2023 08:33:13 +0200 Subject: [PATCH 171/216] libc: update macOS libSystem.13.tbd --- lib/libc/darwin/libSystem.13.tbd | 879 ++++++++----------------------- 1 file changed, 207 insertions(+), 672 deletions(-) diff --git a/lib/libc/darwin/libSystem.13.tbd b/lib/libc/darwin/libSystem.13.tbd index 76e25874ae..d29feaa1e4 100644 --- a/lib/libc/darwin/libSystem.13.tbd +++ b/lib/libc/darwin/libSystem.13.tbd @@ -2,21 +2,8 @@ tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 085E3D5D-7871-3E9E-A097-AAD940171411 - - target: x86_64-maccatalyst - value: 085E3D5D-7871-3E9E-A097-AAD940171411 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: B54723A8-A25C-3D6C-A51B-2B8BBA733DD3 - - target: arm64e-maccatalyst - value: B54723A8-A25C-3D6C-A51B-2B8BBA733DD3 install-name: '/usr/lib/libSystem.B.dylib' -current-version: 1319 +current-version: 1319.100.3 reexported-libraries: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -57,21 +44,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: A7D96CB6-7562-3C14-8B54-ED5E484B54E2 - - target: x86_64-maccatalyst - value: A7D96CB6-7562-3C14-8B54-ED5E484B54E2 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 7A88909B-ED36-360D-ACE9-81107AF0FE14 - - target: arm64e-maccatalyst - value: 7A88909B-ED36-360D-ACE9-81107AF0FE14 install-name: '/usr/lib/system/libcache.dylib' -current-version: 90 +current-version: 92 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -95,21 +69,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 6E120635-E858-30FE-95F6-64D90E33095D - - target: x86_64-maccatalyst - value: 6E120635-E858-30FE-95F6-64D90E33095D - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 452A7C15-97FA-32A0-B514-744E117E2B39 - - target: arm64e-maccatalyst - value: 452A7C15-97FA-32A0-B514-744E117E2B39 install-name: '/usr/lib/system/libcommonCrypto.dylib' -current-version: 60198.60.2 +current-version: 65535.100.4 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -189,13 +150,6 @@ exports: --- !tapi-tbd tbd-version: 4 targets: [ x86_64-macos, arm64-macos, arm64e-macos ] -uuids: - - target: x86_64-macos - value: E9412018-811C-36B7-9F58-6471398EE465 - - target: arm64-macos - value: 954CFCC0-97A8-329B-B5AA-FF9046F3E94F - - target: arm64e-macos - value: 9F57BC0A-3F18-3F00-B772-40B6A8616E26 install-name: '/usr/lib/system/libcompiler_rt.dylib' current-version: 103.1 parent-umbrella: @@ -424,19 +378,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: F92F30BA-35BE-3ED9-B562-FBEC1B7089B5 - - target: x86_64-maccatalyst - value: F92F30BA-35BE-3ED9-B562-FBEC1B7089B5 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 3689048E-9EC2-32D9-B833-B5EDE2839092 - - target: arm64e-maccatalyst - value: 3689048E-9EC2-32D9-B833-B5EDE2839092 install-name: '/usr/lib/system/libcopyfile.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -452,21 +393,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 1A8A8D34-268F-3D42-936A-8A0029817E22 - - target: x86_64-maccatalyst - value: 1A8A8D34-268F-3D42-936A-8A0029817E22 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: E32C0A9B-EDD0-376D-A504-A06C215E89FE - - target: arm64e-maccatalyst - value: E32C0A9B-EDD0-376D-A504-A06C215E89FE install-name: '/usr/lib/system/libcorecrypto.dylib' -current-version: 1386.60.8 +current-version: 1387.100.43 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -766,21 +694,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 6282E528-6A67-334B-ACCF-1F8FD89369BD - - target: x86_64-maccatalyst - value: 6282E528-6A67-334B-ACCF-1F8FD89369BD - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 191028D2-0477-3EBC-9EEF-A85ACAFC7193 - - target: arm64e-maccatalyst - value: 191028D2-0477-3EBC-9EEF-A85ACAFC7193 install-name: '/usr/lib/system/libdispatch.dylib' -current-version: 1412 +current-version: 1415.100.11 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -942,19 +857,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 6F97B8FD-BA81-3779-ADB2-5ECD91F42B75 - - target: x86_64-maccatalyst - value: 6F97B8FD-BA81-3779-ADB2-5ECD91F42B75 - - target: arm64-macos - value: 427D321B-B30E-367F-8E2C-1DA6FD2D0962 - - target: arm64-maccatalyst - value: 427D321B-B30E-367F-8E2C-1DA6FD2D0962 - - target: arm64e-macos - value: C1700833-CCA0-3BA5-8614-C149347F5503 - - target: arm64e-maccatalyst - value: C1700833-CCA0-3BA5-8614-C149347F5503 install-name: '/usr/lib/system/libdyld.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1040,19 +942,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 4C623CBE-6FF4-3731-A647-6EEF7A6F51C7 - - target: x86_64-maccatalyst - value: 4C623CBE-6FF4-3731-A647-6EEF7A6F51C7 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: B63E11DD-4648-3355-A51C-C1B650654C0F - - target: arm64e-maccatalyst - value: B63E11DD-4648-3355-A51C-C1B650654C0F install-name: '/usr/lib/system/libkeymgr.dylib' current-version: 31 parent-umbrella: @@ -1070,21 +959,8 @@ exports: --- !tapi-tbd tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ] -uuids: - - target: x86_64-macos - value: 632C478C-AAF6-3330-AA8E-0D0FCA4C6237 - - target: x86_64-maccatalyst - value: 632C478C-AAF6-3330-AA8E-0D0FCA4C6237 - - target: arm64-macos - value: F71DA09E-609F-3C9A-95BF-22B22CFAD5A5 - - target: arm64-maccatalyst - value: F71DA09E-609F-3C9A-95BF-22B22CFAD5A5 - - target: arm64e-macos - value: 471DA066-B65F-36B1-93B7-243C71F8838B - - target: arm64e-maccatalyst - value: 471DA066-B65F-36B1-93B7-243C71F8838B install-name: '/usr/lib/system/libmacho.dylib' -current-version: 1001.2 +current-version: 1005 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64e-macos ] umbrella: System @@ -1130,21 +1006,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 9C3DCECF-ED9C-3F0F-9E9C-28DC842D4D65 - - target: x86_64-maccatalyst - value: 9C3DCECF-ED9C-3F0F-9E9C-28DC842D4D65 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: A052DB52-9ECA-39EC-8DD4-05A0856579B7 - - target: arm64e-maccatalyst - value: A052DB52-9ECA-39EC-8DD4-05A0856579B7 install-name: '/usr/lib/system/libquarantine.dylib' -current-version: 146.60.2 +current-version: 147.100.8 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1188,21 +1051,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: A7C519E4-A2A5-33E1-B9D6-52951921392F - - target: x86_64-maccatalyst - value: A7C519E4-A2A5-33E1-B9D6-52951921392F - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: E785FBDF-82C9-3642-A38D-EDB07D118303 - - target: arm64e-maccatalyst - value: E785FBDF-82C9-3642-A38D-EDB07D118303 install-name: '/usr/lib/system/libremovefile.dylib' -current-version: 63 +current-version: 68 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1219,19 +1069,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: D32DFE04-D5D4-3BD7-B9B5-9ED721B993EE - - target: x86_64-maccatalyst - value: D32DFE04-D5D4-3BD7-B9B5-9ED721B993EE - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 1E8F925A-501E-32BD-9BE3-2EE5FDEA8818 - - target: arm64e-maccatalyst - value: 1E8F925A-501E-32BD-9BE3-2EE5FDEA8818 install-name: '/usr/lib/system/libsystem_asl.dylib' current-version: 395 parent-umbrella: @@ -1313,21 +1150,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 942C1938-B1BC-3B74-912C-D7E7E2B6DC72 - - target: x86_64-maccatalyst - value: 942C1938-B1BC-3B74-912C-D7E7E2B6DC72 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: B126606C-8D07-3F9D-AD5E-9864CF11D901 - - target: arm64e-maccatalyst - value: B126606C-8D07-3F9D-AD5E-9864CF11D901 install-name: '/usr/lib/system/libsystem_blocks.dylib' -current-version: 84 +current-version: 87 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1345,38 +1169,25 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 376F7CB7-6DD2-3E00-976F-77DD755BDB0D - - target: x86_64-maccatalyst - value: 376F7CB7-6DD2-3E00-976F-77DD755BDB0D - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 756CD0D2-3241-3A74-8C59-02632DCEE221 - - target: arm64e-maccatalyst - value: 756CD0D2-3241-3A74-8C59-02632DCEE221 install-name: '/usr/lib/system/libsystem_c.dylib' -current-version: 1534.40.2 +current-version: 1534.100.14 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] umbrella: System exports: - targets: [ x86_64-macos, x86_64-maccatalyst ] - symbols: [ '___opendir2$INODE64', ___strtopx, '__readdir_unlocked$INODE64', - '__seekdir$INODE64', '_alphasort$INODE64', '_daemon$1050', - '_fdopendir$INODE64', _fstatx64_np, '_fstatx_np$INODE64', - '_fts_children$INODE64', '_fts_close$INODE64', '_fts_open$INODE64', - '_fts_open_b$INODE64', '_fts_read$INODE64', '_fts_set$INODE64', - '_ftw$INODE64', '_getmntinfo$INODE64', _getmntinfo64, '_getmntinfo_r_np$INODE64', - '_glob$INODE64', '_glob_b$INODE64', _lstatx64_np, '_lstatx_np$INODE64', - '_nftw$INODE64', '_opendir$INODE64', '_readdir$INODE64', '_readdir_r$INODE64', + symbols: [ '___opendir2$INODE64', '__readdir_unlocked$INODE64', '__seekdir$INODE64', + '_alphasort$INODE64', '_daemon$1050', '_fdopendir$INODE64', + _fstatx64_np, '_fstatx_np$INODE64', '_fts_children$INODE64', + '_fts_close$INODE64', '_fts_open$INODE64', '_fts_open_b$INODE64', + '_fts_read$INODE64', '_fts_set$INODE64', '_ftw$INODE64', '_getmntinfo$INODE64', + _getmntinfo64, '_getmntinfo_r_np$INODE64', '_glob$INODE64', + '_glob_b$INODE64', _lstatx64_np, '_lstatx_np$INODE64', '_nftw$INODE64', + '_opendir$INODE64', '_readdir$INODE64', '_readdir_r$INODE64', '_rewinddir$INODE64', '_scandir$INODE64', '_scandir_b$INODE64', - '_seekdir$INODE64', _statx64_np, '_statx_np$INODE64', '_telldir$INODE64', - mcount ] + '_seekdir$INODE64', _statx64_np, '_statx_np$INODE64', _strtoencf80_l, + '_telldir$INODE64', mcount ] - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] symbols: [ '$ld$weak$os10.11$_basename_r', '$ld$weak$os10.11$_clock_getres', @@ -1387,26 +1198,24 @@ exports: __CurrentRuneLocale, __DefaultRuneLocale, __Exit, __NSGetArgc, __NSGetArgv, __NSGetEnviron, __NSGetMachExecuteHeader, __NSGetProgname, __PathLocale, __Read_RuneMagi, ___Balloc_D2A, ___Bfree_D2A, - ___ULtod_D2A, ____mb_cur_max, ____mb_cur_max_l, ____runetype, - ____runetype_l, ____tolower, ____tolower_l, ____toupper, ____toupper_l, - ___add_ovflpage, ___addel, ___any_on_D2A, ___assert_rtn, ___b2d_D2A, - ___big_delete, ___big_insert, ___big_keydata, ___big_return, - ___big_split, ___bigtens_D2A, ___bt_close, ___bt_cmp, ___bt_defcmp, - ___bt_defpfx, ___bt_delete, ___bt_dleaf, ___bt_fd, ___bt_free, - ___bt_get, ___bt_new, ___bt_open, ___bt_pgin, ___bt_pgout, - ___bt_put, ___bt_ret, ___bt_search, ___bt_seq, ___bt_setcur, - ___bt_split, ___bt_sync, ___buf_free, ___call_hash, ___cleanup, - ___cmp_D2A, ___collate_equiv_match, ___collate_load_error, - ___collate_lookup, ___collate_lookup_l, ___copybits_D2A, ___cxa_atexit, - ___cxa_finalize, ___cxa_finalize_ranges, ___cxa_thread_atexit, - ___d2b_D2A, ___dbpanic, ___decrement_D2A, ___default_hash, - ___default_utx, ___delpair, ___diff_D2A, ___dtoa, ___expand_table, - ___fflush, ___fgetwc, ___find_bigpair, ___find_last_page, - ___fix_locale_grouping_str, ___fread, ___free_ovflpage, ___freedtoa, - ___gdtoa, ___gdtoa_locks, ___get_buf, ___get_page, ___gethex_D2A, - ___getonlyClocaleconv, ___hash_open, ___hdtoa, ___hexdig_D2A, - ___hexdig_init_D2A, ___hexnan_D2A, ___hi0bits_D2A, ___hldtoa, - ___i2b_D2A, ___ibitmap, ___increment_D2A, ___isctype, ___istype, + ____mb_cur_max, ____mb_cur_max_l, ____runetype, ____runetype_l, + ____tolower, ____tolower_l, ____toupper, ____toupper_l, ___add_ovflpage, + ___addel, ___any_on_D2A, ___assert_rtn, ___b2d_D2A, ___big_delete, + ___big_insert, ___big_keydata, ___big_return, ___big_split, + ___bigtens_D2A, ___bt_close, ___bt_cmp, ___bt_defcmp, ___bt_defpfx, + ___bt_delete, ___bt_dleaf, ___bt_fd, ___bt_free, ___bt_get, + ___bt_new, ___bt_open, ___bt_pgin, ___bt_pgout, ___bt_put, + ___bt_ret, ___bt_search, ___bt_seq, ___bt_setcur, ___bt_split, + ___bt_sync, ___buf_free, ___call_hash, ___cleanup, ___cmp_D2A, + ___collate_equiv_match, ___collate_load_error, ___collate_lookup, + ___collate_lookup_l, ___copybits_D2A, ___cxa_atexit, ___cxa_finalize, + ___cxa_finalize_ranges, ___cxa_thread_atexit, ___d2b_D2A, + ___dbpanic, ___default_hash, ___default_utx, ___delpair, ___diff_D2A, + ___dtoa, ___expand_table, ___fflush, ___fgetwc, ___find_bigpair, + ___find_last_page, ___fix_locale_grouping_str, ___fread, ___free_ovflpage, + ___freedtoa, ___gdtoa, ___gdtoa_locks, ___get_buf, ___get_page, + ___getonlyClocaleconv, ___hash_open, ___hdtoa, ___hi0bits_D2A, + ___hldtoa, ___i2b_D2A, ___ibitmap, ___isctype, ___istype, ___istype_l, ___ldtoa, ___libc_init, ___lo0bits_D2A, ___log2, ___lshift_D2A, ___maskrune, ___maskrune_l, ___match_D2A, ___mb_cur_max, ___mb_sb_limit, ___memccpy_chk, ___memcpy_chk, ___memmove_chk, @@ -1417,53 +1226,54 @@ exports: ___rec_iput, ___rec_open, ___rec_put, ___rec_ret, ___rec_search, ___rec_seq, ___rec_sync, ___rec_vmap, ___rec_vpipe, ___reclaim_buf, ___rshift_D2A, ___rv_alloc_D2A, ___s2b_D2A, ___sF, ___sclose, - ___sdidinit, ___set_ones_D2A, ___setonlyClocaleconv, ___sflags, - ___sflush, ___sfp, ___sfvwrite, ___sglue, ___sinit, ___slbexpand, - ___smakebuf, ___snprintf_chk, ___snprintf_object_size_chk, - ___split_page, ___sprintf_chk, ___sprintf_object_size_chk, - ___sread, ___srefill, ___srget, ___sseek, ___stack_chk_fail, - ___stack_chk_guard, ___stderrp, ___stdinp, ___stdoutp, ___stpcpy_chk, - ___stpncpy_chk, ___strcat_chk, ___strcp_D2A, ___strcpy_chk, - ___strlcat_chk, ___strlcpy_chk, ___strncat_chk, ___strncpy_chk, - ___strtodg, ___strtopdd, ___sum_D2A, ___svfscanf, ___swbuf, - ___swhatbuf, ___swrite, ___swsetup, ___tens_D2A, ___tinytens_D2A, - ___tolower, ___tolower_l, ___toupper, ___toupper_l, ___trailz_D2A, - ___ulp_D2A, ___ungetc, ___ungetwc, ___vsnprintf_chk, ___vsprintf_chk, - ___wcwidth, ___wcwidth_l, __allocenvstate, __atexit_receipt, - __c_locale, __cleanup, __closeutx, __copyenv, __cthread_init_routine, - __deallocenvstate, __endutxent, __flockfile_debug_stub, __fseeko, - __ftello, __fwalk, __getenvp, __getutxent, __getutxid, __getutxline, - __inet_aton_check, __init_clock_port, __int_to_time, __libc_fork_child, - __libc_initializer, __long_to_time, __mkpath_np, __mktemp, - __openutx, __os_assert_log, __os_assert_log_ctx, __os_assumes_log, - __os_assumes_log_ctx, __os_avoid_tail_call, __os_crash, __os_crash_callback, - __os_crash_fmt, __os_crash_msg, __os_debug_log, __os_debug_log_error_offset, - __os_debug_log_error_str, __putenvp, __pututxline, __rand48_add, - __rand48_mult, __rand48_seed, __readdir_unlocked, __reclaim_telldir, - __seekdir, __setenvp, __setutxent, __sigaction_nobind, __sigintr, - __signal_nobind, __sigvec_nobind, __sread, __sseek, __subsystem_init, - __swrite, __time32_to_time, __time64_to_time, __time_to_int, - __time_to_long, __time_to_time32, __time_to_time64, __unsetenvp, - __utmpxname, _a64l, _abort, _abort_report_np, _abs, _acl_add_flag_np, - _acl_add_perm, _acl_calc_mask, _acl_clear_flags_np, _acl_clear_perms, - _acl_copy_entry, _acl_copy_ext, _acl_copy_ext_native, _acl_copy_int, - _acl_copy_int_native, _acl_create_entry, _acl_create_entry_np, - _acl_delete_def_file, _acl_delete_entry, _acl_delete_fd_np, - _acl_delete_file_np, _acl_delete_flag_np, _acl_delete_link_np, - _acl_delete_perm, _acl_dup, _acl_free, _acl_from_text, _acl_get_entry, - _acl_get_fd, _acl_get_fd_np, _acl_get_file, _acl_get_flag_np, - _acl_get_flagset_np, _acl_get_link_np, _acl_get_perm_np, _acl_get_permset, - _acl_get_permset_mask_np, _acl_get_qualifier, _acl_get_tag_type, - _acl_init, _acl_maximal_permset_mask_np, _acl_set_fd, _acl_set_fd_np, - _acl_set_file, _acl_set_flagset_np, _acl_set_link_np, _acl_set_permset, - _acl_set_permset_mask_np, _acl_set_qualifier, _acl_set_tag_type, - _acl_size, _acl_to_text, _acl_valid, _acl_valid_fd_np, _acl_valid_file_np, - _acl_valid_link, _addr2ascii, _alarm, _alphasort, _arc4random, - _arc4random_addrandom, _arc4random_buf, _arc4random_stir, - _arc4random_uniform, _ascii2addr, _asctime, _asctime_r, _asprintf, - _asprintf_l, _asxprintf, _asxprintf_exec, _atexit, _atexit_b, - _atof, _atof_l, _atoi, _atoi_l, _atol, _atol_l, _atoll, _atoll_l, - _backtrace, _backtrace_async, _backtrace_from_fp, _backtrace_image_offsets, + ___sdidinit, ___setonlyClocaleconv, ___sflags, ___sflush, + ___sfp, ___sfvwrite, ___sglue, ___sinit, ___slbexpand, ___smakebuf, + ___snprintf_chk, ___snprintf_object_size_chk, ___split_page, + ___sprintf_chk, ___sprintf_object_size_chk, ___sread, ___srefill, + ___srget, ___sseek, ___stack_chk_fail, ___stack_chk_guard, + ___stderrp, ___stdinp, ___stdoutp, ___stpcpy_chk, ___stpncpy_chk, + ___strcat_chk, ___strcp_D2A, ___strcpy_chk, ___strlcat_chk, + ___strlcpy_chk, ___strncat_chk, ___strncpy_chk, ___sum_D2A, + ___svfscanf, ___swbuf, ___swhatbuf, ___swrite, ___swsetup, + ___tens_D2A, ___tinytens_D2A, ___tolower, ___tolower_l, ___toupper, + ___toupper_l, ___trailz_D2A, ___ulp_D2A, ___ungetc, ___ungetwc, + ___vsnprintf_chk, ___vsprintf_chk, ___wcwidth, ___wcwidth_l, + __allocenvstate, __atexit_receipt, __c_locale, __cleanup, + __closeutx, __copyenv, __cthread_init_routine, __deallocenvstate, + __endutxent, __flockfile_debug_stub, __fseeko, __ftello, __fwalk, + __getenvp, __getutxent, __getutxid, __getutxline, __inet_aton_check, + __init_clock_port, __int_to_time, __libc_fork_child, __libc_fork_parent, + __libc_fork_prepare, __libc_initializer, __long_to_time, __mkpath_np, + __mktemp, __openutx, __os_assert_log, __os_assert_log_ctx, + __os_assumes_log, __os_assumes_log_ctx, __os_avoid_tail_call, + __os_crash, __os_crash_callback, __os_crash_fmt, __os_crash_msg, + __os_debug_log, __os_debug_log_error_offset, __os_debug_log_error_str, + __putenvp, __pututxline, __rand48_add, __rand48_mult, __rand48_seed, + __readdir_unlocked, __reclaim_telldir, __seekdir, __setenvp, + __setutxent, __sigaction_nobind, __sigintr, __signal_nobind, + __sigvec_nobind, __sread, __sseek, __subsystem_init, __swrite, + __time32_to_time, __time64_to_time, __time_to_int, __time_to_long, + __time_to_time32, __time_to_time64, __unsetenvp, __utmpxname, + _a64l, _abort, _abort_report_np, _abs, _acl_add_flag_np, _acl_add_perm, + _acl_calc_mask, _acl_clear_flags_np, _acl_clear_perms, _acl_copy_entry, + _acl_copy_ext, _acl_copy_ext_native, _acl_copy_int, _acl_copy_int_native, + _acl_create_entry, _acl_create_entry_np, _acl_delete_def_file, + _acl_delete_entry, _acl_delete_fd_np, _acl_delete_file_np, + _acl_delete_flag_np, _acl_delete_link_np, _acl_delete_perm, + _acl_dup, _acl_free, _acl_from_text, _acl_get_entry, _acl_get_fd, + _acl_get_fd_np, _acl_get_file, _acl_get_flag_np, _acl_get_flagset_np, + _acl_get_link_np, _acl_get_perm_np, _acl_get_permset, _acl_get_permset_mask_np, + _acl_get_qualifier, _acl_get_tag_type, _acl_init, _acl_maximal_permset_mask_np, + _acl_set_fd, _acl_set_fd_np, _acl_set_file, _acl_set_flagset_np, + _acl_set_link_np, _acl_set_permset, _acl_set_permset_mask_np, + _acl_set_qualifier, _acl_set_tag_type, _acl_size, _acl_to_text, + _acl_valid, _acl_valid_fd_np, _acl_valid_file_np, _acl_valid_link, + _addr2ascii, _alarm, _alphasort, _arc4random, _arc4random_addrandom, + _arc4random_buf, _arc4random_stir, _arc4random_uniform, _ascii2addr, + _asctime, _asctime_r, _asprintf, _asprintf_l, _asxprintf, + _asxprintf_exec, _atexit, _atexit_b, _atof, _atof_l, _atoi, + _atoi_l, _atol, _atol_l, _atoll, _atoll_l, _backtrace, _backtrace_async, + _backtrace_from_fp, _backtrace_image_offsets, _backtrace_set_pcs_func, _backtrace_symbols, _backtrace_symbols_fd, _basename, _basename_r, _bcopy, _brk, _bsd_signal, _bsearch, _bsearch_b, _btowc, _btowc_l, _catclose, _catgets, _catopen, _cfgetispeed, _cfgetospeed, @@ -1587,16 +1397,17 @@ exports: _strncat, _strndup, _strnstr, _strnunvis, _strnunvisx, _strnvis, _strnvisx, _strpbrk, _strptime, _strptime_l, _strrchr, _strsenvisx, _strsep, _strsignal, _strsignal_r, _strsnvis, _strsnvisx, - _strspn, _strsvis, _strsvisx, _strtod, _strtod_l, _strtof, - _strtof_l, _strtofflags, _strtoimax, _strtoimax_l, _strtok, - _strtok_r, _strtol, _strtol_l, _strtold, _strtold_l, _strtoll, - _strtoll_l, _strtonum, _strtoq, _strtoq_l, _strtoul, _strtoul_l, - _strtoull, _strtoull_l, _strtoumax, _strtoumax_l, _strtouq, - _strtouq_l, _strunvis, _strunvisx, _strvis, _strvisx, _strxfrm, - _strxfrm_l, _suboptarg, _svis, _swab, _swprintf, _swprintf_l, - _swscanf, _swscanf_l, _sxprintf, _sxprintf_exec, _sync_volume_np, - _sys_errlist, _sys_nerr, _sys_siglist, _sys_signame, _sysconf, - _sysctl, _sysctlbyname, _sysctlnametomib, _system, '_system$NOCANCEL', + _strspn, _strsvis, _strsvisx, _strtod, _strtod_l, _strtoencf16, + _strtoencf32, _strtoencf64, _strtoencf64x, _strtof, _strtof_l, + _strtofflags, _strtoimax, _strtoimax_l, _strtok, _strtok_r, + _strtol, _strtol_l, _strtold, _strtold_l, _strtoll, _strtoll_l, + _strtonum, _strtoq, _strtoq_l, _strtoul, _strtoul_l, _strtoull, + _strtoull_l, _strtoumax, _strtoumax_l, _strtouq, _strtouq_l, + _strunvis, _strunvisx, _strvis, _strvisx, _strxfrm, _strxfrm_l, + _suboptarg, _svis, _swab, _swprintf, _swprintf_l, _swscanf, + _swscanf_l, _sxprintf, _sxprintf_exec, _sync_volume_np, _sys_errlist, + _sys_nerr, _sys_siglist, _sys_signame, _sysconf, _sysctl, + _sysctlbyname, _sysctlnametomib, _system, '_system$NOCANCEL', _tcdrain, '_tcdrain$NOCANCEL', _tcflow, _tcflush, _tcgetattr, _tcgetpgrp, _tcgetsid, _tcsendbreak, _tcsetattr, _tcsetpgrp, _tdelete, _telldir, _tempnam, _tfind, _thread_stack_async_pcs, @@ -1652,21 +1463,8 @@ reexports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 2053883C-79F4-3AF8-A37C-DE204E208C60 - - target: x86_64-maccatalyst - value: 2053883C-79F4-3AF8-A37C-DE204E208C60 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: CB445464-28B4-353C-976E-59DA0E229FED - - target: arm64e-maccatalyst - value: CB445464-28B4-353C-976E-59DA0E229FED install-name: '/usr/lib/system/libsystem_collections.dylib' -current-version: 1534.40.2 +current-version: 1534.100.14 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1695,21 +1493,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: E7F80C5C-E18C-3201-ACB6-9A4C46B6574B - - target: x86_64-maccatalyst - value: E7F80C5C-E18C-3201-ACB6-9A4C46B6574B - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 113A1DDB-1B61-3C33-9FD5-B39A2A29D779 - - target: arm64e-maccatalyst - value: 113A1DDB-1B61-3C33-9FD5-B39A2A29D779 install-name: '/usr/lib/system/libsystem_configuration.dylib' -current-version: 1241.60.3 +current-version: 1241.100.11 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -1735,19 +1520,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: D44E0845-001C-3C46-B3A7-E4926DAEF6B3 - - target: x86_64-maccatalyst - value: D44E0845-001C-3C46-B3A7-E4926DAEF6B3 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 2694748C-A452-3438-BB47-161D7B220AE2 - - target: arm64e-maccatalyst - value: 2694748C-A452-3438-BB47-161D7B220AE2 install-name: '/usr/lib/system/libsystem_containermanager.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1792,6 +1564,7 @@ exports: _container_create_or_lookup_app_group_paths, _container_create_or_lookup_app_group_paths_for_current_user, _container_create_or_lookup_app_group_paths_for_platform, _container_create_or_lookup_app_group_paths_from_entitlements, + _container_create_or_lookup_app_group_paths_from_entitlements_4ls, _container_create_or_lookup_for_current_user, _container_create_or_lookup_for_platform, _container_create_or_lookup_group_container_paths_for_current_user, _container_create_or_lookup_path, _container_create_or_lookup_path_for_current_user, @@ -1910,19 +1683,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: D86D13CC-2AF9-3A17-BCF3-0D16703F99A7 - - target: x86_64-maccatalyst - value: D86D13CC-2AF9-3A17-BCF3-0D16703F99A7 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 6E9DED8E-2A44-33E3-909F-74B4786482A2 - - target: arm64e-maccatalyst - value: 6E9DED8E-2A44-33E3-909F-74B4786482A2 install-name: '/usr/lib/system/libsystem_coreservices.dylib' current-version: 129 parent-umbrella: @@ -1944,19 +1704,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: E272E2C2-8511-3C94-8C39-F5319F2812BB - - target: x86_64-maccatalyst - value: E272E2C2-8511-3C94-8C39-F5319F2812BB - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 74F6C923-5FF6-39D0-90DE-8FB4812EA263 - - target: arm64e-maccatalyst - value: 74F6C923-5FF6-39D0-90DE-8FB4812EA263 install-name: '/usr/lib/system/libsystem_darwin.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -1995,21 +1742,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 77610ACE-81D4-33E5-A343-5FDA27F53E10 - - target: x86_64-maccatalyst - value: 77610ACE-81D4-33E5-A343-5FDA27F53E10 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: F87EFC17-B673-3488-B503-C67E2FFDE6A0 - - target: arm64e-maccatalyst - value: F87EFC17-B673-3488-B503-C67E2FFDE6A0 install-name: '/usr/lib/system/libsystem_dnssd.dylib' -current-version: 1790.60.25 +current-version: 1807.101.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2045,21 +1779,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 223BBDCF-6D59-3770-9E6A-38B762676030 - - target: x86_64-maccatalyst - value: 223BBDCF-6D59-3770-9E6A-38B762676030 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: EE355E15-A47F-3BED-A955-1041497449AE - - target: arm64e-maccatalyst - value: EE355E15-A47F-3BED-A955-1041497449AE install-name: '/usr/lib/system/libsystem_featureflags.dylib' -current-version: 71 +current-version: 74 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2072,19 +1793,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 7B76D94D-56F7-3B8A-B63D-ED567EFA12F6 - - target: x86_64-maccatalyst - value: 7B76D94D-56F7-3B8A-B63D-ED567EFA12F6 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 67168754-ABAC-33C6-AFF7-FF53F1A8745C - - target: arm64e-maccatalyst - value: 67168754-ABAC-33C6-AFF7-FF53F1A8745C install-name: '/usr/lib/system/libsystem_info.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -2209,21 +1917,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 7C3DCC95-9F42-3C7C-8796-476FF67B9CF7 - - target: x86_64-maccatalyst - value: 7C3DCC95-9F42-3C7C-8796-476FF67B9CF7 - - target: arm64-macos - value: EB0327EE-CB9C-37ED-AB6A-E9AF74E814F0 - - target: arm64-maccatalyst - value: EB0327EE-CB9C-37ED-AB6A-E9AF74E814F0 - - target: arm64e-macos - value: AEBF397E-E2EF-3A49-BE58-23D4558511F6 - - target: arm64e-maccatalyst - value: AEBF397E-E2EF-3A49-BE58-23D4558511F6 install-name: '/usr/lib/system/libsystem_kernel.dylib' -current-version: 8792.61.2 +current-version: 8796.101.5 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2243,19 +1938,20 @@ exports: ___channel_get_opt, ___channel_open, ___channel_set_opt, ___channel_sync, ___chmod, ___chmod_extended, ___close_nocancel, ___coalition, ___coalition_info, ___coalition_ledger, ___commpage_gettimeofday, - ___connect, ___connect_nocancel, ___copyfile, ___csrctl, ___darwin_check_fd_set_overflow, - ___debug_syscall_reject, ___debug_syscall_reject_config, ___delete, - ___disable_threadsignal, ___error, ___execve, ___exit, ___fchmod, - ___fchmod_extended, ___fcntl, ___fcntl_nocancel, ___fork, - ___fs_snapshot, ___fstat64_extended, ___fstat_extended, ___fsync_nocancel, - ___get_remove_counter, ___getattrlist, ___getdirentries64, - ___gethostuuid, ___getlogin, ___getpeername, ___getpid, ___getrlimit, - ___getsgroups, ___getsockname, ___gettid, ___gettimeofday, - ___getwgroups, ___guarded_open_dprotected_np, ___guarded_open_np, - ___identitysvc, ___inc_remove_counter, ___initgroups, ___ioctl, - ___iopolicysys, ___kdebug_trace, ___kdebug_trace64, ___kdebug_trace_string, - ___kdebug_typefilter, ___kill, ___kqueue_workloop_ctl, ___lchown, - ___libkernel_init, ___libkernel_init_after_boot_tasks, ___libkernel_init_late, + ___connect, ___connect_nocancel, ___copyfile, ___crossarch_trap, + ___csrctl, ___darwin_check_fd_set_overflow, ___debug_syscall_reject, + ___debug_syscall_reject_config, ___delete, ___disable_threadsignal, + ___error, ___execve, ___exit, ___fchmod, ___fchmod_extended, + ___fcntl, ___fcntl_nocancel, ___fork, ___fs_snapshot, ___fstat64_extended, + ___fstat_extended, ___fsync_nocancel, ___get_remove_counter, + ___getattrlist, ___getdirentries64, ___gethostuuid, ___getlogin, + ___getpeername, ___getpid, ___getrlimit, ___getsgroups, ___getsockname, + ___gettid, ___gettimeofday, ___getwgroups, ___guarded_open_dprotected_np, + ___guarded_open_np, ___identitysvc, ___inc_remove_counter, + ___initgroups, ___ioctl, ___iopolicysys, ___kdebug_trace, + ___kdebug_trace64, ___kdebug_trace_string, ___kdebug_typefilter, + ___kill, ___kqueue_workloop_ctl, ___lchown, ___libkernel_init, + ___libkernel_init_after_boot_tasks, ___libkernel_init_late, ___libkernel_platform_init, ___libkernel_voucher_init, ___listen, ___log_data, ___lseek, ___lstat64_extended, ___lstat_extended, ___mac_execve, ___mac_get_fd, ___mac_get_file, ___mac_get_link, @@ -2572,32 +2268,32 @@ exports: _posix_spawnattr_set_uid_np, _posix_spawnattr_setarchpref_np, _posix_spawnattr_setauditsessionport_np, _posix_spawnattr_setbinpref_np, _posix_spawnattr_setcoalition_np, _posix_spawnattr_setcpumonitor, - _posix_spawnattr_setcpumonitor_default, _posix_spawnattr_setexceptionports_np, - _posix_spawnattr_setflags, _posix_spawnattr_setjetsam_ext, - _posix_spawnattr_setmacpolicyinfo_np, _posix_spawnattr_setnosmt_np, - _posix_spawnattr_setpcontrol_np, _posix_spawnattr_setpgroup, - _posix_spawnattr_setprocesstype_np, _posix_spawnattr_setsigdefault, - _posix_spawnattr_setsigmask, _posix_spawnattr_setspecialport_np, - _pread, '_pread$NOCANCEL', _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, - _proc_clear_delayidlesleep, _proc_clear_dirty, _proc_clear_vmpressure, - _proc_current_thread_schedinfo, _proc_denap_assertion_begin_with_msg, - _proc_denap_assertion_complete, _proc_disable_apptype, _proc_disable_cpumon, - _proc_disable_wakemon, _proc_donate_importance_boost, _proc_enable_apptype, - _proc_get_cpumon_params, _proc_get_dirty, _proc_get_wakemon_params, - _proc_importance_assertion_begin_with_msg, _proc_importance_assertion_complete, - _proc_kmsgbuf, _proc_libversion, _proc_list_dynkqueueids, - _proc_list_uptrs, _proc_listallpids, _proc_listchildpids, - _proc_listcoalitions, _proc_listpgrppids, _proc_listpids, - _proc_listpidspath, _proc_name, _proc_pid_rusage, _proc_piddynkqueueinfo, - _proc_pidfdinfo, _proc_pidfileportinfo, _proc_pidinfo, _proc_pidoriginatorinfo, - _proc_pidpath, _proc_pidpath_audittoken, _proc_regionfilename, - _proc_reset_footprint_interval, _proc_resume_cpumon, _proc_rlimit_control, - _proc_set_cpumon_defaults, _proc_set_cpumon_params, _proc_set_cpumon_params_fatal, - _proc_set_csm, _proc_set_delayidlesleep, _proc_set_dirty, - _proc_set_no_smt, _proc_set_owner_vmpressure, _proc_set_wakemon_defaults, - _proc_set_wakemon_params, _proc_setcpu_percentage, _proc_setpcontrol, - _proc_setthread_cpupercent, _proc_setthread_csm, _proc_setthread_no_smt, - _proc_suppress, _proc_terminate, _proc_terminate_all_rsr, + _posix_spawnattr_setcpumonitor_default, _posix_spawnattr_setdataless_iopolicy_np, + _posix_spawnattr_setexceptionports_np, _posix_spawnattr_setflags, + _posix_spawnattr_setjetsam_ext, _posix_spawnattr_setmacpolicyinfo_np, + _posix_spawnattr_setnosmt_np, _posix_spawnattr_setpcontrol_np, + _posix_spawnattr_setpgroup, _posix_spawnattr_setprocesstype_np, + _posix_spawnattr_setsigdefault, _posix_spawnattr_setsigmask, + _posix_spawnattr_setspecialport_np, _pread, '_pread$NOCANCEL', + _preadv, '_preadv$NOCANCEL', _proc_clear_cpulimits, _proc_clear_delayidlesleep, + _proc_clear_dirty, _proc_clear_vmpressure, _proc_current_thread_schedinfo, + _proc_denap_assertion_begin_with_msg, _proc_denap_assertion_complete, + _proc_disable_apptype, _proc_disable_cpumon, _proc_disable_wakemon, + _proc_donate_importance_boost, _proc_enable_apptype, _proc_get_cpumon_params, + _proc_get_dirty, _proc_get_wakemon_params, _proc_importance_assertion_begin_with_msg, + _proc_importance_assertion_complete, _proc_kmsgbuf, _proc_libversion, + _proc_list_dynkqueueids, _proc_list_uptrs, _proc_listallpids, + _proc_listchildpids, _proc_listcoalitions, _proc_listpgrppids, + _proc_listpids, _proc_listpidspath, _proc_name, _proc_pid_rusage, + _proc_piddynkqueueinfo, _proc_pidfdinfo, _proc_pidfileportinfo, + _proc_pidinfo, _proc_pidoriginatorinfo, _proc_pidpath, _proc_pidpath_audittoken, + _proc_regionfilename, _proc_reset_footprint_interval, _proc_resume_cpumon, + _proc_rlimit_control, _proc_set_cpumon_defaults, _proc_set_cpumon_params, + _proc_set_cpumon_params_fatal, _proc_set_csm, _proc_set_delayidlesleep, + _proc_set_dirty, _proc_set_no_smt, _proc_set_owner_vmpressure, + _proc_set_wakemon_defaults, _proc_set_wakemon_params, _proc_setcpu_percentage, + _proc_setpcontrol, _proc_setthread_cpupercent, _proc_setthread_csm, + _proc_setthread_no_smt, _proc_suppress, _proc_terminate, _proc_terminate_all_rsr, _proc_trace_log, _proc_track_dirty, _proc_udata_info, _proc_uuid_policy, _processor_assign, _processor_control, _processor_exit, _processor_get_assignment, _processor_info, _processor_set_create, _processor_set_default, @@ -2707,25 +2403,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: DC460796-C8A7-3507-8539-C890D9EDDC8C - - target: x86_64-maccatalyst - value: DC460796-C8A7-3507-8539-C890D9EDDC8C - - target: x86_64h-macos - value: 73F0FC1C-FC2A-3B36-8796-7C2C2CBA7214 - - target: x86_64h-maccatalyst - value: 73F0FC1C-FC2A-3B36-8796-7C2C2CBA7214 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 6BEE17F3-04F2-3B1F-B8EB-C94379ABA9BD - - target: arm64e-maccatalyst - value: 6BEE17F3-04F2-3B1F-B8EB-C94379ABA9BD install-name: '/usr/lib/system/libsystem_m.dylib' -current-version: 3226.0.1 +current-version: 3226.100.4 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, x86_64h-macos, x86_64h-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2938,21 +2617,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: F609F029-BCD0-3A54-B48A-99B3CE8378CE - - target: x86_64-maccatalyst - value: F609F029-BCD0-3A54-B48A-99B3CE8378CE - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 04185997-16D2-30DA-8691-7C82612635A3 - - target: arm64e-maccatalyst - value: 04185997-16D2-30DA-8691-7C82612635A3 install-name: '/usr/lib/system/libsystem_malloc.dylib' -current-version: 409.60.6 +current-version: 425.100.7 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -2992,7 +2658,7 @@ exports: _malloc_zone_print, _malloc_zone_print_ptr_info, _malloc_zone_realloc, _malloc_zone_register, _malloc_zone_statistics, _malloc_zone_unregister, _malloc_zone_valloc, _malloc_zones, _mstats, _pgm_diagnose_fault_from_crash_reporter, - _pgm_disable_for_current_thread, _posix_memalign, _quarantine_diagnose_fault_from_crash_reporter, + _posix_memalign, _quarantine_diagnose_fault_from_crash_reporter, _realloc, '_reallocarray$DARWIN_EXTSN', '_reallocarrayf$DARWIN_EXTSN', _scalable_zone_info, _scalable_zone_statistics, _set_malloc_singlethreaded, _stack_logging_enable_logging, _szone_check_counter, _szone_check_modulo, @@ -3002,19 +2668,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 09114B12-EC3D-3943-A1BD-9909EE2F85B6 - - target: x86_64-maccatalyst - value: 09114B12-EC3D-3943-A1BD-9909EE2F85B6 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 8737AB7F-91FA-3C06-B797-566A62D0751C - - target: arm64e-maccatalyst - value: 8737AB7F-91FA-3C06-B797-566A62D0751C install-name: '/usr/lib/system/libsystem_networkextension.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -3039,9 +2692,9 @@ exports: _NEHelperSettingsSetArray, _NEHelperSettingsSetBool, _NEHelperSettingsSetNumber, _NEHelperVPNConfigurationExists, _NEHelperVPNSetEnabled, _g_ne_read_uuid_cache, _g_ne_uuid_cache_hit, _ne_copy_cached_bundle_identifier_for_uuid, - _ne_copy_cached_preferred_bundle_for_bundle_identifier, _ne_copy_cached_uuids_for_bundle_identifier, - _ne_copy_signature_info_for_pid, _ne_copy_signing_identifier_for_pid, - _ne_copy_uuid_cache, _ne_force_reset_uuid_cache, _ne_get_configuration_generation, + _ne_copy_cached_uuids_for_bundle_identifier, _ne_copy_signature_info_for_pid, + _ne_copy_signing_identifier_for_pid, _ne_copy_uuid_cache, + _ne_force_reset_uuid_cache, _ne_get_configuration_generation, _ne_is_sockaddr_valid, _ne_log_large_obj, _ne_log_obj, _ne_print_backtrace, _ne_privacy_dns_netagent_id, _ne_privacy_proxy_netagent_id, _ne_session_add_necp_drop_dest_from_dest_list, _ne_session_add_necp_drop_dest_from_path, @@ -3069,20 +2722,20 @@ exports: _ne_session_policy_match_get_service, _ne_session_policy_match_get_service_action, _ne_session_policy_match_get_service_type, _ne_session_policy_match_is_drop, _ne_session_policy_match_is_flow_divert, _ne_session_policy_match_service_is_registered, - _ne_session_release, _ne_session_retain, _ne_session_send_barrier, - _ne_session_service_get_dns_service_id, _ne_session_service_get_dns_service_id_for_interface, - _ne_session_service_matches_address, _ne_session_service_matches_address_for_interface, - _ne_session_set_event_handler, _ne_session_set_socket_attributes, - _ne_session_set_socket_context_attribute, _ne_session_set_socket_tracker_attributes, - _ne_session_should_disable_nexus, _ne_session_start, _ne_session_start_on_behalf_of, - _ne_session_start_with_options, _ne_session_status_to_string, - _ne_session_stop, _ne_session_stop_all_with_plugin_type, _ne_session_stop_reason_to_string, - _ne_session_type_to_string, _ne_session_use_as_system_vpn, - _ne_session_vod_evaluate_connection_present, _ne_session_vpn_include_all_networks_configs_present, - _ne_socket_set_attribution, _ne_socket_set_domains, _ne_socket_set_is_app_initiated, - _ne_socket_set_website_attribution, _ne_tracker_build_cache, - _ne_tracker_build_trie, _ne_tracker_check_info_changed, _ne_tracker_clear_cache, - _ne_tracker_context_get_domain, _ne_tracker_context_get_domain_owner, + _ne_session_random_port_fallback, _ne_session_release, _ne_session_retain, + _ne_session_send_barrier, _ne_session_service_get_dns_service_id, + _ne_session_service_get_dns_service_id_for_interface, _ne_session_service_matches_address, + _ne_session_service_matches_address_for_interface, _ne_session_set_event_handler, + _ne_session_set_socket_attributes, _ne_session_set_socket_context_attribute, + _ne_session_set_socket_tracker_attributes, _ne_session_should_disable_nexus, + _ne_session_start, _ne_session_start_on_behalf_of, _ne_session_start_with_options, + _ne_session_status_to_string, _ne_session_stop, _ne_session_stop_all_with_plugin_type, + _ne_session_stop_reason_to_string, _ne_session_type_to_string, + _ne_session_use_as_system_vpn, _ne_session_vod_evaluate_connection_present, + _ne_session_vpn_include_all_networks_configs_present, _ne_socket_set_attribution, + _ne_socket_set_domains, _ne_socket_set_is_app_initiated, _ne_socket_set_website_attribution, + _ne_tracker_build_cache, _ne_tracker_build_trie, _ne_tracker_check_info_changed, + _ne_tracker_clear_cache, _ne_tracker_context_get_domain, _ne_tracker_context_get_domain_owner, _ne_tracker_context_is_from_app_list, _ne_tracker_context_is_from_web_list, _ne_tracker_get_ddg_dictionary, _ne_tracker_lookup_app_domains, _ne_tracker_set_test_domains, _ne_tracker_validate_domain, @@ -3095,21 +2748,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 0463374D-9E62-3E58-A668-C9EFF9DB217C - - target: x86_64-maccatalyst - value: 0463374D-9E62-3E58-A668-C9EFF9DB217C - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 62FA1CCF-D4BB-3606-BDC9-C2F247A12CE8 - - target: arm64e-maccatalyst - value: 62FA1CCF-D4BB-3606-BDC9-C2F247A12CE8 install-name: '/usr/lib/system/libsystem_notify.dylib' -current-version: 306 +current-version: 312 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3128,21 +2768,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: F314B62B-98F4-3A7C-8296-8739F8B6855A - - target: x86_64-maccatalyst - value: F314B62B-98F4-3A7C-8296-8739F8B6855A - - target: arm64-macos - value: ABF0BAEB-706B-3AC1-B6AD-B5CF380B8963 - - target: arm64-maccatalyst - value: ABF0BAEB-706B-3AC1-B6AD-B5CF380B8963 - - target: arm64e-macos - value: B215AE90-4ED2-3FCD-8CCC-6C0D93CC4F41 - - target: arm64e-maccatalyst - value: B215AE90-4ED2-3FCD-8CCC-6C0D93CC4F41 install-name: '/usr/lib/system/libsystem_platform.dylib' -current-version: 288 +current-version: 292.100.1 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3204,37 +2831,18 @@ exports: _os_unfair_lock_unlock, _os_unfair_lock_unlock_no_tsd, _os_unfair_recursive_lock_lock_with_options, _os_unfair_recursive_lock_owned, _os_unfair_recursive_lock_trylock, _os_unfair_recursive_lock_tryunlock4objc, _os_unfair_recursive_lock_unlock, - _os_unfair_recursive_lock_unlock_forked_child, _platform_task_attach, - _platform_task_copy_next_thread, _platform_task_detach, _platform_task_is_64_bit, - _platform_task_perform, _platform_task_resume_threads, _platform_task_suspend_threads, - _platform_task_update_threads, _platform_thread_abort_safely, - _platform_thread_get_pthread, _platform_thread_get_state, - _platform_thread_get_unique_id, _platform_thread_info, _platform_thread_perform, - _platform_thread_release, _platform_thread_resume, _platform_thread_set_state, - _platform_thread_suspend, _setcontext, _setjmp, _siglongjmp, - _sigsetjmp, _spin_lock, _spin_lock_try, _spin_unlock, _swapcontext, - _sys_cache_control, _sys_dcache_flush, _sys_icache_invalidate ] + _os_unfair_recursive_lock_unlock_forked_child, _setcontext, + _setjmp, _siglongjmp, _sigsetjmp, _spin_lock, _spin_lock_try, + _spin_unlock, _swapcontext, _sys_cache_control, _sys_dcache_flush, + _sys_icache_invalidate ] - targets: [ arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] symbols: [ __ctx_done ] --- !tapi-tbd tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 5920E36F-53EC-33F0-B675-8AE48B58418C - - target: x86_64-maccatalyst - value: 5920E36F-53EC-33F0-B675-8AE48B58418C - - target: arm64-macos - value: 51C613E3-4ABF-359C-B275-2608BB1BE0B6 - - target: arm64-maccatalyst - value: 51C613E3-4ABF-359C-B275-2608BB1BE0B6 - - target: arm64e-macos - value: 132084C6-C347-3489-9AC2-FCAAD21CDB73 - - target: arm64e-maccatalyst - value: 132084C6-C347-3489-9AC2-FCAAD21CDB73 install-name: '/usr/lib/system/libsystem_pthread.dylib' -current-version: 514 +current-version: 514.100.2 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3328,21 +2936,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: D199B283-8F09-3F2F-A17E-274BFF7733BE - - target: x86_64-maccatalyst - value: D199B283-8F09-3F2F-A17E-274BFF7733BE - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 3680811A-78F7-361A-ABBE-8E783165AC81 - - target: arm64e-maccatalyst - value: 3680811A-78F7-361A-ABBE-8E783165AC81 install-name: '/usr/lib/system/libsystem_sandbox.dylib' -current-version: 1845.60.12 +current-version: 1846.100.185 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3370,8 +2965,8 @@ exports: _rootless_check_trusted_class, _rootless_check_trusted_fd, _rootless_convert_to_datavault, _rootless_manifest_free, _rootless_manifest_parse, _rootless_mkdir_datavault, _rootless_mkdir_nounlink, _rootless_mkdir_restricted, - _rootless_preflight, _rootless_protected_volume, _rootless_register_trusted_storage_class, - _rootless_remove_datavault_in_favor_of_static_storage_class, + _rootless_preflight, _rootless_protected_volume, _rootless_protected_volume_fd, + _rootless_register_trusted_storage_class, _rootless_remove_datavault_in_favor_of_static_storage_class, _rootless_remove_restricted_in_favor_of_static_storage_class, _rootless_restricted_environment, _rootless_suspend, _rootless_trusted_by_self_token, _rootless_verify_trusted_by_self_token, _sandbox_builtin_query, @@ -3415,21 +3010,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: F24B1FA9-5692-35BA-9A9C-E071B7BFA5D7 - - target: x86_64-maccatalyst - value: F24B1FA9-5692-35BA-9A9C-E071B7BFA5D7 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 82513DC5-565F-3A4E-9431-4511FB0C22FA - - target: arm64e-maccatalyst - value: 82513DC5-565F-3A4E-9431-4511FB0C22FA install-name: '/usr/lib/system/libsystem_secinit.dylib' -current-version: 119.40.2 +current-version: 120.100.7 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3444,19 +3026,6 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: A5915FB2-F0C9-3BF0-ADC6-BEB571C73E57 - - target: x86_64-maccatalyst - value: A5915FB2-F0C9-3BF0-ADC6-BEB571C73E57 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: B31CD553-083B-39C6-BCB9-B0413ECAF562 - - target: arm64e-maccatalyst - value: B31CD553-083B-39C6-BCB9-B0413ECAF562 install-name: '/usr/lib/system/libsystem_symptoms.dylib' parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, @@ -3474,21 +3043,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: C5359E6E-7B63-3E51-A664-3E3581E15F52 - - target: x86_64-maccatalyst - value: C5359E6E-7B63-3E51-A664-3E3581E15F52 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 616F473A-EB21-377D-B3B4-F1581F127F0D - - target: arm64e-maccatalyst - value: 616F473A-EB21-377D-B3B4-F1581F127F0D install-name: '/usr/lib/system/libsystem_trace.dylib' -current-version: 1406.60.2 +current-version: 1431.100.13 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3534,15 +3090,17 @@ exports: _os_log_backtrace_create_from_return_address, _os_log_backtrace_destroy, _os_log_backtrace_get_frames, _os_log_backtrace_get_length, _os_log_backtrace_print_to_blob, _os_log_backtrace_serialize_to_blob, - _os_log_create, _os_log_errors_count, _os_log_fault_default_callback, - _os_log_faults_count, _os_log_fmt_compose, _os_log_fmt_convert_trace, - _os_log_fmt_extract_pubdata, _os_log_fmt_get_plugin, _os_log_get_type, - _os_log_is_debug_enabled, _os_log_is_enabled, _os_log_pack_compose, - _os_log_pack_send, _os_log_pack_send_and_compose, _os_log_set_client_type, - _os_log_set_enabled, _os_log_set_fault_callback, _os_log_shim_enabled, + _os_log_compare_enablement, _os_log_copy_decorated_message, + _os_log_copy_message_string, _os_log_create, _os_log_errors_count, + _os_log_fault_default_callback, _os_log_faults_count, _os_log_fmt_compose, + _os_log_fmt_convert_trace, _os_log_fmt_extract_pubdata, _os_log_fmt_get_plugin, + _os_log_get_type, _os_log_is_debug_enabled, _os_log_is_enabled, + _os_log_pack_compose, _os_log_pack_send, _os_log_pack_send_and_compose, + _os_log_set_client_type, _os_log_set_enabled, _os_log_set_fault_callback, + _os_log_set_hook, _os_log_set_test_callback, _os_log_shim_enabled, _os_log_shim_legacy_logging_enabled, _os_log_shim_with_CFString, - _os_log_type_enabled, _os_log_with_args, _os_signpost_enabled, - _os_signpost_id_generate, _os_signpost_id_make_with_pointer, + _os_log_type_enabled, _os_log_type_get_name, _os_log_with_args, + _os_signpost_enabled, _os_signpost_id_generate, _os_signpost_id_make_with_pointer, _os_signpost_set_introspection_hook_4Perf, _os_state_add_handler, _os_state_remove_handler, _os_trace_debug_enabled, _os_trace_get_mode, _os_trace_get_type, _os_trace_info_enabled, _os_trace_set_mode ] @@ -3551,21 +3109,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: E45FA86E-48EB-3926-A24C-323DB84D3700 - - target: x86_64-maccatalyst - value: E45FA86E-48EB-3926-A24C-323DB84D3700 - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 1228EDDF-7C61-3674-8C42-B537FFE9EDDA - - target: arm64e-maccatalyst - value: 1228EDDF-7C61-3674-8C42-B537FFE9EDDA install-name: '/usr/lib/system/libunwind.dylib' -current-version: 202.100 +current-version: 1500.26 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3614,7 +3159,8 @@ exports: __Unwind_GetLanguageSpecificData, __Unwind_GetRegionStart, __Unwind_GetTextRelBase, __Unwind_RaiseException, __Unwind_Resume, __Unwind_Resume_or_Rethrow, __Unwind_SetGR, __Unwind_SetIP, - ___deregister_frame, ___register_frame, ___unw_add_dynamic_fde, + ___deregister_frame, ___register_frame, ___unw_add_dynamic_eh_frame_section, + ___unw_add_dynamic_fde, ___unw_remove_dynamic_eh_frame_section, ___unw_remove_dynamic_fde, _unw_get_fpreg, _unw_get_proc_info, _unw_get_proc_name, _unw_get_reg, _unw_getcontext, _unw_init_local, _unw_is_fpreg, _unw_is_signal_frame, _unw_iterate_dwarf_unwind_cache, @@ -3624,21 +3170,8 @@ exports: tbd-version: 4 targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] -uuids: - - target: x86_64-macos - value: 7E56F9FE-DC35-3354-BA23-4103C09E22DD - - target: x86_64-maccatalyst - value: 7E56F9FE-DC35-3354-BA23-4103C09E22DD - - target: arm64-macos - value: 00000000-0000-0000-0000-000000000000 - - target: arm64-maccatalyst - value: 00000000-0000-0000-0000-000000000000 - - target: arm64e-macos - value: 8EF4547D-1AF8-37CF-B15A-29405BF12642 - - target: arm64e-maccatalyst - value: 8EF4547D-1AF8-37CF-B15A-29405BF12642 install-name: '/usr/lib/system/libxpc.dylib' -current-version: 2462.60.15 +current-version: 2462.100.95 parent-umbrella: - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, arm64e-macos, arm64e-maccatalyst ] @@ -3685,12 +3218,13 @@ exports: _XPC_COALITION_INFO_KEY_RESOURCE_USAGE_BLOB, __availability_version_check, __launch_job_routine, __launch_job_routine_async, __launch_msg2, __launch_server_test_routine, __launch_service_stats_copy_4ppse_impl, - __libxpc_initializer, __spawn_via_launchd, __system_ios_support_version_copy_string_sysctl, - __system_version_copy_string_plist, __system_version_copy_string_sysctl, - __system_version_fallback, __system_version_parse_string, - __vproc_get_last_exit_status, __vproc_grab_subset, __vproc_kickstart_by_label, - __vproc_log, __vproc_log_error, __vproc_logv, __vproc_pid_is_managed, - __vproc_post_fork_ping, __vproc_send_signal_by_label, __vproc_set_global_on_demand, + __launch_service_stats_copy_impl, __libxpc_initializer, __spawn_via_launchd, + __system_ios_support_version_copy_string_sysctl, __system_version_copy_string_plist, + __system_version_copy_string_sysctl, __system_version_fallback, + __system_version_parse_string, __vproc_get_last_exit_status, + __vproc_grab_subset, __vproc_kickstart_by_label, __vproc_log, + __vproc_log_error, __vproc_logv, __vproc_pid_is_managed, __vproc_post_fork_ping, + __vproc_send_signal_by_label, __vproc_set_global_on_demand, __vproc_standby_begin, __vproc_standby_count, __vproc_standby_end, __vproc_standby_timeout, __vproc_transaction_begin, __vproc_transaction_count, __vproc_transaction_count_for_pid, __vproc_transaction_end, @@ -3762,16 +3296,17 @@ exports: _launch_perfcheck_property_endpoint_name, _launch_perfcheck_property_endpoint_needs_activation, _launch_perfcheck_property_endpoints, _launch_remove_external_service, _launch_service_instance_copy_uuids, _launch_service_instance_create, - _launch_service_instance_remove, _launch_service_stats_disable_4ppse, - _launch_service_stats_enable_4ppse, _launch_service_stats_is_enabled_4ppse, - _launch_set_service_enabled, _launch_set_system_service_enabled, - _launch_socket_service_check_in, _launch_version_for_user_service_4coresim, - _launch_wait, _launchd_close, _launchd_fdopen, _launchd_getfd, - _launchd_msg_recv, _launchd_msg_send, _load_launchd_jobs_at_loginwindow_prompt, - _mpm_uncork_fork, _mpm_wait, _os_system_version_get_current_version, - _os_system_version_get_ios_support_version, _os_system_version_sim_get_current_host_version, - _os_transaction_copy_description, _os_transaction_create, - _os_transaction_get_description, _os_transaction_get_timestamp, + _launch_service_instance_remove, _launch_service_stats_disable, + _launch_service_stats_disable_4ppse, _launch_service_stats_enable, + _launch_service_stats_enable_4ppse, _launch_service_stats_is_enabled, + _launch_service_stats_is_enabled_4ppse, _launch_set_service_enabled, + _launch_set_system_service_enabled, _launch_socket_service_check_in, + _launch_version_for_user_service_4coresim, _launch_wait, _launchd_close, + _launchd_fdopen, _launchd_getfd, _launchd_msg_recv, _launchd_msg_send, + _load_launchd_jobs_at_loginwindow_prompt, _mpm_uncork_fork, + _mpm_wait, _os_system_version_get_current_version, _os_system_version_get_ios_support_version, + _os_system_version_sim_get_current_host_version, _os_transaction_copy_description, + _os_transaction_create, _os_transaction_get_description, _os_transaction_get_timestamp, _os_transaction_needs_more_time, _place_hold_on_real_loginwindow, _reboot2, _reboot3, _vproc_release, _vproc_retain, _vproc_standby_begin, _vproc_standby_end, _vproc_swap_complex, _vproc_swap_integer, From f2587de4e915423d0224b8b6ef0cb3d9cb7e60e2 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 22:36:10 +0200 Subject: [PATCH 172/216] macho: look for entry in archives/dylibs too --- src/link/MachO.zig | 2 +- src/link/MachO/load_commands.zig | 4 ++ src/link/MachO/zld.zig | 67 ++++++++++++++++++++------------ 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 3206b63fa3..4c3301a3b4 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3981,7 +3981,7 @@ pub fn getStubsAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?At /// Returns symbol location corresponding to the set entrypoint. /// Asserts output mode is executable. pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { - const entry_name = self.base.options.entry orelse "_main"; + const entry_name = self.base.options.entry orelse load_commands.default_entry_point; const global = self.getGlobal(entry_name) orelse { log.err("entrypoint '{s}' not found", .{entry_name}); return error.MissingMainEntrypoint; diff --git a/src/link/MachO/load_commands.zig b/src/link/MachO/load_commands.zig index 43469ac435..228a1ccfaf 100644 --- a/src/link/MachO/load_commands.zig +++ b/src/link/MachO/load_commands.zig @@ -8,6 +8,10 @@ const mem = std.mem; const Allocator = mem.Allocator; const Dylib = @import("Dylib.zig"); +/// Default implicit entrypoint symbol name. +pub const default_entry_point: []const u8 = "_main"; + +/// Default path to dyld. pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld"; fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool) u64 { diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 07241b54cd..196a437884 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -932,6 +932,34 @@ pub const Zld = struct { } } + fn resolveSymbols(self: *Zld, resolver: *SymbolResolver) !void { + // We add the specified entrypoint as the first unresolved symbols so that + // we search for it in libraries should there be no object files specified + // on the linker line. + if (self.options.output_mode == .Exe) { + const entry_name = self.options.entry orelse load_commands.default_entry_point; + const sym_index = try self.allocateSymbol(); + const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; + const sym = self.getSymbolPtr(sym_loc); + sym.n_strx = try self.strtab.insert(self.gpa, entry_name); + sym.n_type = macho.N_UNDF | macho.N_EXT; + const global_index = try self.addGlobal(sym_loc); + try resolver.table.putNoClobber(entry_name, global_index); + try resolver.unresolved.putNoClobber(global_index, {}); + } + + for (self.objects.items, 0..) |_, object_id| { + try self.resolveSymbolsInObject(@intCast(u32, object_id), resolver); + } + + try self.resolveSymbolsInArchives(resolver); + try self.resolveDyldStubBinder(resolver); + try self.resolveSymbolsInDylibs(resolver); + try self.createMhExecuteHeaderSymbol(resolver); + try self.createDsoHandleSymbol(resolver); + try self.resolveSymbolsAtLoading(resolver); + } + fn resolveSymbolsInObject(self: *Zld, object_id: u32, resolver: *SymbolResolver) !void { const object = &self.objects.items[object_id]; const in_symtab = object.in_symtab orelse return; @@ -975,9 +1003,7 @@ pub const Zld = struct { const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 }; const global_index = resolver.table.get(sym_name) orelse { - const gpa = self.gpa; - const global_index = @intCast(u32, self.globals.items.len); - try self.globals.append(gpa, sym_loc); + const global_index = try self.addGlobal(sym_loc); try resolver.table.putNoClobber(sym_name, global_index); if (sym.undf() and !sym.tentative()) { try resolver.unresolved.putNoClobber(global_index, {}); @@ -1034,8 +1060,10 @@ pub const Zld = struct { }; if (update_global) { - const global_object = &self.objects.items[global.getFile().?]; - global_object.globals_lookup[global.sym_index] = global_index; + if (global.getFile()) |file| { + const global_object = &self.objects.items[file]; + global_object.globals_lookup[global.sym_index] = global_index; + } _ = resolver.unresolved.swapRemove(resolver.table.get(sym_name).?); global.* = sym_loc; } else { @@ -1180,9 +1208,7 @@ pub const Zld = struct { global.* = sym_loc; self.mh_execute_header_index = global_index; } else { - const global_index = @intCast(u32, self.globals.items.len); - try self.globals.append(gpa, sym_loc); - self.mh_execute_header_index = global_index; + self.mh_execute_header_index = try self.addGlobal(sym_loc); } } @@ -1358,6 +1384,12 @@ pub const Zld = struct { return index; } + fn addGlobal(self: *Zld, sym_loc: SymbolWithLoc) !u32 { + const global_index = @intCast(u32, self.globals.items.len); + try self.globals.append(self.gpa, sym_loc); + return global_index; + } + fn allocateSpecialSymbols(self: *Zld) !void { for (&[_]?u32{ self.dso_handle_index, @@ -3980,17 +4012,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr .table = std.StringHashMap(u32).init(arena), .unresolved = std.AutoArrayHashMap(u32, void).init(arena), }; - - for (zld.objects.items, 0..) |_, object_id| { - try zld.resolveSymbolsInObject(@intCast(u32, object_id), &resolver); - } - - try zld.resolveSymbolsInArchives(&resolver); - try zld.resolveDyldStubBinder(&resolver); - try zld.resolveSymbolsInDylibs(&resolver); - try zld.createMhExecuteHeaderSymbol(&resolver); - try zld.createDsoHandleSymbol(&resolver); - try zld.resolveSymbolsAtLoading(&resolver); + try zld.resolveSymbols(&resolver); if (resolver.unresolved.count() > 0) { return error.UndefinedSymbolReference; @@ -4003,11 +4025,8 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr } if (options.output_mode == .Exe) { - const entry_name = options.entry orelse "_main"; - const global_index = resolver.table.get(entry_name) orelse { - log.err("entrypoint '{s}' not found", .{entry_name}); - return error.MissingMainEntrypoint; - }; + const entry_name = options.entry orelse load_commands.default_entry_point; + const global_index = resolver.table.get(entry_name).?; // Error was flagged earlier zld.entry_index = global_index; } From 6f83a741d8f3847c65aa8b791a865f339b77531d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 22:39:41 +0200 Subject: [PATCH 173/216] macho: handle weird case of entrypoint being a stub --- src/link/MachO/ZldAtom.zig | 2 +- src/link/MachO/zld.zig | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/link/MachO/ZldAtom.zig b/src/link/MachO/ZldAtom.zig index e701ee2a13..7e784ded05 100644 --- a/src/link/MachO/ZldAtom.zig +++ b/src/link/MachO/ZldAtom.zig @@ -389,7 +389,7 @@ pub fn addGotEntry(zld: *Zld, target: SymbolWithLoc) !void { try zld.got_table.putNoClobber(gpa, target, got_index); } -fn addStub(zld: *Zld, target: SymbolWithLoc) !void { +pub fn addStub(zld: *Zld, target: SymbolWithLoc) !void { const target_sym = zld.getSymbol(target); if (!target_sym.undf()) return; if (zld.stubs_table.contains(target)) return; diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 196a437884..2e2b215698 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -4042,6 +4042,16 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr try zld.createTentativeDefAtoms(); try zld.createStubHelperPreambleAtom(); + if (zld.options.output_mode == .Exe) { + const global = zld.getEntryPoint(); + if (zld.getSymbol(global).undf()) { + // We do one additional check here in case the entry point was found in one of the dylibs. + // (I actually have no idea what this would imply but it is a possible outcome and so we + // support it.) + try Atom.addStub(&zld, global); + } + } + for (zld.objects.items) |object| { for (object.atoms.items) |atom_index| { const atom = zld.getAtom(atom_index); @@ -4153,8 +4163,18 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr const seg = zld.segments.items[seg_id]; const global = zld.getEntryPoint(); const sym = zld.getSymbol(global); + + const addr: u64 = if (sym.undf()) blk: { + // In this case, the symbol has been resolved in one of dylibs and so we point + // to the stub as its vmaddr value. + const stub_atom_index = zld.getStubsAtomIndexForSymbol(global).?; + const stub_atom = zld.getAtom(stub_atom_index); + const stub_sym = zld.getSymbol(stub_atom.getSymbolWithLoc()); + break :blk stub_sym.n_value; + } else sym.n_value; + try lc_writer.writeStruct(macho.entry_point_command{ - .entryoff = @intCast(u32, sym.n_value - seg.vmaddr), + .entryoff = @intCast(u32, addr - seg.vmaddr), .stacksize = options.stack_size_override orelse 0, }); } else { From 3874df839d3deabec0e82d0ae19947d655f5713d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 23:06:00 +0200 Subject: [PATCH 174/216] link-test: add test for entry in a static archive for MachO --- test/link.zig | 4 +++ test/link/macho/entry_in_archive/build.zig | 35 ++++++++++++++++++++++ test/link/macho/entry_in_archive/main.c | 5 ++++ 3 files changed, 44 insertions(+) create mode 100644 test/link/macho/entry_in_archive/build.zig create mode 100644 test/link/macho/entry_in_archive/main.c diff --git a/test/link.zig b/test/link.zig index aa0ed4817e..2b098c9b5d 100644 --- a/test/link.zig +++ b/test/link.zig @@ -104,6 +104,10 @@ pub const cases = [_]Case{ .build_root = "test/link/macho/entry", .import = @import("link/macho/entry/build.zig"), }, + .{ + .build_root = "test/link/macho/entry_in_archive", + .import = @import("link/macho/entry_in_archive/build.zig"), + }, .{ .build_root = "test/link/macho/headerpad", .import = @import("link/macho/headerpad/build.zig"), diff --git a/test/link/macho/entry_in_archive/build.zig b/test/link/macho/entry_in_archive/build.zig new file mode 100644 index 0000000000..f1eb775c0c --- /dev/null +++ b/test/link/macho/entry_in_archive/build.zig @@ -0,0 +1,35 @@ +const std = @import("std"); + +pub const requires_symlinks = true; + +pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + + add(b, test_step, .Debug); + add(b, test_step, .ReleaseFast); + add(b, test_step, .ReleaseSmall); + add(b, test_step, .ReleaseSafe); +} + +fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { + const lib = b.addStaticLibrary(.{ + .name = "main", + .optimize = optimize, + .target = .{ .os_tag = .macos }, + }); + lib.addCSourceFile("main.c", &.{}); + lib.linkLibC(); + + const exe = b.addExecutable(.{ + .name = "main", + .optimize = optimize, + .target = .{ .os_tag = .macos }, + }); + exe.linkLibrary(lib); + exe.linkLibC(); + + const run = exe.run(); + run.expectExitCode(0); + test_step.dependOn(&run.step); +} diff --git a/test/link/macho/entry_in_archive/main.c b/test/link/macho/entry_in_archive/main.c new file mode 100644 index 0000000000..b9f6deb5be --- /dev/null +++ b/test/link/macho/entry_in_archive/main.c @@ -0,0 +1,5 @@ +#include + +int main(int argc, char* argv[]) { + return 0; +} From 5d0bb50e3d0e87d1d8aad864559e10c83199b608 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Mar 2023 23:28:55 +0200 Subject: [PATCH 175/216] link-test: add test for entry in a dynamic library for MachO --- test/link.zig | 4 ++ test/link/macho/entry_in_dylib/bootstrap.c | 5 ++ test/link/macho/entry_in_dylib/build.zig | 53 ++++++++++++++++++++++ test/link/macho/entry_in_dylib/main.c | 6 +++ 4 files changed, 68 insertions(+) create mode 100644 test/link/macho/entry_in_dylib/bootstrap.c create mode 100644 test/link/macho/entry_in_dylib/build.zig create mode 100644 test/link/macho/entry_in_dylib/main.c diff --git a/test/link.zig b/test/link.zig index 2b098c9b5d..d319d7fa61 100644 --- a/test/link.zig +++ b/test/link.zig @@ -108,6 +108,10 @@ pub const cases = [_]Case{ .build_root = "test/link/macho/entry_in_archive", .import = @import("link/macho/entry_in_archive/build.zig"), }, + .{ + .build_root = "test/link/macho/entry_in_dylib", + .import = @import("link/macho/entry_in_dylib/build.zig"), + }, .{ .build_root = "test/link/macho/headerpad", .import = @import("link/macho/headerpad/build.zig"), diff --git a/test/link/macho/entry_in_dylib/bootstrap.c b/test/link/macho/entry_in_dylib/bootstrap.c new file mode 100644 index 0000000000..6e9a2b830c --- /dev/null +++ b/test/link/macho/entry_in_dylib/bootstrap.c @@ -0,0 +1,5 @@ +extern int my_main(); + +int bootstrap() { + return my_main(); +} diff --git a/test/link/macho/entry_in_dylib/build.zig b/test/link/macho/entry_in_dylib/build.zig new file mode 100644 index 0000000000..feaa8541b7 --- /dev/null +++ b/test/link/macho/entry_in_dylib/build.zig @@ -0,0 +1,53 @@ +const std = @import("std"); + +pub const requires_symlinks = true; + +pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + + add(b, test_step, .Debug); + add(b, test_step, .ReleaseFast); + add(b, test_step, .ReleaseSmall); + add(b, test_step, .ReleaseSafe); +} + +fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { + const lib = b.addSharedLibrary(.{ + .name = "bootstrap", + .optimize = optimize, + .target = .{ .os_tag = .macos }, + }); + lib.addCSourceFile("bootstrap.c", &.{}); + lib.linkLibC(); + lib.linker_allow_shlib_undefined = true; + + const exe = b.addExecutable(.{ + .name = "main", + .optimize = optimize, + .target = .{ .os_tag = .macos }, + }); + exe.addCSourceFile("main.c", &.{}); + exe.linkLibrary(lib); + exe.linkLibC(); + exe.entry_symbol_name = "_bootstrap"; + + const check_exe = exe.checkObject(); + check_exe.checkStart("segname __TEXT"); + check_exe.checkNext("vmaddr {text_vmaddr}"); + + check_exe.checkStart("sectname __stubs"); + check_exe.checkNext("addr {stubs_vmaddr}"); + + check_exe.checkStart("cmd MAIN"); + check_exe.checkNext("entryoff {entryoff}"); + + check_exe.checkComputeCompare("text_vmaddr entryoff +", .{ + .op = .eq, + .value = .{ .variable = "stubs_vmaddr" }, // The entrypoint should be a synthetic stub + }); + + const run = check_exe.runAndCompare(); + run.expectStdOutEqual("Hello!\n"); + test_step.dependOn(&run.step); +} diff --git a/test/link/macho/entry_in_dylib/main.c b/test/link/macho/entry_in_dylib/main.c new file mode 100644 index 0000000000..26173b80ba --- /dev/null +++ b/test/link/macho/entry_in_dylib/main.c @@ -0,0 +1,6 @@ +#include + +int my_main() { + fprintf(stdout, "Hello!\n"); + return 0; +} From 2dd178443abcbd91a923c64a4fd066caef974a82 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 1 Apr 2023 06:49:01 +0200 Subject: [PATCH 176/216] macho: do not assume entrypoint is defined --- src/link/MachO/dead_strip.zig | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index cd64e72170..66c644ec04 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -43,15 +43,19 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void { .Exe => { // Add entrypoint as GC root const global: SymbolWithLoc = zld.getEntryPoint(); - const object = zld.objects.items[global.getFile().?]; - const atom_index = object.getAtomIndexForSymbol(global.sym_index).?; // panic here means fatal error - _ = try roots.getOrPut(atom_index); + if (global.getFile()) |file| { + const object = zld.objects.items[file]; + const atom_index = object.getAtomIndexForSymbol(global.sym_index).?; // panic here means fatal error + _ = try roots.getOrPut(atom_index); - log.debug("root(ATOM({d}, %{d}, {?d}))", .{ - atom_index, - zld.getAtom(atom_index).sym_index, - zld.getAtom(atom_index).getFile(), - }); + log.debug("root(ATOM({d}, %{d}, {?d}))", .{ + atom_index, + zld.getAtom(atom_index).sym_index, + zld.getAtom(atom_index).getFile(), + }); + } else { + assert(zld.getSymbol(global).undf()); // Stub as our entrypoint is in a dylib. + } }, else => |other| { assert(other == .Lib); From a88c0b4d089d286e36351cf476c8d982fb730541 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 1 Apr 2023 11:51:05 +0200 Subject: [PATCH 177/216] link: handle -u flag in all linkers Also clean up parsing of linker args - reuse `ArgsIterator`. In MachO, ensure we add every symbol marked with `-u` as undefined before proceeding with symbol resolution. Additionally, ensure those symbols are never garbage collected. MachO entry_in_dylib test: pass `-u _my_main` when linking executable so that it is not incorrectly garbage collected by the linker. --- lib/std/Build/CompileStep.zig | 19 ++ src/Compilation.zig | 7 +- src/clang_options_data.zig | 11 +- src/link.zig | 3 +- src/link/Coff/lld.zig | 2 +- src/link/Elf.zig | 2 +- src/link/MachO/dead_strip.zig | 52 ++-- src/link/MachO/zld.zig | 32 ++- src/link/Wasm.zig | 4 +- src/main.zig | 294 +++++++---------------- test/link/macho/entry_in_dylib/build.zig | 1 + tools/update_clang_options.zig | 4 + 12 files changed, 185 insertions(+), 246 deletions(-) diff --git a/lib/std/Build/CompileStep.zig b/lib/std/Build/CompileStep.zig index b438331991..0ee6e32826 100644 --- a/lib/std/Build/CompileStep.zig +++ b/lib/std/Build/CompileStep.zig @@ -202,6 +202,11 @@ subsystem: ?std.Target.SubSystem = null, entry_symbol_name: ?[]const u8 = null, +/// List of symbols forced as undefined in the symbol table +/// thus forcing their resolution by the linker. +/// Corresponds to `-u ` for ELF/MachO and `/include:` for COFF/PE. +force_undefined_symbols: std.StringHashMap(void), + /// Overrides the default stack size stack_size: ?u64 = null, @@ -386,6 +391,7 @@ pub fn create(owner: *std.Build, options: Options) *CompileStep { .override_dest_dir = null, .installed_path = null, .install_step = null, + .force_undefined_symbols = StringHashMap(void).init(owner.allocator), .output_path_source = GeneratedFile{ .step = &self.step }, .output_lib_path_source = GeneratedFile{ .step = &self.step }, @@ -568,6 +574,11 @@ pub fn setLinkerScriptPath(self: *CompileStep, source: FileSource) void { source.addStepDependencies(&self.step); } +pub fn forceUndefinedSymbol(self: *CompileStep, symbol_name: []const u8) void { + const b = self.step.owner; + self.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM"); +} + pub fn linkFramework(self: *CompileStep, framework_name: []const u8) void { const b = self.step.owner; self.frameworks.put(b.dupe(framework_name), .{}) catch @panic("OOM"); @@ -1266,6 +1277,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try zig_args.append(entry); } + { + var it = self.force_undefined_symbols.keyIterator(); + while (it.next()) |symbol_name| { + try zig_args.append("--force_undefined"); + try zig_args.append(symbol_name.*); + } + } + if (self.stack_size) |stack_size| { try zig_args.append("--stack"); try zig_args.append(try std.fmt.allocPrint(b.allocator, "{}", .{stack_size})); diff --git a/src/Compilation.zig b/src/Compilation.zig index 2c9b4e4063..2fdb2ae4ba 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -602,6 +602,7 @@ pub const InitOptions = struct { parent_compilation_link_libc: bool = false, hash_style: link.HashStyle = .both, entry: ?[]const u8 = null, + force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}, stack_size_override: ?u64 = null, image_base_override: ?u64 = null, self_exe_path: ?[]const u8 = null, @@ -1523,7 +1524,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .headerpad_size = options.headerpad_size, .headerpad_max_install_names = options.headerpad_max_install_names, .dead_strip_dylibs = options.dead_strip_dylibs, - .force_undefined_symbols = .{}, + .force_undefined_symbols = options.force_undefined_symbols, .pdb_source_path = options.pdb_source_path, .pdb_out_path = options.pdb_out_path, }); @@ -2186,7 +2187,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo /// to remind the programmer to update multiple related pieces of code that /// are in different locations. Bump this number when adding or deleting /// anything from the link cache manifest. -pub const link_hash_implementation_version = 7; +pub const link_hash_implementation_version = 8; fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { const gpa = comp.gpa; @@ -2196,7 +2197,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - comptime assert(link_hash_implementation_version == 7); + comptime assert(link_hash_implementation_version == 8); if (comp.bin_file.options.module) |mod| { const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{ diff --git a/src/clang_options_data.zig b/src/clang_options_data.zig index 7cee0327bf..8134d4cc06 100644 --- a/src/clang_options_data.zig +++ b/src/clang_options_data.zig @@ -1448,7 +1448,7 @@ flagpsl("MT"), .{ .name = "u", .syntax = .flag, - .zig_equivalent = .other, + .zig_equivalent = .force_undefined_symbol, .pd1 = true, .pd2 = false, .psl = true, @@ -7170,7 +7170,14 @@ joinpd1("d"), .pd2 = false, .psl = true, }, -jspd1("u"), +.{ + .name = "u", + .syntax = .joined_or_separate, + .zig_equivalent = .force_undefined_symbol, + .pd1 = true, + .pd2 = false, + .psl = false, +}, .{ .name = "x", .syntax = .joined_or_separate, diff --git a/src/link.zig b/src/link.zig index dc114eb0ad..05519ba6b5 100644 --- a/src/link.zig +++ b/src/link.zig @@ -186,8 +186,7 @@ pub const Options = struct { /// List of symbols forced as undefined in the symbol table /// thus forcing their resolution by the linker. - /// Corresponds to `-u ` for ELF and `/include:` for COFF/PE. - /// TODO add handling for MachO. + /// Corresponds to `-u ` for ELF/MachO and `/include:` for COFF/PE. force_undefined_symbols: std.StringArrayHashMapUnmanaged(void), version: ?std.builtin.Version, diff --git a/src/link/Coff/lld.zig b/src/link/Coff/lld.zig index 358c905b2c..01f724ed41 100644 --- a/src/link/Coff/lld.zig +++ b/src/link/Coff/lld.zig @@ -63,7 +63,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod man = comp.cache_parent.obtain(); self.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 7); + comptime assert(Compilation.link_hash_implementation_version == 8); for (self.base.options.objects) |obj| { _ = try man.addFile(obj.path, null); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index fcab34bf5e..95104ec2e8 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1305,7 +1305,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v // We are about to obtain this lock, so here we give other processes a chance first. self.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 7); + comptime assert(Compilation.link_hash_implementation_version == 8); try man.addOptionalFile(self.base.options.linker_script); try man.addOptionalFile(self.base.options.version_script); diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index 66c644ec04..ca0d961e2d 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -12,6 +12,7 @@ const Allocator = mem.Allocator; const AtomIndex = @import("zld.zig").AtomIndex; const Atom = @import("ZldAtom.zig"); const SymbolWithLoc = @import("zld.zig").SymbolWithLoc; +const SymbolResolver = @import("zld.zig").SymbolResolver; const UnwindInfo = @import("UnwindInfo.zig"); const Zld = @import("zld.zig").Zld; @@ -19,7 +20,7 @@ const N_DEAD = @import("zld.zig").N_DEAD; const AtomTable = std.AutoHashMap(AtomIndex, void); -pub fn gcAtoms(zld: *Zld) !void { +pub fn gcAtoms(zld: *Zld, resolver: *const SymbolResolver) !void { const gpa = zld.gpa; var arena = std.heap.ArenaAllocator.init(gpa); @@ -31,12 +32,25 @@ pub fn gcAtoms(zld: *Zld) !void { var alive = AtomTable.init(arena.allocator()); try alive.ensureTotalCapacity(@intCast(u32, zld.atoms.items.len)); - try collectRoots(zld, &roots); + try collectRoots(zld, &roots, resolver); try mark(zld, roots, &alive); prune(zld, alive); } -fn collectRoots(zld: *Zld, roots: *AtomTable) !void { +fn addRoot(zld: *Zld, roots: *AtomTable, file: u32, sym_loc: SymbolWithLoc) !void { + const sym = zld.getSymbol(sym_loc); + assert(!sym.undf()); + const object = &zld.objects.items[file]; + const atom_index = object.getAtomIndexForSymbol(sym_loc.sym_index).?; // panic here means fatal error + log.debug("root(ATOM({d}, %{d}, {d}))", .{ + atom_index, + zld.getAtom(atom_index).sym_index, + file, + }); + _ = try roots.getOrPut(atom_index); +} + +fn collectRoots(zld: *Zld, roots: *AtomTable, resolver: *const SymbolResolver) !void { log.debug("collecting roots", .{}); switch (zld.options.output_mode) { @@ -44,15 +58,7 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void { // Add entrypoint as GC root const global: SymbolWithLoc = zld.getEntryPoint(); if (global.getFile()) |file| { - const object = zld.objects.items[file]; - const atom_index = object.getAtomIndexForSymbol(global.sym_index).?; // panic here means fatal error - _ = try roots.getOrPut(atom_index); - - log.debug("root(ATOM({d}, %{d}, {?d}))", .{ - atom_index, - zld.getAtom(atom_index).sym_index, - zld.getAtom(atom_index).getFile(), - }); + try addRoot(zld, roots, file, global); } else { assert(zld.getSymbol(global).undf()); // Stub as our entrypoint is in a dylib. } @@ -64,20 +70,22 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void { const sym = zld.getSymbol(global); if (sym.undf()) continue; - const file = global.getFile() orelse continue; // synthetic globals are atomless - const object = zld.objects.items[file]; - const atom_index = object.getAtomIndexForSymbol(global.sym_index).?; // panic here means fatal error - _ = try roots.getOrPut(atom_index); - - log.debug("root(ATOM({d}, %{d}, {?d}))", .{ - atom_index, - zld.getAtom(atom_index).sym_index, - zld.getAtom(atom_index).getFile(), - }); + if (global.getFile()) |file| { + try addRoot(zld, roots, file, global); + } } }, } + // Add all symbols force-defined by the user. + for (zld.options.force_undefined_symbols.keys()) |sym_name| { + const global_index = resolver.table.get(sym_name).?; + const global = zld.globals.items[global_index]; + const sym = zld.getSymbol(global); + assert(!sym.undf()); + try addRoot(zld, roots, global.getFile().?, global); + } + for (zld.objects.items) |object| { const has_subsections = object.header.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0; diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 2e2b215698..47dd4dd54f 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -932,20 +932,29 @@ pub const Zld = struct { } } + fn forceSymbolDefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void { + const sym_index = try self.allocateSymbol(); + const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; + const sym = self.getSymbolPtr(sym_loc); + sym.n_strx = try self.strtab.insert(self.gpa, name); + sym.n_type = macho.N_UNDF | macho.N_EXT; + const global_index = try self.addGlobal(sym_loc); + try resolver.table.putNoClobber(name, global_index); + try resolver.unresolved.putNoClobber(global_index, {}); + } + fn resolveSymbols(self: *Zld, resolver: *SymbolResolver) !void { // We add the specified entrypoint as the first unresolved symbols so that // we search for it in libraries should there be no object files specified // on the linker line. if (self.options.output_mode == .Exe) { const entry_name = self.options.entry orelse load_commands.default_entry_point; - const sym_index = try self.allocateSymbol(); - const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; - const sym = self.getSymbolPtr(sym_loc); - sym.n_strx = try self.strtab.insert(self.gpa, entry_name); - sym.n_type = macho.N_UNDF | macho.N_EXT; - const global_index = try self.addGlobal(sym_loc); - try resolver.table.putNoClobber(entry_name, global_index); - try resolver.unresolved.putNoClobber(global_index, {}); + try self.forceSymbolDefined(entry_name, resolver); + } + + // Force resolution of any symbols requested by the user. + for (self.options.force_undefined_symbols.keys()) |sym_name| { + try self.forceSymbolDefined(sym_name, resolver); } for (self.objects.items, 0..) |_, object_id| { @@ -3539,7 +3548,7 @@ pub const SymbolWithLoc = extern struct { } }; -const SymbolResolver = struct { +pub const SymbolResolver = struct { arena: Allocator, table: std.StringHashMap(u32), unresolved: std.AutoArrayHashMap(u32, void), @@ -3600,7 +3609,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr // We are about to obtain this lock, so here we give other processes a chance first. macho_file.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 7); + comptime assert(Compilation.link_hash_implementation_version == 8); for (options.objects) |obj| { _ = try man.addFile(obj.path, null); @@ -3630,6 +3639,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr } link.hashAddSystemLibs(&man.hash, options.system_libs); man.hash.addOptionalBytes(options.sysroot); + man.hash.addListOfBytes(options.force_undefined_symbols.keys()); try man.addOptionalFile(options.entitlements); // We don't actually care whether it's a cache hit or miss; we just @@ -4035,7 +4045,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr } if (gc_sections) { - try dead_strip.gcAtoms(&zld); + try dead_strip.gcAtoms(&zld, &resolver); } try zld.createDyldPrivateAtom(); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index e59b83176c..b1fc25bf26 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3059,7 +3059,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l // We are about to obtain this lock, so here we give other processes a chance first. wasm.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 7); + comptime assert(Compilation.link_hash_implementation_version == 8); for (options.objects) |obj| { _ = try man.addFile(obj.path, null); @@ -4086,7 +4086,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! // We are about to obtain this lock, so here we give other processes a chance first. wasm.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 7); + comptime assert(Compilation.link_hash_implementation_version == 8); for (wasm.base.options.objects) |obj| { _ = try man.addFile(obj.path, null); diff --git a/src/main.zig b/src/main.zig index 1a445107ba..76c43476ee 100644 --- a/src/main.zig +++ b/src/main.zig @@ -478,6 +478,7 @@ const usage_build_generic = \\ --sysroot [path] Set the system root directory (usually /) \\ --version [ver] Dynamic library semver \\ --entry [name] Set the entrypoint symbol name + \\ --force_undefined [name] Specify the symbol must be defined for the link to succeed \\ -fsoname[=name] Override the default SONAME value \\ -fno-soname Disable emitting a SONAME \\ -fLLD Force using LLD as the linker @@ -680,6 +681,28 @@ const Listen = union(enum) { stdio, }; +const ArgsIterator = struct { + resp_file: ?ArgIteratorResponseFile = null, + args: []const []const u8, + i: usize = 0, + fn next(it: *@This()) ?[]const u8 { + if (it.i >= it.args.len) { + if (it.resp_file) |*resp| return resp.next(); + return null; + } + defer it.i += 1; + return it.args[it.i]; + } + fn nextOrFatal(it: *@This()) []const u8 { + if (it.i >= it.args.len) { + if (it.resp_file) |*resp| if (resp.next()) |ret| return ret; + fatal("expected parameter after {s}", .{it.args[it.i - 1]}); + } + defer it.i += 1; + return it.args[it.i]; + } +}; + fn buildOutputType( gpa: Allocator, arena: Allocator, @@ -784,6 +807,7 @@ fn buildOutputType( var test_evented_io = false; var test_no_exec = false; var entry: ?[]const u8 = null; + var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}; var stack_size_override: ?u64 = null; var image_base_override: ?u64 = null; var use_llvm: ?bool = null; @@ -917,28 +941,7 @@ fn buildOutputType( soname = .yes_default_value; - const Iterator = struct { - resp_file: ?ArgIteratorResponseFile = null, - args: []const []const u8, - i: usize = 0, - fn next(it: *@This()) ?[]const u8 { - if (it.i >= it.args.len) { - if (it.resp_file) |*resp| return resp.next(); - return null; - } - defer it.i += 1; - return it.args[it.i]; - } - fn nextOrFatal(it: *@This()) []const u8 { - if (it.i >= it.args.len) { - if (it.resp_file) |*resp| if (resp.next()) |ret| return ret; - fatal("expected parameter after {s}", .{it.args[it.i - 1]}); - } - defer it.i += 1; - return it.args[it.i]; - } - }; - var args_iter = Iterator{ + var args_iter = ArgsIterator{ .args = all_args[2..], }; @@ -1029,6 +1032,8 @@ fn buildOutputType( optimize_mode_string = args_iter.nextOrFatal(); } else if (mem.eql(u8, arg, "--entry")) { entry = args_iter.nextOrFatal(); + } else if (mem.eql(u8, arg, "--force_undefined")) { + try force_undefined_symbols.put(gpa, args_iter.nextOrFatal(), {}); } else if (mem.eql(u8, arg, "--stack")) { const next_arg = args_iter.nextOrFatal(); stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { @@ -1816,6 +1821,9 @@ fn buildOutputType( .entry => { entry = it.only_arg; }, + .force_undefined_symbol => { + try force_undefined_symbols.put(gpa, it.only_arg, {}); + }, .weak_library => try system_libs.put(it.only_arg, .{ .weak = true }), .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }), .headerpad_max_install_names => headerpad_max_install_names = true, @@ -1843,17 +1851,14 @@ fn buildOutputType( } } // Parse linker args. - var i: usize = 0; - while (i < linker_args.items.len) : (i += 1) { - const arg = linker_args.items[i]; + var linker_args_it = ArgsIterator{ + .args = linker_args.items, + }; + while (linker_args_it.next()) |arg| { if (mem.eql(u8, arg, "-soname") or mem.eql(u8, arg, "--soname")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - const name = linker_args.items[i]; + const name = linker_args_it.nextOrFatal(); soname = .{ .yes = name }; // Use it as --name. // Example: libsoundio.so.2 @@ -1881,64 +1886,37 @@ fn buildOutputType( } provided_name = name[prefix..end]; } else if (mem.eql(u8, arg, "-rpath")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try rpath_list.append(linker_args.items[i]); + try rpath_list.append(linker_args_it.nextOrFatal()); } else if (mem.eql(u8, arg, "--subsystem")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - subsystem = try parseSubSystem(linker_args.items[i]); + subsystem = try parseSubSystem(linker_args_it.nextOrFatal()); } else if (mem.eql(u8, arg, "-I") or mem.eql(u8, arg, "--dynamic-linker") or mem.eql(u8, arg, "-dynamic-linker")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - target_dynamic_linker = linker_args.items[i]; + target_dynamic_linker = linker_args_it.nextOrFatal(); } else if (mem.eql(u8, arg, "-E") or mem.eql(u8, arg, "--export-dynamic") or mem.eql(u8, arg, "-export-dynamic")) { rdynamic = true; } else if (mem.eql(u8, arg, "--version-script")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - version_script = linker_args.items[i]; + version_script = linker_args_it.nextOrFatal(); } else if (mem.eql(u8, arg, "-O")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - linker_optimization = std.fmt.parseUnsigned(u8, linker_args.items[i], 10) catch |err| { - fatal("unable to parse optimization level '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const opt = linker_args_it.nextOrFatal(); + linker_optimization = std.fmt.parseUnsigned(u8, opt, 10) catch |err| { + fatal("unable to parse optimization level '{s}': {s}", .{ opt, @errorName(err) }); }; } else if (mem.startsWith(u8, arg, "-O")) { linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| { fatal("unable to parse optimization level '{s}': {s}", .{ arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-pagezero_size")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - const next_arg = linker_args.items[i]; + const next_arg = linker_args_it.nextOrFatal(); pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { fatal("unable to parse pagezero size '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-headerpad")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - const next_arg = linker_args.items[i]; + const next_arg = linker_args_it.nextOrFatal(); headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { fatal("unable to parse headerpad size '{s}': {s}", .{ next_arg, @errorName(err) }); }; @@ -1961,11 +1939,7 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "--print-map")) { linker_print_map = true; } else if (mem.eql(u8, arg, "--sort-section")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - const arg1 = linker_args.items[i]; + const arg1 = linker_args_it.nextOrFatal(); linker_sort_section = std.meta.stringToEnum(link.SortSection, arg1) orelse { fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1}); }; @@ -1998,28 +1972,16 @@ fn buildOutputType( } else if (mem.startsWith(u8, arg, "--export=")) { try linker_export_symbol_names.append(arg["--export=".len..]); } else if (mem.eql(u8, arg, "--export")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try linker_export_symbol_names.append(linker_args.items[i]); + try linker_export_symbol_names.append(linker_args_it.nextOrFatal()); } else if (mem.eql(u8, arg, "--compress-debug-sections")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - const arg1 = linker_args.items[i]; + const arg1 = linker_args_it.nextOrFatal(); linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, arg1) orelse { fatal("expected [none|zlib] after --compress-debug-sections, found '{s}'", .{arg1}); }; } else if (mem.startsWith(u8, arg, "-z")) { var z_arg = arg[2..]; if (z_arg.len == 0) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker extension flag after '{s}'", .{arg}); - } - z_arg = linker_args.items[i]; + z_arg = linker_args_it.nextOrFatal(); } if (mem.eql(u8, z_arg, "nodelete")) { linker_z_nodelete = true; @@ -2056,51 +2018,33 @@ fn buildOutputType( fatal("unsupported linker extension flag: -z {s}", .{z_arg}); } } else if (mem.eql(u8, arg, "--major-image-version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - version.major = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { - fatal("unable to parse major image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const major = linker_args_it.nextOrFatal(); + version.major = std.fmt.parseUnsigned(u32, major, 10) catch |err| { + fatal("unable to parse major image version '{s}': {s}", .{ major, @errorName(err) }); }; have_version = true; } else if (mem.eql(u8, arg, "--minor-image-version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - version.minor = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { - fatal("unable to parse minor image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const minor = linker_args_it.nextOrFatal(); + version.minor = std.fmt.parseUnsigned(u32, minor, 10) catch |err| { + fatal("unable to parse minor image version '{s}': {s}", .{ minor, @errorName(err) }); }; have_version = true; } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - entry = linker_args.items[i]; + entry = linker_args_it.nextOrFatal(); + } else if (mem.eql(u8, arg, "-u")) { + try force_undefined_symbols.put(gpa, linker_args_it.nextOrFatal(), {}); } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - stack_size_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { - fatal("unable to parse stack size override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const stack_size = linker_args_it.nextOrFatal(); + stack_size_override = std.fmt.parseUnsigned(u64, stack_size, 0) catch |err| { + fatal("unable to parse stack size override '{s}': {s}", .{ stack_size, @errorName(err) }); }; } else if (mem.eql(u8, arg, "--image-base")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { - fatal("unable to parse image base override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const image_base = linker_args_it.nextOrFatal(); + image_base_override = std.fmt.parseUnsigned(u64, image_base, 0) catch |err| { + fatal("unable to parse image base override '{s}': {s}", .{ image_base, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - linker_script = linker_args.items[i]; + linker_script = linker_args_it.nextOrFatal(); } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { link_eh_frame_hdr = true; } else if (mem.eql(u8, arg, "--no-eh-frame-hdr")) { @@ -2138,130 +2082,74 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "--major-os-version") or mem.eql(u8, arg, "--minor-os-version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } // This option does not do anything. + _ = linker_args_it.nextOrFatal(); } else if (mem.eql(u8, arg, "--major-subsystem-version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - + const major = linker_args_it.nextOrFatal(); major_subsystem_version = std.fmt.parseUnsigned( u32, - linker_args.items[i], + major, 10, ) catch |err| { - fatal("unable to parse major subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + fatal("unable to parse major subsystem version '{s}': {s}", .{ major, @errorName(err) }); }; } else if (mem.eql(u8, arg, "--minor-subsystem-version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - + const minor = linker_args_it.nextOrFatal(); minor_subsystem_version = std.fmt.parseUnsigned( u32, - linker_args.items[i], + minor, 10, ) catch |err| { - fatal("unable to parse minor subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + fatal("unable to parse minor subsystem version '{s}': {s}", .{ minor, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-framework")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try frameworks.put(gpa, linker_args.items[i], .{}); + try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{}); } else if (mem.eql(u8, arg, "-weak_framework")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try frameworks.put(gpa, linker_args.items[i], .{ .weak = true }); + try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .weak = true }); } else if (mem.eql(u8, arg, "-needed_framework")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try frameworks.put(gpa, linker_args.items[i], .{ .needed = true }); + try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .needed = true }); } else if (mem.eql(u8, arg, "-needed_library")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try system_libs.put(linker_args.items[i], .{ .needed = true }); + try system_libs.put(linker_args_it.nextOrFatal(), .{ .needed = true }); } else if (mem.startsWith(u8, arg, "-weak-l")) { try system_libs.put(arg["-weak-l".len..], .{ .weak = true }); } else if (mem.eql(u8, arg, "-weak_library")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - try system_libs.put(linker_args.items[i], .{ .weak = true }); + try system_libs.put(linker_args_it.nextOrFatal(), .{ .weak = true }); } else if (mem.eql(u8, arg, "-compatibility_version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - compatibility_version = std.builtin.Version.parse(linker_args.items[i]) catch |err| { - fatal("unable to parse -compatibility_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const compat_version = linker_args_it.nextOrFatal(); + compatibility_version = std.builtin.Version.parse(compat_version) catch |err| { + fatal("unable to parse -compatibility_version '{s}': {s}", .{ compat_version, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-current_version")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - version = std.builtin.Version.parse(linker_args.items[i]) catch |err| { - fatal("unable to parse -current_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + const curr_version = linker_args_it.nextOrFatal(); + version = std.builtin.Version.parse(curr_version) catch |err| { + fatal("unable to parse -current_version '{s}': {s}", .{ curr_version, @errorName(err) }); }; have_version = true; } else if (mem.eql(u8, arg, "--out-implib") or mem.eql(u8, arg, "-implib")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - emit_implib = .{ .yes = linker_args.items[i] }; + emit_implib = .{ .yes = linker_args_it.nextOrFatal() }; emit_implib_arg_provided = true; } else if (mem.eql(u8, arg, "-undefined")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - if (mem.eql(u8, "dynamic_lookup", linker_args.items[i])) { + const lookup_type = linker_args_it.nextOrFatal(); + if (mem.eql(u8, "dynamic_lookup", lookup_type)) { linker_allow_shlib_undefined = true; - } else if (mem.eql(u8, "error", linker_args.items[i])) { + } else if (mem.eql(u8, "error", lookup_type)) { linker_allow_shlib_undefined = false; } else { - fatal("unsupported -undefined option '{s}'", .{linker_args.items[i]}); + fatal("unsupported -undefined option '{s}'", .{lookup_type}); } } else if (mem.eql(u8, arg, "-install_name")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - install_name = linker_args.items[i]; + install_name = linker_args_it.nextOrFatal(); } else if (mem.eql(u8, arg, "-force_load")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } try link_objects.append(.{ - .path = linker_args.items[i], + .path = linker_args_it.nextOrFatal(), .must_link = true, }); } else if (mem.eql(u8, arg, "-hash-style") or mem.eql(u8, arg, "--hash-style")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker arg after '{s}'", .{arg}); - } - const next_arg = linker_args.items[i]; + const next_arg = linker_args_it.nextOrFatal(); hash_style = std.meta.stringToEnum(link.HashStyle, next_arg) orelse { fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{ next_arg, @@ -3219,6 +3107,7 @@ fn buildOutputType( .link_eh_frame_hdr = link_eh_frame_hdr, .link_emit_relocs = link_emit_relocs, .entry = entry, + .force_undefined_symbols = force_undefined_symbols, .stack_size_override = stack_size_override, .image_base_override = image_base_override, .strip = strip, @@ -5295,6 +5184,7 @@ pub const ClangArgIterator = struct { emit_llvm, sysroot, entry, + force_undefined_symbol, weak_library, weak_framework, headerpad_max_install_names, diff --git a/test/link/macho/entry_in_dylib/build.zig b/test/link/macho/entry_in_dylib/build.zig index feaa8541b7..135661872d 100644 --- a/test/link/macho/entry_in_dylib/build.zig +++ b/test/link/macho/entry_in_dylib/build.zig @@ -31,6 +31,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize exe.linkLibrary(lib); exe.linkLibC(); exe.entry_symbol_name = "_bootstrap"; + exe.forceUndefinedSymbol("_my_main"); const check_exe = exe.checkObject(); check_exe.checkStart("segname __TEXT"); diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index a1719c5ab6..fee877add0 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -468,6 +468,10 @@ const known_options = [_]KnownOpt{ .name = "e", .ident = "entry", }, + .{ + .name = "u", + .ident = "force_undefined_symbol", + }, .{ .name = "weak-l", .ident = "weak_library", From e0bf7b6424a4b3d21e10e9371e0ebed7ba9730a5 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 1 Apr 2023 20:02:33 +0200 Subject: [PATCH 178/216] link-test: skip foreign checks in entry_in_archive MachO test --- test/link/macho/entry_in_archive/build.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/test/link/macho/entry_in_archive/build.zig b/test/link/macho/entry_in_archive/build.zig index f1eb775c0c..5d244a93fc 100644 --- a/test/link/macho/entry_in_archive/build.zig +++ b/test/link/macho/entry_in_archive/build.zig @@ -30,6 +30,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize exe.linkLibC(); const run = exe.run(); + run.skip_foreign_checks = true; run.expectExitCode(0); test_step.dependOn(&run.step); } From 43a6384e9c6ee6f3e250172f6f655782e808afed Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 1 Apr 2023 22:44:05 +0200 Subject: [PATCH 179/216] link-test: adjust test/link/bugs/macho/13056 to latest changes on macOS 13.3 Latest macOS 13.3 rolled out LLVM 15 and thus the way `nullptr_t` is defined within the `libc++`: https://github.com/llvm/llvm-project/commit/157bbe6aea22e87c822f6cda3cd404b8f657dce4 This seems to require including `/usr/include` with `-isystem` directive rather than `-I`. Otherwise we get clang miscompilation issues due to missing `nullptr_t` declaration. --- test/link/macho/bugs/13056/build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/link/macho/bugs/13056/build.zig b/test/link/macho/bugs/13056/build.zig index db7c129cbf..bcee22504f 100644 --- a/test/link/macho/bugs/13056/build.zig +++ b/test/link/macho/bugs/13056/build.zig @@ -23,7 +23,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .name = "test", .optimize = optimize, }); - exe.addIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include" }) catch unreachable); + exe.addSystemIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include" }) catch unreachable); exe.addIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include/c++/v1" }) catch unreachable); exe.addCSourceFile("test.cpp", &.{ "-nostdlib++", From ac68d72d244fafb601725d22631f7834fb14212c Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 31 Mar 2023 20:31:39 -0400 Subject: [PATCH 180/216] x86_64: implement aggregate init of a packed struct --- src/arch/x86_64/CodeGen.zig | 82 +++++++++++++++++++++++++++++---- test/behavior/packed-struct.zig | 2 - test/behavior/struct.zig | 1 - 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 604052ee7e..a216ed3c2c 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -7853,19 +7853,85 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { if (self.liveness.isUnused(inst)) break :res MCValue.dead; switch (result_ty.zigTypeTag()) { .Struct => { - if (result_ty.containerLayout() == .Packed) { - return self.fail("TODO airAggregateInit implement packed structs", .{}); - } const stack_offset = @intCast(i32, try self.allocMem(inst, abi_size, abi_align)); - for (elements, 0..) |elem, elem_i| { - if (result_ty.structFieldValueComptime(elem_i) != null) continue; // comptime elem + const dst_mcv = MCValue{ .stack_offset = stack_offset }; + if (result_ty.containerLayout() == .Packed) { + const struct_obj = result_ty.castTag(.@"struct").?.data; + try self.genInlineMemset( + dst_mcv, + .{ .immediate = 0 }, + .{ .immediate = abi_size }, + .{}, + ); + for (elements, 0..) |elem, elem_i| { + if (result_ty.structFieldValueComptime(elem_i) != null) continue; + + const elem_ty = result_ty.structFieldType(elem_i); + const elem_bit_size = @intCast(u32, elem_ty.bitSize(self.target.*)); + if (elem_bit_size > 64) { + return self.fail("TODO airAggregateInit implement packed structs with large fields", .{}); + } + const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*)); + const elem_abi_bits = elem_abi_size * 8; + const elem_off = struct_obj.packedFieldBitOffset(self.target.*, elem_i); + const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size); + const elem_bit_off = elem_off % elem_abi_bits; + const elem_mcv = try self.resolveInst(elem); + const elem_lock = switch (elem_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + .immediate => |imm| lock: { + if (imm == 0) continue; + break :lock null; + }, + else => null, + }; + defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); + const elem_reg = try self.copyToTmpRegister(elem_ty, elem_mcv); + const elem_extra_bits = self.regExtraBits(elem_ty); + if (elem_bit_off < elem_extra_bits) { + try self.truncateRegister(elem_ty, registerAlias(elem_reg, elem_abi_size)); + } + if (elem_bit_off > 0) try self.genShiftBinOpMir( + .sal, + elem_ty, + .{ .register = elem_reg }, + .{ .immediate = elem_bit_off }, + ); + try self.genBinOpMir( + .@"or", + elem_ty, + .{ .stack_offset = stack_offset - elem_byte_off }, + .{ .register = elem_reg }, + ); + if (elem_bit_off > elem_extra_bits) { + const reg = try self.copyToTmpRegister(elem_ty, elem_mcv); + if (elem_extra_bits > 0) { + try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size)); + } + try self.genShiftBinOpMir( + .sar, + elem_ty, + .{ .register = reg }, + .{ .immediate = elem_abi_bits - elem_bit_off }, + ); + try self.genBinOpMir( + .@"or", + elem_ty, + .{ .stack_offset = stack_offset - elem_byte_off - + @intCast(i32, elem_abi_size) }, + .{ .register = reg }, + ); + } + } + } else for (elements, 0..) |elem, elem_i| { + if (result_ty.structFieldValueComptime(elem_i) != null) continue; const elem_ty = result_ty.structFieldType(elem_i); - const elem_off = result_ty.structFieldOffset(elem_i, self.target.*); + const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*)); const elem_mcv = try self.resolveInst(elem); - try self.genSetStack(elem_ty, stack_offset - @intCast(i32, elem_off), elem_mcv, .{}); + try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); } - break :res MCValue{ .stack_offset = stack_offset }; + break :res dst_mcv; }, .Array => { const stack_offset = @intCast(i32, try self.allocMem(inst, abi_size, abi_align)); diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index a7dfd46064..858d4f9c17 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -352,7 +352,6 @@ test "byte-aligned field pointer offsets" { } test "load pointer from packed struct" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -585,7 +584,6 @@ test "overaligned pointer to packed struct" { test "packed struct initialized in bitcast" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const T = packed struct { val: u8 }; var val: u8 = 123; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index b59615f01a..15a9861d0f 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1244,7 +1244,6 @@ test "loading a struct pointer perfoms a copy" { } test "packed struct aggregate init" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From ccefa9dbf5369e0fadc75b9e705e74ec96a02859 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 31 Mar 2023 23:47:17 -0400 Subject: [PATCH 181/216] x86_64: implement calling var args functions --- src/arch/x86_64/CodeGen.zig | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index a216ed3c2c..45d8547082 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -316,7 +316,7 @@ pub fn generate( defer function.mir_extra.deinit(bin_file.allocator); defer if (builtin.mode == .Debug) function.mir_to_air_map.deinit(); - var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) { + var call_info = function.resolveCallingConventionValues(fn_type, &.{}) catch |err| switch (err) { error.CodegenFail => return Result{ .fail = function.err_msg.? }, error.OutOfRegisters => return Result{ .fail = try ErrorMsg.create( @@ -5191,7 +5191,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier else => unreachable, }; - var info = try self.resolveCallingConventionValues(fn_ty); + var info = try self.resolveCallingConventionValues(fn_ty, args[fn_ty.fnParamLen()..]); defer info.deinit(self); try self.spillEflagsIfOccupied(); @@ -8089,11 +8089,18 @@ const CallMCValues = struct { }; /// Caller must call `CallMCValues.deinit`. -fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { +fn resolveCallingConventionValues( + self: *Self, + fn_ty: Type, + var_args: []const Air.Inst.Ref, +) !CallMCValues { const cc = fn_ty.fnCallingConvention(); - const param_types = try self.gpa.alloc(Type, fn_ty.fnParamLen()); + const param_len = fn_ty.fnParamLen(); + const param_types = try self.gpa.alloc(Type, param_len + var_args.len); defer self.gpa.free(param_types); fn_ty.fnParamTypes(param_types); + // TODO: promote var arg types + for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.air.typeOf(arg); var result: CallMCValues = .{ .args = try self.gpa.alloc(MCValue, param_types.len), // These undefined values must be populated before returning from this function. From 677427bc3ac839629654175f0a2aaaec9fd6fb6c Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 1 Apr 2023 03:08:55 -0400 Subject: [PATCH 182/216] x86_64: implement error name --- src/arch/x86_64/CodeGen.zig | 127 ++++++++++++++++++++++++++++------- src/codegen.zig | 51 ++++++++++++-- src/link.zig | 21 ++++++ src/link/Coff.zig | 122 +++++++++++++++++++++++++++++++++ src/link/Elf.zig | 114 +++++++++++++++++++++++++++++++ src/link/MachO.zig | 130 ++++++++++++++++++++++++++++++++++-- test/behavior/bugs/6047.zig | 1 - test/behavior/defer.zig | 1 - test/behavior/error.zig | 2 - test/behavior/optional.zig | 1 - test/behavior/switch.zig | 1 - 11 files changed, 529 insertions(+), 42 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 45d8547082..684724f68e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1923,7 +1923,7 @@ fn genSetStackTruncatedOverflowCompare( ); try self.genSetStack(ty, stack_offset, .{ .register = scratch_reg }, .{}); - try self.genSetStack(Type.initTag(.u1), stack_offset - overflow_bit_offset, .{ + try self.genSetStack(Type.u1, stack_offset - overflow_bit_offset, .{ .register = overflow_reg.to8(), }, .{}); } @@ -5280,8 +5280,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.bin_file.cast(link.File.Elf)) |elf_file| { const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); - const atom = elf_file.getAtom(atom_index); - const got_addr = atom.getOffsetTableAddress(elf_file); + const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file); try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .ds, .disp = @intCast(i32, got_addr), @@ -5289,22 +5288,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl); const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; - try self.genSetReg(Type.initTag(.usize), .rax, .{ - .linker_load = .{ - .type = .got, - .sym_index = sym_index, - }, - }); + try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ + .type = .got, + .sym_index = sym_index, + } }); try self.asmRegister(.call, .rax); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl); const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; - try self.genSetReg(Type.initTag(.usize), .rax, .{ - .linker_load = .{ - .type = .got, - .sym_index = sym_index, - }, - }); + try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ + .type = .got, + .sym_index = sym_index, + } }); try self.asmRegister(.call, .rax); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { const decl_block_index = try p9.seeDecl(func.owner_decl); @@ -5325,7 +5320,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const lib_name = mem.sliceTo(extern_fn.lib_name, 0); if (self.bin_file.cast(link.File.Coff)) |coff_file| { const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); - try self.genSetReg(Type.initTag(.usize), .rax, .{ + try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ .type = .import, .sym_index = sym_index, @@ -5353,7 +5348,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier } else { assert(ty.zigTypeTag() == .Pointer); const mcv = try self.resolveInst(callee); - try self.genSetReg(Type.initTag(.usize), .rax, mcv); + try self.genSetReg(Type.usize, .rax, mcv); try self.asmRegister(.call, .rax); } @@ -7299,7 +7294,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: { const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16)); try self.genSetStack(ptr_ty, stack_offset, ptr, .{}); - try self.genSetStack(Type.initTag(.u64), stack_offset - 8, .{ .immediate = array_len }, .{}); + try self.genSetStack(Type.u64, stack_offset - 8, .{ .immediate = array_len }, .{}); break :blk .{ .stack_offset = stack_offset }; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -7809,10 +7804,92 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; - const operand = try self.resolveInst(un_op); - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else { - _ = operand; - return self.fail("TODO implement airErrorName for x86_64", .{}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const err_ty = self.air.typeOf(un_op); + const err_mcv = try self.resolveInst(un_op); + const err_reg = try self.copyToTmpRegister(err_ty, err_mcv); + const err_lock = self.register_manager.lockRegAssumeUnused(err_reg); + defer self.register_manager.unlockReg(err_lock); + + const addr_reg = try self.register_manager.allocReg(null, gp); + const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); + defer self.register_manager.unlockReg(addr_lock); + + if (self.bin_file.cast(link.File.Elf)) |elf_file| { + const atom_index = try elf_file.getOrCreateAtomForLazySymbol( + .{ .kind = .const_data, .ty = Type.anyerror }, + 4, // dword alignment + ); + const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file); + try self.asmRegisterMemory(.mov, addr_reg.to64(), Memory.sib(.qword, .{ + .base = .ds, + .disp = @intCast(i32, got_addr), + })); + } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { + const atom_index = try coff_file.getOrCreateAtomForLazySymbol( + .{ .kind = .const_data, .ty = Type.anyerror }, + 4, // dword alignment + ); + const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; + try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ + .type = .got, + .sym_index = sym_index, + } }); + } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { + const atom_index = try macho_file.getOrCreateAtomForLazySymbol( + .{ .kind = .const_data, .ty = Type.anyerror }, + 4, // dword alignment + ); + const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; + try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ + .type = .got, + .sym_index = sym_index, + } }); + } else { + return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); + } + + const start_reg = try self.register_manager.allocReg(null, gp); + const start_lock = self.register_manager.lockRegAssumeUnused(start_reg); + defer self.register_manager.unlockReg(start_lock); + + const end_reg = try self.register_manager.allocReg(null, gp); + const end_lock = self.register_manager.lockRegAssumeUnused(end_reg); + defer self.register_manager.unlockReg(end_lock); + + try self.truncateRegister(err_ty, err_reg.to32()); + + try self.asmRegisterMemory(.mov, start_reg.to32(), Memory.sib(.dword, .{ + .base = addr_reg.to64(), + .scale_index = .{ .scale = 4, .index = err_reg.to64() }, + .disp = 0, + })); + try self.asmRegisterMemory(.mov, end_reg.to32(), Memory.sib(.dword, .{ + .base = addr_reg.to64(), + .scale_index = .{ .scale = 4, .index = err_reg.to64() }, + .disp = 4, + })); + try self.asmRegisterRegister(.sub, end_reg.to32(), start_reg.to32()); + try self.asmRegisterMemory(.lea, start_reg.to64(), Memory.sib(.byte, .{ + .base = addr_reg.to64(), + .scale_index = .{ .scale = 1, .index = start_reg.to64() }, + .disp = 0, + })); + try self.asmRegisterMemory(.lea, end_reg.to32(), Memory.sib(.byte, .{ + .base = end_reg.to64(), + .disp = -1, + })); + + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.asmMemoryRegister(.mov, Memory.sib(.qword, .{ + .base = .rbp, + .disp = 0 - dst_mcv.stack_offset, + }), start_reg.to64()); + try self.asmMemoryRegister(.mov, Memory.sib(.qword, .{ + .base = .rbp, + .disp = 8 - dst_mcv.stack_offset, + }), end_reg.to64()); + break :result dst_mcv; }; return self.finishAir(inst, result, .{ un_op, .none, .none }); } @@ -8046,7 +8123,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV // This immediate is unsigned. const U = std.meta.Int(.unsigned, ti.bits - @boolToInt(ti.signedness == .signed)); if (imm >= math.maxInt(U)) { - return MCValue{ .register = try self.copyToTmpRegister(Type.initTag(.usize), mcv) }; + return MCValue{ .register = try self.copyToTmpRegister(Type.usize, mcv) }; } }, else => {}, @@ -8321,8 +8398,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { .unsigned => { const shift = @intCast(u6, max_reg_bit_width - int_info.bits); const mask = (~@as(u64, 0)) >> shift; - if (int_info.bits < 32) { - try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .immediate = mask }); + if (int_info.bits <= 32) { + try self.genBinOpMir(.@"and", Type.u32, .{ .register = reg }, .{ .immediate = mask }); } else { const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask }); try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .register = tmp_reg }); diff --git a/src/codegen.zig b/src/codegen.zig index a99ff18dfd..67ada2fedd 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -99,6 +99,47 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian mem.writeInt(Int, code[0..@sizeOf(Int)], int, endian); } +pub fn generateLazySymbol( + bin_file: *link.File, + src_loc: Module.SrcLoc, + lazy_sym: link.File.LazySymbol, + code: *std.ArrayList(u8), + debug_output: DebugInfoOutput, + reloc_info: RelocInfo, +) CodeGenError!Result { + _ = debug_output; + _ = reloc_info; + + const tracy = trace(@src()); + defer tracy.end(); + + const target = bin_file.options.target; + const endian = target.cpu.arch.endian(); + + const mod = bin_file.options.module.?; + log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ + @tagName(lazy_sym.kind), + lazy_sym.ty.fmt(mod), + }); + + if (lazy_sym.kind == .const_data and lazy_sym.ty.isAnyError()) { + const err_names = mod.error_name_list.items; + try code.resize(err_names.len * 4); + for (err_names, 0..) |err_name, index| { + mem.writeInt(u32, code.items[index * 4 ..][0..4], @intCast(u32, code.items.len), endian); + try code.ensureUnusedCapacity(err_name.len + 1); + code.appendSliceAssumeCapacity(err_name); + code.appendAssumeCapacity(0); + } + return Result.ok; + } else return .{ .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateLazySymbol for {s} {}", + .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) }, + ) }; +} + pub fn generateSymbol( bin_file: *link.File, src_loc: Module.SrcLoc, @@ -118,9 +159,10 @@ pub fn generateSymbol( const target = bin_file.options.target; const endian = target.cpu.arch.endian(); + const mod = bin_file.options.module.?; log.debug("generateSymbol: ty = {}, val = {}", .{ - typed_value.ty.fmtDebug(), - typed_value.val.fmtDebug(), + typed_value.ty.fmt(mod), + typed_value.val.fmtValue(typed_value.ty, mod), }); if (typed_value.val.isUndefDeep()) { @@ -170,7 +212,6 @@ pub fn generateSymbol( }, .str_lit => { const str_lit = typed_value.val.castTag(.str_lit).?.data; - const mod = bin_file.options.module.?; const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; try code.ensureUnusedCapacity(bytes.len + 1); code.appendSliceAssumeCapacity(bytes); @@ -300,7 +341,6 @@ pub fn generateSymbol( switch (container_ptr.tag()) { .decl_ref => { const decl_index = container_ptr.castTag(.decl_ref).?.data; - const mod = bin_file.options.module.?; const decl = mod.declPtr(decl_index); const addend = blk: { switch (decl.ty.zigTypeTag()) { @@ -493,7 +533,6 @@ pub fn generateSymbol( const field_vals = typed_value.val.castTag(.aggregate).?.data; const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow; const current_pos = code.items.len; - const mod = bin_file.options.module.?; try code.resize(current_pos + abi_size); var bits: u16 = 0; @@ -570,7 +609,6 @@ pub fn generateSymbol( } const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data; - const mod = bin_file.options.module.?; const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?; assert(union_ty.haveFieldTypes()); const field_ty = union_ty.fields.values()[field_index].ty; @@ -776,7 +814,6 @@ pub fn generateSymbol( }, .str_lit => { const str_lit = typed_value.val.castTag(.str_lit).?.data; - const mod = bin_file.options.module.?; const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; try code.ensureUnusedCapacity(str_lit.len); code.appendSliceAssumeCapacity(bytes); diff --git a/src/link.zig b/src/link.zig index 05519ba6b5..7ca94f4f6d 100644 --- a/src/link.zig +++ b/src/link.zig @@ -687,6 +687,7 @@ pub const File = struct { FrameworkNotFound, FunctionSignatureMismatch, GlobalTypeMismatch, + HotSwapUnavailableOnHostOperatingSystem, InvalidCharacter, InvalidEntryKind, InvalidFeatureSet, @@ -1104,6 +1105,26 @@ pub const File = struct { missing_libc: bool = false, }; + pub const LazySymbol = struct { + kind: enum { code, const_data }, + ty: Type, + + pub const Context = struct { + mod: *Module, + + pub fn hash(ctx: @This(), sym: LazySymbol) u32 { + var hasher = std.hash.Wyhash.init(0); + std.hash.autoHash(&hasher, sym.kind); + sym.ty.hashWithHasher(&hasher, ctx.mod); + return @truncate(u32, hasher.final()); + } + + pub fn eql(ctx: @This(), lhs: LazySymbol, rhs: LazySymbol, _: usize) bool { + return lhs.kind == rhs.kind and lhs.ty.eql(rhs.ty, ctx.mod); + } + }; + }; + pub const C = @import("link/C.zig"); pub const Coff = @import("link/Coff.zig"); pub const Plan9 = @import("link/Plan9.zig"); diff --git a/src/link/Coff.zig b/src/link/Coff.zig index f3068f01a9..800f96e90c 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -49,6 +49,9 @@ imports_count_dirty: bool = true, /// Virtual address of the entry point procedure relative to image base. entry_addr: ?u32 = null, +/// Table of tracked LazySymbols. +lazy_syms: LazySymbolTable = .{}, + /// Table of tracked Decls. decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, @@ -142,6 +145,18 @@ const Section = struct { free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, }; +const LazySymbolTable = std.ArrayHashMapUnmanaged( + link.File.LazySymbol, + LazySymbolMetadata, + link.File.LazySymbol.Context, + true, +); + +const LazySymbolMetadata = struct { + atom: Atom.Index, + section: u16, +}; + const DeclMetadata = struct { atom: Atom.Index, section: u16, @@ -1168,6 +1183,100 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); } +fn updateLazySymbol( + self: *Coff, + lazy_sym: link.File.LazySymbol, + lazy_metadata: LazySymbolMetadata, +) !void { + const gpa = self.base.allocator; + const mod = self.base.options.module.?; + + var code_buffer = std.ArrayList(u8).init(gpa); + defer code_buffer.deinit(); + + const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ + @tagName(lazy_sym.kind), + lazy_sym.ty.fmt(mod), + }); + defer gpa.free(name); + + const atom_index = lazy_metadata.atom; + const atom = self.getAtomPtr(atom_index); + const local_sym_index = atom.getSymbolIndex().?; + + const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl| + mod.declPtr(owner_decl).srcLoc() + else + Module.SrcLoc{ + .file_scope = undefined, + .parent_decl_node = undefined, + .lazy = .unneeded, + }; + const res = try codegen.generateLazySymbol( + &self.base, + src, + lazy_sym, + &code_buffer, + .none, + .{ .parent_atom_index = local_sym_index }, + ); + const code = switch (res) { + .ok => code_buffer.items, + .fail => |em| { + log.err("{s}", .{em.msg}); + return error.CodegenFail; + }, + }; + + const required_alignment = atom.alignment; + const code_len = @intCast(u32, code.len); + const symbol = atom.getSymbolPtr(self); + try self.setSymbolName(symbol, name); + symbol.section_number = @intToEnum(coff.SectionNumber, lazy_metadata.section + 1); + symbol.type = .{ .complex_type = .NULL, .base_type = .NULL }; + + const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); + errdefer self.freeAtom(atom_index); + + log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr }); + log.debug(" (required alignment 0x{x})", .{required_alignment}); + + atom.size = code_len; + symbol.value = vaddr; + + const got_target = SymbolWithLoc{ .sym_index = local_sym_index, .file = null }; + const got_index = try self.allocateGotEntry(got_target); + const got_atom_index = try self.createGotAtom(got_target); + const got_atom = self.getAtom(got_atom_index); + self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; + try self.writePtrWidthAtom(got_atom_index); + + self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); + try self.writeAtom(atom_index, code); +} + +pub fn getOrCreateAtomForLazySymbol( + self: *Coff, + lazy_sym: link.File.LazySymbol, + alignment: u32, +) !Atom.Index { + const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{ + .mod = self.base.options.module.?, + }); + errdefer _ = self.lazy_syms.pop(); + if (!gop.found_existing) { + gop.value_ptr.* = .{ + .atom = try self.createAtom(), + .section = switch (lazy_sym.kind) { + .code => self.text_section_index.?, + .const_data => self.rdata_section_index.?, + }, + }; + self.getAtomPtr(gop.value_ptr.atom).alignment = alignment; + } + return gop.value_ptr.atom; +} + pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index { const gop = try self.decls.getOrPut(self.base.allocator, decl_index); if (!gop.found_existing) { @@ -1498,6 +1607,19 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod sub_prog_node.activate(); defer sub_prog_node.end(); + { + var lazy_it = self.lazy_syms.iterator(); + while (lazy_it.next()) |lazy_entry| { + self.updateLazySymbol( + lazy_entry.key_ptr.*, + lazy_entry.value_ptr.*, + ) catch |err| switch (err) { + error.CodegenFail => return error.FlushFailure, + else => |e| return e, + }; + } + } + const gpa = self.base.allocator; while (self.unresolved.popOrNull()) |entry| { diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 95104ec2e8..3b7c2efa0e 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -63,6 +63,12 @@ const Section = struct { free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, }; +const LazySymbolMetadata = struct { + atom: Atom.Index, + shdr: u16, + alignment: u32, +}; + const DeclMetadata = struct { atom: Atom.Index, shdr: u16, @@ -157,6 +163,9 @@ debug_line_header_dirty: bool = false, error_flags: File.ErrorFlags = File.ErrorFlags{}, +/// Table of tracked LazySymbols. +lazy_syms: LazySymbolTable = .{}, + /// Table of tracked Decls. decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, @@ -194,6 +203,7 @@ relocs: RelocTable = .{}, const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc)); const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); +const LazySymbolTable = std.ArrayHashMapUnmanaged(File.LazySymbol, LazySymbolMetadata, File.LazySymbol.Context, true); /// When allocating, the ideal_capacity is calculated by /// actual_capacity + (actual_capacity / ideal_factor) @@ -1011,6 +1021,19 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node sub_prog_node.activate(); defer sub_prog_node.end(); + { + var lazy_it = self.lazy_syms.iterator(); + while (lazy_it.next()) |lazy_entry| { + self.updateLazySymbol( + lazy_entry.key_ptr.*, + lazy_entry.value_ptr.*, + ) catch |err| switch (err) { + error.CodegenFail => return error.FlushFailure, + else => |e| return e, + }; + } + } + // TODO This linker code currently assumes there is only 1 compilation unit and it // corresponds to the Zig source code. const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; @@ -2344,6 +2367,24 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void { } } +pub fn getOrCreateAtomForLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, alignment: u32) !Atom.Index { + const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{ + .mod = self.base.options.module.?, + }); + errdefer _ = self.lazy_syms.pop(); + if (!gop.found_existing) { + gop.value_ptr.* = .{ + .atom = try self.createAtom(), + .shdr = switch (lazy_sym.kind) { + .code => self.text_section_index.?, + .const_data => self.rodata_section_index.?, + }, + .alignment = alignment, + }; + } + return gop.value_ptr.atom; +} + pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index { const gop = try self.decls.getOrPut(self.base.allocator, decl_index); if (!gop.found_existing) { @@ -2610,6 +2651,79 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); } +fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void { + const gpa = self.base.allocator; + const mod = self.base.options.module.?; + + var code_buffer = std.ArrayList(u8).init(gpa); + defer code_buffer.deinit(); + + const name_str_index = blk: { + const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ + @tagName(lazy_sym.kind), + lazy_sym.ty.fmt(mod), + }); + defer gpa.free(name); + break :blk try self.shstrtab.insert(gpa, name); + }; + const name = self.shstrtab.get(name_str_index).?; + + const atom_index = lazy_metadata.atom; + const atom = self.getAtom(atom_index); + const local_sym_index = atom.getSymbolIndex().?; + + const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl| + mod.declPtr(owner_decl).srcLoc() + else + Module.SrcLoc{ + .file_scope = undefined, + .parent_decl_node = undefined, + .lazy = .unneeded, + }; + const res = try codegen.generateLazySymbol( + &self.base, + src, + lazy_sym, + &code_buffer, + .none, + .{ .parent_atom_index = local_sym_index }, + ); + const code = switch (res) { + .ok => code_buffer.items, + .fail => |em| { + log.err("{s}", .{em.msg}); + return error.CodegenFail; + }, + }; + + const shdr_index = lazy_metadata.shdr; + const phdr_index = self.sections.items(.phdr_index)[shdr_index]; + const local_sym = atom.getSymbolPtr(self); + local_sym.* = .{ + .st_name = name_str_index, + .st_info = (elf.STB_LOCAL << 4) | elf.STT_OBJECT, + .st_other = 0, + .st_shndx = shdr_index, + .st_value = 0, + .st_size = 0, + }; + const required_alignment = lazy_metadata.alignment; + const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment); + errdefer self.freeAtom(atom_index); + log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr }); + + self.offset_table.items[atom.offset_table_index] = vaddr; + local_sym.st_value = vaddr; + local_sym.st_size = code.len; + + try self.writeSymbol(local_sym_index); + try self.writeOffsetTableEntry(atom.offset_table_index); + + const section_offset = vaddr - self.program_headers.items[phdr_index].p_vaddr; + const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset; + try self.base.file.?.pwriteAll(code, file_offset); +} + pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module.Decl.Index) !u32 { const gpa = self.base.allocator; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 4c3301a3b4..7840f5d89d 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -218,6 +218,9 @@ bindings: BindingTable = .{}, /// this will be a table indexed by index into the list of Atoms. lazy_bindings: BindingTable = .{}, +/// Table of tracked LazySymbols. +lazy_syms: LazySymbolTable = .{}, + /// Table of tracked Decls. decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, @@ -229,6 +232,18 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) { else => false, }; +const LazySymbolTable = std.ArrayHashMapUnmanaged( + link.File.LazySymbol, + LazySymbolMetadata, + link.File.LazySymbol.Context, + true, +); + +const LazySymbolMetadata = struct { + atom: Atom.Index, + section: u8, +}; + const DeclMetadata = struct { atom: Atom.Index, section: u8, @@ -497,6 +512,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No sub_prog_node.activate(); defer sub_prog_node.end(); + { + var lazy_it = self.lazy_syms.iterator(); + while (lazy_it.next()) |lazy_entry| { + self.updateLazySymbol( + lazy_entry.key_ptr.*, + lazy_entry.value_ptr.*, + ) catch |err| switch (err) { + error.CodegenFail => return error.FlushFailure, + else => |e| return e, + }; + } + } + const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; if (self.d_sym) |*d_sym| { @@ -2163,13 +2191,13 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu const name_str_index = blk: { const index = unnamed_consts.items.len; - const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); + const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index }); defer gpa.free(name); break :blk try self.strtab.insert(gpa, name); }; - const name = self.strtab.get(name_str_index); + const name = self.strtab.get(name_str_index).?; - log.debug("allocating symbol indexes for {?s}", .{name}); + log.debug("allocating symbol indexes for {s}", .{name}); const atom_index = try self.createAtom(); @@ -2202,7 +2230,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu try unnamed_consts.append(gpa, atom_index); - log.debug("allocated atom for {?s} at 0x{x}", .{ name, symbol.n_value }); + log.debug("allocated atom for {s} at 0x{x}", .{ name, symbol.n_value }); log.debug(" (required alignment 0x{x})", .{required_alignment}); try self.writeAtom(atom_index, code); @@ -2282,6 +2310,100 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); } +fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void { + const gpa = self.base.allocator; + const mod = self.base.options.module.?; + + var code_buffer = std.ArrayList(u8).init(gpa); + defer code_buffer.deinit(); + + const name_str_index = blk: { + const name = try std.fmt.allocPrint(gpa, "___lazy_{s}_{}", .{ + @tagName(lazy_sym.kind), + lazy_sym.ty.fmt(mod), + }); + defer gpa.free(name); + break :blk try self.strtab.insert(gpa, name); + }; + const name = self.strtab.get(name_str_index).?; + + const atom_index = lazy_metadata.atom; + const atom = self.getAtomPtr(atom_index); + const local_sym_index = atom.getSymbolIndex().?; + + const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl| + mod.declPtr(owner_decl).srcLoc() + else + Module.SrcLoc{ + .file_scope = undefined, + .parent_decl_node = undefined, + .lazy = .unneeded, + }; + const res = try codegen.generateLazySymbol( + &self.base, + src, + lazy_sym, + &code_buffer, + .none, + .{ .parent_atom_index = local_sym_index }, + ); + const code = switch (res) { + .ok => code_buffer.items, + .fail => |em| { + log.err("{s}", .{em.msg}); + return error.CodegenFail; + }, + }; + + const required_alignment = atom.alignment; + const symbol = atom.getSymbolPtr(self); + symbol.n_strx = name_str_index; + symbol.n_type = macho.N_SECT; + symbol.n_sect = lazy_metadata.section + 1; + symbol.n_desc = 0; + + const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment); + errdefer self.freeAtom(atom_index); + + log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr }); + log.debug(" (required alignment 0x{x}", .{required_alignment}); + + atom.size = code.len; + symbol.n_value = vaddr; + + const got_target = SymbolWithLoc{ .sym_index = local_sym_index, .file = null }; + const got_index = try self.allocateGotEntry(got_target); + const got_atom_index = try self.createGotAtom(got_target); + const got_atom = self.getAtom(got_atom_index); + self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; + try self.writePtrWidthAtom(got_atom_index); + + self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); + try self.writeAtom(atom_index, code); +} + +pub fn getOrCreateAtomForLazySymbol( + self: *MachO, + lazy_sym: File.LazySymbol, + alignment: u32, +) !Atom.Index { + const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{ + .mod = self.base.options.module.?, + }); + errdefer _ = self.lazy_syms.pop(); + if (!gop.found_existing) { + gop.value_ptr.* = .{ + .atom = try self.createAtom(), + .section = switch (lazy_sym.kind) { + .code => self.text_section_index.?, + .const_data => self.data_const_section_index.?, + }, + }; + self.getAtomPtr(gop.value_ptr.atom).alignment = alignment; + } + return gop.value_ptr.atom; +} + pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { const gop = try self.decls.getOrPut(self.base.allocator, decl_index); if (!gop.found_existing) { diff --git a/test/behavior/bugs/6047.zig b/test/behavior/bugs/6047.zig index 22d660991a..d3c2c8349c 100644 --- a/test/behavior/bugs/6047.zig +++ b/test/behavior/bugs/6047.zig @@ -11,7 +11,6 @@ fn getError2() !void { test "`try`ing an if/else expression" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index 26c2adc271..c5ea12aff0 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -110,7 +110,6 @@ test "mixing normal and error defers" { } test "errdefer with payload" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/error.zig b/test/behavior/error.zig index a708971a49..6460c5089c 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -575,7 +575,6 @@ fn gimmeItBroke() anyerror { } test "@errorName sentinel length matches slice length" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -851,7 +850,6 @@ test "catch within a function that calls no errorable functions" { test "error from comptime string" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const name = "Weird error name!"; diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 9fb0a617a3..1716ccd9c4 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -468,7 +468,6 @@ test "peer type resolution in nested if expressions" { test "cast slice to const slice nested in error union and optional" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const S = struct { fn inner() !?[]u8 { diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 52f5b79723..e02a66f54b 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -419,7 +419,6 @@ test "switch on integer with else capturing expr" { } test "else prong of switch on error set excludes other cases" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From 83a208c3551ae470f92753592a4c88984d2154d3 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 1 Apr 2023 22:10:15 -0400 Subject: [PATCH 183/216] x86_64: implement large cmp --- lib/std/os.zig | 2 + lib/std/start.zig | 24 +- src/arch/x86_64/CodeGen.zig | 451 ++++++++---------- src/arch/x86_64/bits.zig | 10 + test/behavior/align.zig | 3 - test/behavior/basic.zig | 8 - test/behavior/bitcast.zig | 1 - test/behavior/bugs/6905.zig | 1 - ...n_functions_returning_void_or_noreturn.zig | 1 - test/behavior/cast.zig | 1 - test/behavior/cast_int.zig | 1 - test/behavior/error.zig | 2 - test/behavior/eval.zig | 1 - test/behavior/int128.zig | 3 - test/behavior/int_div.zig | 1 - test/behavior/optional.zig | 1 - test/behavior/pointers.zig | 1 - test/behavior/struct.zig | 1 - test/behavior/typename.zig | 6 - .../hello_world_with_updates.0.zig | 2 +- .../hello_world_with_updates.0.zig | 2 +- .../hello_world_with_updates.0.zig | 2 +- .../hello_world_with_updates.0.zig | 2 +- 23 files changed, 227 insertions(+), 300 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 12cda72e40..2b604f19fe 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1937,6 +1937,8 @@ pub fn getenv(key: []const u8) ?[]const u8 { if (builtin.os.tag == .windows) { @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API."); } + // The simplified start logic doesn't populate environ. + if (std.start.simplified_logic) return null; // TODO see https://github.com/ziglang/zig/issues/4524 for (environ) |ptr| { var line_i: usize = 0; diff --git a/lib/std/start.zig b/lib/std/start.zig index 6edebde122..b3a064c7f0 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -14,22 +14,24 @@ var argc_argv_ptr: [*]usize = undefined; const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start"; +// The self-hosted compiler is not fully capable of handling all of this start.zig file. +// Until then, we have simplified logic here for self-hosted. TODO remove this once +// self-hosted is capable enough to handle all of the real start.zig logic. +pub const simplified_logic = + builtin.zig_backend == .stage2_wasm or + builtin.zig_backend == .stage2_x86_64 or + builtin.zig_backend == .stage2_x86 or + builtin.zig_backend == .stage2_aarch64 or + builtin.zig_backend == .stage2_arm or + builtin.zig_backend == .stage2_riscv64 or + builtin.zig_backend == .stage2_sparc64; + comptime { // No matter what, we import the root file, so that any export, test, comptime // decls there get run. _ = root; - // The self-hosted compiler is not fully capable of handling all of this start.zig file. - // Until then, we have simplified logic here for self-hosted. TODO remove this once - // self-hosted is capable enough to handle all of the real start.zig logic. - if (builtin.zig_backend == .stage2_wasm or - builtin.zig_backend == .stage2_x86_64 or - builtin.zig_backend == .stage2_x86 or - builtin.zig_backend == .stage2_aarch64 or - builtin.zig_backend == .stage2_arm or - builtin.zig_backend == .stage2_riscv64 or - builtin.zig_backend == .stage2_sparc64) - { + if (simplified_logic) { if (builtin.output_mode == .Exe) { if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) { if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) { diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 684724f68e..578c32ace3 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3986,7 +3986,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue .eflags => unreachable, .register_overflow => unreachable, .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), - .ptr_stack_offset, .stack_offset => |off| { + .stack_offset => |off| { if (abi_size > 8) { return self.fail("TODO implement {} for stack dst with large ABI", .{mir_tag}); } @@ -3996,20 +3996,13 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue .disp = -off, })); }, + .ptr_stack_offset => unreachable, .memory, .linker_load => { const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_reg_lock); try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv); - - // To get the actual address of the value we want to modify we have to go through the GOT - try self.asmRegisterMemory( - .mov, - addr_reg, - Memory.sib(.qword, .{ .base = addr_reg }), - ); - try self.asmMemory( mir_tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), @@ -4454,7 +4447,7 @@ fn genBinOp( else => false, }; - const needs_reg_dst = switch (tag) { + const dst_mem_ok = switch (tag) { .add, .addwrap, .sub, @@ -4464,9 +4457,9 @@ fn genBinOp( .div_exact, .div_trunc, .div_floor, - => lhs_ty.isRuntimeFloat(), + => !lhs_ty.isRuntimeFloat(), - else => false, + else => true, }; const lhs_lock: ?RegisterLock = switch (lhs) { @@ -4482,18 +4475,21 @@ fn genBinOp( defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); var flipped: bool = false; - const dst_mcv: MCValue = blk: { + const dst_mcv: MCValue = dst: { if (maybe_inst) |inst| { - if ((!needs_reg_dst or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) { - break :blk lhs; + if ((dst_mem_ok or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) { + break :dst lhs; } - if (is_commutative and (!needs_reg_dst or rhs.isRegister()) and self.reuseOperand(inst, rhs_air, 1, rhs)) { + if (is_commutative and (dst_mem_ok or rhs.isRegister()) and + self.reuseOperand(inst, rhs_air, 1, rhs)) + { flipped = true; - break :blk rhs; + break :dst rhs; } - break :blk try self.copyToRegisterWithInstTracking(inst, lhs_ty, lhs); } - break :blk MCValue{ .register = try self.copyToTmpRegister(lhs_ty, lhs) }; + const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); + try self.setRegOrMem(lhs_ty, dst_mcv, lhs); + break :dst dst_mcv; }; const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { .register => |reg| self.register_manager.lockReg(reg), @@ -4501,17 +4497,7 @@ fn genBinOp( }; defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); - const src_mcv: MCValue = blk: { - const mcv = if (flipped) lhs else rhs; - if (mcv.isRegister() or mcv.isMemory()) break :blk mcv; - break :blk MCValue{ .register = try self.copyToTmpRegister(rhs_ty, mcv) }; - }; - const src_mcv_lock: ?RegisterLock = switch (src_mcv) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (src_mcv_lock) |lock| self.register_manager.unlockReg(lock); - + const src_mcv = if (flipped) lhs else rhs; switch (tag) { .add, .addwrap, @@ -4573,14 +4559,18 @@ fn genBinOp( .ptr_add, .ptr_sub, => { - const mir_tag: Mir.Inst.Tag = switch (tag) { + const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv); + const tmp_mcv = MCValue{ .register = tmp_reg }; + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); + + const elem_size = lhs_ty.elemType2().abiSize(self.target.*); + try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size }); + try self.genBinOpMir(switch (tag) { .ptr_add => .add, .ptr_sub => .sub, else => unreachable, - }; - const elem_size = lhs_ty.elemType2().abiSize(self.target.*); - try self.genIntMulComplexOpMir(rhs_ty, src_mcv, .{ .immediate = elem_size }); - try self.genBinOpMir(mir_tag, lhs_ty, dst_mcv, src_mcv); + }, lhs_ty, dst_mcv, tmp_mcv); }, .bool_or, @@ -4657,16 +4647,8 @@ fn genBinOp( const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_reg_lock); + try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mat_src_mcv); - - // To get the actual address of the value we want to modify we - // we have to go through the GOT - try self.asmRegisterMemory( - .mov, - addr_reg, - Memory.sib(.qword, .{ .base = addr_reg }), - ); - try self.asmCmovccRegisterMemory( registerAlias(tmp_reg, abi_size), Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), @@ -4706,6 +4688,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s .eflags => unreachable, .register_overflow => unreachable, .register => |dst_reg| { + const dst_alias = registerAlias(dst_reg, abi_size); switch (src_mcv) { .none => unreachable, .undef => unreachable, @@ -4728,41 +4711,47 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s }, else => try self.asmRegisterRegister( mir_tag, - registerAlias(dst_reg, abi_size), + dst_alias, registerAlias(src_reg, abi_size), ), }, .immediate => |imm| { switch (self.regBitSize(ty)) { - 8, 16, 32 => { - try self.asmRegisterImmediate( - mir_tag, - registerAlias(dst_reg, abi_size), + 8 => try self.asmRegisterImmediate( + mir_tag, + dst_alias, + if (math.cast(i8, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u8, imm)), + ), + 16 => try self.asmRegisterImmediate( + mir_tag, + dst_alias, + if (math.cast(i16, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u16, imm)), + ), + 32 => try self.asmRegisterImmediate( + mir_tag, + dst_alias, + if (math.cast(i32, @bitCast(i64, imm))) |small| + Immediate.s(small) + else Immediate.u(@intCast(u32, imm)), - ); - }, - 64 => { - if (math.cast(i32, @bitCast(i64, imm))) |small| { - try self.asmRegisterImmediate( - mir_tag, - registerAlias(dst_reg, abi_size), - Immediate.s(small), - ); - } else { - try self.asmRegisterRegister( - mir_tag, - registerAlias(dst_reg, abi_size), - registerAlias(try self.copyToTmpRegister(ty, src_mcv), abi_size), - ); - } - }, - else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}), + ), + 64 => if (math.cast(i32, @bitCast(i64, imm))) |small| + try self.asmRegisterImmediate(mir_tag, dst_alias, Immediate.s(small)) + else + try self.asmRegisterRegister(mir_tag, dst_alias, registerAlias( + try self.copyToTmpRegister(ty, src_mcv), + abi_size, + )), + else => unreachable, } }, - .memory, - .linker_load, - .eflags, - => { + .memory, .linker_load, .eflags => { assert(abi_size <= 8); const dst_reg_lock = self.register_manager.lockReg(dst_reg); defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); @@ -4779,7 +4768,27 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s }, } }, - .ptr_stack_offset, .stack_offset => |dst_off| { + .memory, .linker_load, .stack_offset => { + const dst: ?struct { + addr_reg: Register, + addr_lock: RegisterLock, + } = switch (dst_mcv) { + else => unreachable, + .memory, .linker_load => dst: { + const dst_addr_reg = try self.register_manager.allocReg(null, gp); + const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); + errdefer self.register_manager.unlockReg(dst_addr_lock); + + try self.loadMemPtrIntoRegister(dst_addr_reg, Type.usize, dst_mcv); + break :dst .{ + .addr_reg = dst_addr_reg, + .addr_lock = dst_addr_lock, + }; + }, + .stack_offset => null, + }; + defer if (dst) |lock| self.register_manager.unlockReg(lock.addr_lock); + const src: ?struct { limb_reg: Register, limb_lock: RegisterLock, @@ -4787,7 +4796,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s addr_lock: RegisterLock, } = switch (src_mcv) { else => null, - .memory, .linker_load => addr: { + .memory, .linker_load => src: { const src_limb_reg = try self.register_manager.allocReg(null, gp); const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); errdefer self.register_manager.unlockReg(src_limb_lock); @@ -4797,15 +4806,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s errdefer self.register_manager.unlockReg(src_addr_lock); try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_mcv); - // To get the actual address of the value we want to modify we - // we have to go through the GOT - try self.asmRegisterMemory( - .mov, - src_addr_reg, - Memory.sib(.qword, .{ .base = src_addr_reg }), - ); - - break :addr .{ + break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock, .limb_reg = src_limb_reg, @@ -4831,7 +4832,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s 0 => mir_tag, else => switch (mir_tag) { .add => .adc, - .sub => .sbb, + .sub, .cmp => .sbb, .@"or", .@"and", .xor => mir_tag, else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{ @tagName(mir_tag), @@ -4840,7 +4841,14 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s }; const dst_limb_mem = Memory.sib( Memory.PtrSize.fromSize(limb_abi_size), - .{ .base = .rbp, .disp = off - dst_off }, + switch (dst_mcv) { + else => unreachable, + .stack_offset => |dst_off| .{ + .base = .rbp, + .disp = off - dst_off, + }, + .memory, .linker_load => .{ .base = dst.?.addr_reg, .disp = off }, + }, ); switch (src_mcv) { .none => unreachable, @@ -4861,34 +4869,45 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s .unsigned => 0, }; switch (self.regBitSize(limb_ty)) { - 8, 16, 32 => { + 8 => try self.asmMemoryImmediate( + mir_limb_tag, + dst_limb_mem, + if (math.cast(i8, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u8, imm)), + ), + 16 => try self.asmMemoryImmediate( + mir_limb_tag, + dst_limb_mem, + if (math.cast(i16, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u16, imm)), + ), + 32 => try self.asmMemoryImmediate( + mir_limb_tag, + dst_limb_mem, + if (math.cast(i32, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u32, imm)), + ), + 64 => if (math.cast(i32, @bitCast(i64, imm))) |small| try self.asmMemoryImmediate( mir_limb_tag, dst_limb_mem, - if (math.cast(i32, @bitCast(i64, imm))) |small| - Immediate.s(small) - else - Immediate.u(@intCast(u32, imm)), - ); - }, - 64 => { - if (math.cast(i32, @bitCast(i64, imm))) |small| { - try self.asmMemoryImmediate( - mir_limb_tag, - dst_limb_mem, - Immediate.s(small), - ); - } else { - try self.asmMemoryRegister( - mir_limb_tag, - dst_limb_mem, - registerAlias( - try self.copyToTmpRegister(limb_ty, .{ .immediate = imm }), - limb_abi_size, - ), - ); - } - }, + Immediate.s(small), + ) + else + try self.asmMemoryRegister( + mir_limb_tag, + dst_limb_mem, + registerAlias( + try self.copyToTmpRegister(limb_ty, .{ .immediate = imm }), + limb_abi_size, + ), + ), else => unreachable, } }, @@ -4930,12 +4949,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s } } }, - .memory => { - return self.fail("TODO implement x86 genBinOpMir destination memory", .{}); - }, - .linker_load => { - return self.fail("TODO implement x86 genBinOpMir destination symbol at index", .{}); - }, + .ptr_stack_offset => unreachable, } } @@ -5452,79 +5466,61 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ty = self.air.typeOf(bin_op.lhs); + const ty_abi_size = ty.abiSize(self.target.*); + const can_reuse = ty_abi_size <= 8; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } + try self.spillEflagsIfOccupied(); + self.eflags_inst = inst; - const ty = self.air.typeOf(bin_op.lhs); - const abi_size = ty.abiSize(self.target.*); - if (abi_size > 8) return self.fail("TODO implement cmp for large values", .{}); - - const signedness: std.builtin.Signedness = blk: { - // For non-int types, we treat the values as unsigned - if (ty.zigTypeTag() != .Int) break :blk .unsigned; - - // Otherwise, we take the signedness of the actual int - break :blk ty.intInfo(self.target.*).signedness; - }; - - try self.spillEflagsIfOccupied(); - self.eflags_inst = inst; - - const result: MCValue = result: { - // There are 2 operands, destination and source. - // Either one, but not both, can be a memory operand. - // Source operand can be an immediate, 8 bits or 32 bits. - // TODO look into reusing the operand - const lhs = try self.resolveInst(bin_op.lhs); - const lhs_lock: ?RegisterLock = switch (lhs) { + const lhs_mcv = try self.resolveInst(bin_op.lhs); + const lhs_lock = switch (lhs_mcv) { .register => |reg| self.register_manager.lockRegAssumeUnused(reg), else => null, }; defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); - const dst_reg = try self.copyToTmpRegister(ty, lhs); - const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg); - defer self.register_manager.unlockReg(dst_reg_lock); - - const dst_mcv = MCValue{ .register = dst_reg }; - - const rhs_ty = self.air.typeOf(bin_op.rhs); - // This instruction supports only signed 32-bit immediates at most. - const src_mcv: MCValue = blk: { - switch (rhs_ty.zigTypeTag()) { - .Float => { - const rhs = try self.resolveInst(bin_op.rhs); - const rhs_lock: ?RegisterLock = switch (rhs) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); - const src_reg = try self.copyToTmpRegister(rhs_ty, rhs); - break :blk MCValue{ .register = src_reg }; - }, - else => break :blk try self.limitImmediateType(bin_op.rhs, i32), - } + const rhs_mcv = try self.resolveInst(bin_op.rhs); + const rhs_lock = switch (rhs_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, }; - const src_lock: ?RegisterLock = switch (src_mcv) { + defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mem_ok = !ty.isRuntimeFloat(); + var flipped = false; + const dst_mcv: MCValue = if (can_reuse and !lhs_mcv.isImmediate() and + (dst_mem_ok or lhs_mcv.isRegister()) and self.liveness.operandDies(inst, 0)) + lhs_mcv + else if (can_reuse and !rhs_mcv.isImmediate() and + (dst_mem_ok or rhs_mcv.isRegister()) and self.liveness.operandDies(inst, 1)) + dst: { + flipped = true; + break :dst rhs_mcv; + } else if (dst_mem_ok) dst: { + const dst_mcv = try self.allocTempRegOrMem(ty, true); + try self.setRegOrMem(ty, dst_mcv, lhs_mcv); + break :dst dst_mcv; + } else .{ .register = try self.copyToTmpRegister(ty, lhs_mcv) }; + const dst_lock = switch (dst_mcv) { .register => |reg| self.register_manager.lockReg(reg), else => null, }; - defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + const src_mcv = if (flipped) lhs_mcv else rhs_mcv; try self.genBinOpMir(switch (ty.tag()) { else => .cmp, .f32 => .ucomiss, .f64 => .ucomisd, }, ty, dst_mcv, src_mcv); - break :result switch (signedness) { - .signed => MCValue{ .eflags = Condition.fromCompareOperatorSigned(op) }, - .unsigned => MCValue{ .eflags = Condition.fromCompareOperatorUnsigned(op) }, + const signedness = if (ty.isAbiInt()) ty.intInfo(self.target.*).signedness else .unsigned; + break :result .{ + .eflags = Condition.fromCompareOperator(signedness, if (flipped) op.reverse() else op), }; }; - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -5785,13 +5781,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC try self.loadMemPtrIntoRegister(addr_reg, Type.usize, opt_mcv); - // To get the actual address of the value we want to modify we have to go through the GOT - try self.asmRegisterMemory( - .mov, - addr_reg, - Memory.sib(.qword, .{ .base = addr_reg }), - ); - const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); try self.asmMemoryImmediate(.cmp, Memory.sib( Memory.PtrSize.fromSize(some_abi_size), @@ -6803,22 +6792,14 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl }, } }, - .memory, .linker_load => { - if (abi_size <= 8) { - const reg = try self.copyToTmpRegister(ty, mcv); - return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); - } - - try self.genInlineMemcpy(.{ .stack_offset = stack_offset }, mcv, .{ .immediate = abi_size }, opts); - }, - .ptr_stack_offset => { - const reg = try self.copyToTmpRegister(ty, mcv); - return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); - }, - .stack_offset => |off| { - if (stack_offset == off) { - // Copy stack variable to itself; nothing to do. - return; + .memory, .linker_load, .stack_offset, .ptr_stack_offset => { + switch (mcv) { + else => unreachable, + .memory, .linker_load, .ptr_stack_offset => {}, + .stack_offset => |src_off| if (stack_offset == src_off) { + // Copy stack variable to itself; nothing to do. + return; + }, } if (abi_size <= 8) { @@ -7096,33 +7077,30 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void try self.asmRegisterRegister(.mov, registerAlias(reg, abi_size), registerAlias(src_reg, abi_size)); }, - .linker_load => { - switch (ty.zigTypeTag()) { - .Float => { - const base_reg = try self.register_manager.allocReg(null, gp); - try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv); + .memory, .linker_load => switch (ty.zigTypeTag()) { + .Float => { + const base_reg = try self.register_manager.allocReg(null, gp); + try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv); - if (intrinsicsAllowed(self.target.*, ty)) { - const tag: Mir.Inst.Tag = switch (ty.tag()) { + if (intrinsicsAllowed(self.target.*, ty)) { + return self.asmRegisterMemory( + switch (ty.tag()) { .f32 => .movss, .f64 => .movsd, - else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}), - }; - const ptr_size: Memory.PtrSize = switch (ty.tag()) { - .f32 => .dword, - .f64 => .qword, - else => unreachable, - }; - return self.asmRegisterMemory( - tag, - reg.to128(), - Memory.sib(ptr_size, .{ .base = base_reg.to64() }), - ); - } + else => return self.fail("TODO genSetReg from memory for {}", .{ + ty.fmt(self.bin_file.options.module.?), + }), + }, + reg.to128(), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg.to64() }), + ); + } - return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); - }, - else => { + return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); + }, + else => switch (mcv) { + else => unreachable, + .linker_load => { try self.loadMemPtrIntoRegister(reg, Type.usize, mcv); try self.asmRegisterMemory( .mov, @@ -7130,35 +7108,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), ); }, - } - }, - .memory => |x| switch (ty.zigTypeTag()) { - .Float => { - const base_reg = try self.register_manager.allocReg(null, gp); - try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv); - - if (intrinsicsAllowed(self.target.*, ty)) { - const tag: Mir.Inst.Tag = switch (ty.tag()) { - .f32 => .movss, - .f64 => .movsd, - else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}), - }; - const ptr_size: Memory.PtrSize = switch (ty.tag()) { - .f32 => .dword, - .f64 => .qword, - else => unreachable, - }; - return self.asmRegisterMemory( - tag, - reg.to128(), - Memory.sib(ptr_size, .{ .base = base_reg.to64() }), - ); - } - - return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); - }, - else => { - if (x <= math.maxInt(i32)) { + .memory => |x| if (x <= math.maxInt(i32)) { try self.asmRegisterMemory( .mov, registerAlias(reg, abi_size), @@ -7185,7 +7135,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), ); } - } + }, }, }, .stack_offset => |off| { @@ -7226,15 +7176,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .{ty.fmtDebug()}, ), }; - const ptr_size: Memory.PtrSize = switch (ty.tag()) { - .f32 => .dword, - .f64 => .qword, - else => unreachable, - }; - return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{ - .base = .rbp, - .disp = -off, - })); + return self.asmRegisterMemory(tag, reg.to128(), Memory.sib( + Memory.PtrSize.fromSize(abi_size), + .{ .base = .rbp, .disp = -off }, + )); } return self.fail("TODO genSetReg from stack offset for float with no intrinsics", .{}); }, diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index b2a6b31749..38e4a7e717 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -100,6 +100,16 @@ pub const Condition = enum(u5) { }; } + pub fn fromCompareOperator( + signedness: std.builtin.Signedness, + op: std.math.CompareOperator, + ) Condition { + return switch (signedness) { + .signed => fromCompareOperatorSigned(op), + .unsigned => fromCompareOperatorUnsigned(op), + }; + } + /// Returns the condition which is true iff the given condition is false pub fn negate(cond: Condition) Condition { return switch (cond) { diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 9d626dad66..1887f0a180 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -271,7 +271,6 @@ fn sliceExpects4(slice: []align(4) u32) void { test "return error union with 128-bit integer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -477,7 +476,6 @@ const DefaultAligned = struct { test "read 128-bit field from default aligned struct in stack memory" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -494,7 +492,6 @@ var default_aligned_global = DefaultAligned{ }; test "read 128-bit field from default aligned struct in global memory" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 5a7bb0e8e2..d3cd6918f5 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -39,7 +39,6 @@ test "truncate to non-power-of-two integers" { test "truncate to non-power-of-two integers from 128-bit" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -345,7 +344,6 @@ fn copy(src: *const u64, dst: *u64) void { test "call result of if else expression" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO try expect(mem.eql(u8, f2(true), "a")); @@ -663,7 +661,6 @@ test "multiline string literal is null terminated" { test "string escapes" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO try expectEqualStrings("\"", "\x22"); @@ -682,8 +679,6 @@ test "explicit cast optional pointers" { } test "pointer comparison" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - const a = @as([]const u8, "a"); const b = &a; try expect(ptrEql(b, b)); @@ -695,7 +690,6 @@ fn ptrEql(a: *const []const u8, b: *const []const u8) bool { test "string concatenation" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const a = "OK" ++ " IT " ++ "WORKED"; @@ -916,7 +910,6 @@ test "vector initialized with array init syntax has proper type" { } test "weird array and tuple initializations" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -1060,7 +1053,6 @@ test "inline call of function with a switch inside the return statement" { test "namespace lookup ignores decl causing the lookup" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 8ac87bb9c0..ecb4ddf678 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -20,7 +20,6 @@ test "@bitCast iX -> uX (32, 64)" { test "@bitCast iX -> uX (8, 16, 128)" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/6905.zig b/test/behavior/bugs/6905.zig index f274c81a63..4f308ede22 100644 --- a/test/behavior/bugs/6905.zig +++ b/test/behavior/bugs/6905.zig @@ -3,7 +3,6 @@ const builtin = @import("builtin"); test "sentinel-terminated 0-length slices" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/builtin_functions_returning_void_or_noreturn.zig b/test/behavior/builtin_functions_returning_void_or_noreturn.zig index 072f5576cc..3caf01542c 100644 --- a/test/behavior/builtin_functions_returning_void_or_noreturn.zig +++ b/test/behavior/builtin_functions_returning_void_or_noreturn.zig @@ -8,7 +8,6 @@ var x: u8 = 1; test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 9ba91c64f3..470b17e0b6 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1178,7 +1178,6 @@ fn castToOptionalSlice() ?[]const u8 { test "cast u128 to f128 and back" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/cast_int.zig b/test/behavior/cast_int.zig index 89b129f0db..fef31c1822 100644 --- a/test/behavior/cast_int.zig +++ b/test/behavior/cast_int.zig @@ -5,7 +5,6 @@ const maxInt = std.math.maxInt; test "@intCast i32 to u7" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 6460c5089c..b1f77f33a8 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -561,7 +561,6 @@ test "error union comptime caching" { } test "@errorName" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -798,7 +797,6 @@ test "error union of noreturn used with catch" { } test "alignment of wrapping an error union payload" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 52b30f9aed..7fa8066505 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -458,7 +458,6 @@ test "binary math operator in partially inlined function" { test "comptime shl" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/int128.zig b/test/behavior/int128.zig index 85598b3585..166b03809b 100644 --- a/test/behavior/int128.zig +++ b/test/behavior/int128.zig @@ -5,7 +5,6 @@ const minInt = std.math.minInt; const builtin = @import("builtin"); test "uint128" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -24,7 +23,6 @@ test "uint128" { } test "undefined 128 bit int" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -87,7 +85,6 @@ test "truncate int128" { test "shift int128" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/int_div.zig b/test/behavior/int_div.zig index 954f6be220..c917dde1c9 100644 --- a/test/behavior/int_div.zig +++ b/test/behavior/int_div.zig @@ -97,7 +97,6 @@ test "large integer division" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; { var numerator: u256 = 99999999999999999997315645440; diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 1716ccd9c4..8dcd252125 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -412,7 +412,6 @@ test "orelse on C pointer" { } test "alignment of wrapping an optional payload" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 0532212559..626a1a7eb6 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -160,7 +160,6 @@ test "implicit casting between C pointer and optional non-C pointer" { } test "implicit cast error unions with non-optional to optional pointer" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 15a9861d0f..37b24a1ed5 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -800,7 +800,6 @@ test "fn with C calling convention returns struct by value" { } test "non-packed struct with u128 entry in union" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/typename.zig b/test/behavior/typename.zig index e8327a1981..fa2446dc6e 100644 --- a/test/behavior/typename.zig +++ b/test/behavior/typename.zig @@ -12,7 +12,6 @@ const expectStringStartsWith = std.testing.expectStringStartsWith; // failures. test "anon fn param" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -38,7 +37,6 @@ test "anon fn param" { } test "anon field init" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -87,7 +85,6 @@ test "basic" { } test "top level decl" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -137,7 +134,6 @@ const B = struct { }; test "fn param" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -208,7 +204,6 @@ pub fn expectEqualStringsIgnoreDigits(expected: []const u8, actual: []const u8) } test "local variable" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -236,7 +231,6 @@ test "comptime parameters not converted to anytype in function type" { } test "anon name strategy used in sub expression" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/cases/aarch64-macos/hello_world_with_updates.0.zig b/test/cases/aarch64-macos/hello_world_with_updates.0.zig index a3bcb8527f..90aa14ab65 100644 --- a/test/cases/aarch64-macos/hello_world_with_updates.0.zig +++ b/test/cases/aarch64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=aarch64-macos // -// :108:9: error: root struct of file 'tmp' has no member named 'main' +// :110:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-linux/hello_world_with_updates.0.zig b/test/cases/x86_64-linux/hello_world_with_updates.0.zig index 70cec703da..16c280774e 100644 --- a/test/cases/x86_64-linux/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-linux/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-linux // -// :108:9: error: root struct of file 'tmp' has no member named 'main' +// :110:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-macos/hello_world_with_updates.0.zig b/test/cases/x86_64-macos/hello_world_with_updates.0.zig index 3b8758a0e5..d91bd9dc91 100644 --- a/test/cases/x86_64-macos/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-macos // -// :108:9: error: root struct of file 'tmp' has no member named 'main' +// :110:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-windows/hello_world_with_updates.0.zig b/test/cases/x86_64-windows/hello_world_with_updates.0.zig index e9a55f6061..0c4d2c2bc2 100644 --- a/test/cases/x86_64-windows/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-windows/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-windows // -// :129:9: error: root struct of file 'tmp' has no member named 'main' +// :131:9: error: root struct of file 'tmp' has no member named 'main' From b80cdde4f079181ad4b3ba937771fcfd1de94bdb Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 00:45:21 -0400 Subject: [PATCH 184/216] x86_64: implement struct_field_val for large packed structs --- src/arch/x86_64/CodeGen.zig | 154 ++++++++++++++++++++++++------------ test/behavior/bugs/9584.zig | 1 - 2 files changed, 105 insertions(+), 50 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 578c32ace3..2d613dedf0 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3818,45 +3818,95 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; - const operand = extra.struct_operand; - const index = extra.field_index; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const operand = extra.struct_operand; + const index = extra.field_index; - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ extra.struct_operand, .none, .none }); - } + const container_ty = self.air.typeOf(operand); + const field_ty = container_ty.structFieldType(index); + if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; - const mcv = try self.resolveInst(operand); - const container_ty = self.air.typeOf(operand); - const field_ty = container_ty.structFieldType(index); - const field_bit_offset = switch (container_ty.containerLayout()) { - .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*) * 8), - .Packed => if (container_ty.castTag(.@"struct")) |struct_obj| - struct_obj.data.packedFieldBitOffset(self.target.*, index) - else - 0, - }; + const src_mcv = try self.resolveInst(operand); + const field_off = switch (container_ty.containerLayout()) { + .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*) * 8), + .Packed => if (container_ty.castTag(.@"struct")) |struct_obj| + struct_obj.data.packedFieldBitOffset(self.target.*, index) + else + 0, + }; - const result: MCValue = result: { - switch (mcv) { - .stack_offset => |off| { - const byte_offset = std.math.divExact(u32, field_bit_offset, 8) catch - return self.fail("TODO implement struct_field_val for a packed struct", .{}); - break :result MCValue{ .stack_offset = off - @intCast(i32, byte_offset) }; + switch (src_mcv) { + .stack_offset => |src_off| { + const field_abi_size = @intCast(u32, field_ty.abiSize(self.target.*)); + const limb_abi_size = @min(field_abi_size, 8); + const limb_abi_bits = limb_abi_size * 8; + const field_byte_off = @intCast(i32, field_off / limb_abi_bits * limb_abi_size); + const field_bit_off = field_off % limb_abi_bits; + + if (field_bit_off == 0) { + const off_mcv = MCValue{ .stack_offset = src_off - field_byte_off }; + if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result off_mcv; + + const dst_mcv = try self.allocRegOrMem(inst, true); + try self.setRegOrMem(field_ty, dst_mcv, off_mcv); + break :result dst_mcv; + } + + if (field_abi_size > 8) { + return self.fail("TODO implement struct_field_val with large packed field", .{}); + } + + const dst_reg = try self.register_manager.allocReg(inst, gp); + const field_extra_bits = self.regExtraBits(field_ty); + const load_abi_size = + if (field_bit_off < field_extra_bits) field_abi_size else field_abi_size * 2; + if (load_abi_size <= 8) { + const load_reg = registerAlias(dst_reg, load_abi_size); + try self.asmRegisterMemory(.mov, load_reg, Memory.sib( + Memory.PtrSize.fromSize(load_abi_size), + .{ .base = .rbp, .disp = field_byte_off - src_off }, + )); + try self.asmRegisterImmediate(.shr, load_reg, Immediate.u(field_bit_off)); + } else { + const tmp_reg = registerAlias( + try self.register_manager.allocReg(null, gp), + field_abi_size, + ); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); + + const dst_alias = registerAlias(dst_reg, field_abi_size); + try self.asmRegisterMemory(.mov, dst_alias, Memory.sib( + Memory.PtrSize.fromSize(field_abi_size), + .{ .base = .rbp, .disp = field_byte_off - src_off }, + )); + try self.asmRegisterMemory(.mov, tmp_reg, Memory.sib( + Memory.PtrSize.fromSize(field_abi_size), + .{ .base = .rbp, .disp = field_byte_off + 1 - src_off }, + )); + try self.asmRegisterRegisterImmediate( + .shrd, + dst_alias, + tmp_reg, + Immediate.u(field_bit_off), + ); + } + + if (field_extra_bits > 0) try self.truncateRegister(field_ty, dst_reg); + break :result .{ .register = dst_reg }; }, .register => |reg| { const reg_lock = self.register_manager.lockRegAssumeUnused(reg); defer self.register_manager.unlockReg(reg_lock); - const dst_mcv: MCValue = blk: { - if (self.reuseOperand(inst, operand, 0, mcv)) { - break :blk mcv; - } else { - const dst_mcv = try self.copyToRegisterWithInstTracking(inst, Type.usize, .{ - .register = reg.to64(), - }); - break :blk dst_mcv; - } - }; + const dst_mcv = if (self.reuseOperand(inst, operand, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking( + inst, + Type.usize, + .{ .register = reg.to64() }, + ); const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { .register => |a_reg| self.register_manager.lockReg(a_reg), else => null, @@ -3864,7 +3914,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); // Shift by struct_field_offset. - try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv, .{ .immediate = field_bit_offset }); + try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv, .{ .immediate = field_off }); // Mask to field_bit_size bits const field_bit_size = field_ty.bitSize(self.target.*); @@ -3883,31 +3933,34 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { registerAlias(dst_mcv.register, field_byte_size), ); } - break :result dst_mcv; }, .register_overflow => |ro| { switch (index) { - 0 => { - // Get wrapped value for overflow operation. - break :result MCValue{ .register = ro.reg }; - }, - 1 => { - // Get overflow bit. - const reg_lock = self.register_manager.lockRegAssumeUnused(ro.reg); - defer self.register_manager.unlockReg(reg_lock); - + // Get wrapped value for overflow operation. + 0 => if (self.liveness.operandDies(inst, 0)) { + self.eflags_inst = null; + break :result .{ .register = ro.reg }; + } else break :result try self.copyToRegisterWithInstTracking( + inst, + Type.usize, + .{ .register = ro.reg }, + ), + // Get overflow bit. + 1 => if (self.liveness.operandDies(inst, 0)) { + self.eflags_inst = inst; + break :result .{ .eflags = ro.eflags }; + } else { const dst_reg = try self.register_manager.allocReg(inst, gp); try self.asmSetccRegister(dst_reg.to8(), ro.eflags); - break :result MCValue{ .register = dst_reg.to8() }; + break :result .{ .register = dst_reg.to8() }; }, else => unreachable, } }, - else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}), + else => return self.fail("TODO implement codegen struct_field_val for {}", .{src_mcv}), } }; - return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); } @@ -7908,13 +7961,16 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { else => null, }; defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); - const elem_reg = try self.copyToTmpRegister(elem_ty, elem_mcv); + const elem_reg = registerAlias( + try self.copyToTmpRegister(elem_ty, elem_mcv), + elem_abi_size, + ); const elem_extra_bits = self.regExtraBits(elem_ty); if (elem_bit_off < elem_extra_bits) { - try self.truncateRegister(elem_ty, registerAlias(elem_reg, elem_abi_size)); + try self.truncateRegister(elem_ty, elem_reg); } if (elem_bit_off > 0) try self.genShiftBinOpMir( - .sal, + .shl, elem_ty, .{ .register = elem_reg }, .{ .immediate = elem_bit_off }, @@ -7931,7 +7987,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size)); } try self.genShiftBinOpMir( - .sar, + .shr, elem_ty, .{ .register = reg }, .{ .immediate = elem_abi_bits - elem_bit_off }, diff --git a/test/behavior/bugs/9584.zig b/test/behavior/bugs/9584.zig index fe3dedcd30..307f1689bf 100644 --- a/test/behavior/bugs/9584.zig +++ b/test/behavior/bugs/9584.zig @@ -47,7 +47,6 @@ test { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var flags = A{ .a = false, From c713c863896d4ef6b4fd0817e8db59f5992b2303 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 04:34:14 -0400 Subject: [PATCH 185/216] x86_64: implement wide multiply --- src/arch/x86_64/CodeGen.zig | 357 +++++++++++++++++++++--------------- 1 file changed, 210 insertions(+), 147 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 2d613dedf0..112c9ac106 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1625,24 +1625,68 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } +fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { + const air_tag = self.air.instructions.items(.tag); + const air_data = self.air.instructions.items(.data); + + const dst_ty = self.air.typeOf(dst_air); + const dst_info = dst_ty.intInfo(self.target.*); + if (Air.refToIndex(dst_air)) |inst| { + switch (air_tag[inst]) { + .constant => { + const src_val = self.air.values[air_data[inst].ty_pl.payload]; + var space: Value.BigIntSpace = undefined; + const src_int = src_val.toBigInt(&space, self.target.*); + return @intCast(u16, src_int.bitCountTwosComp()) + + @boolToInt(src_int.positive and dst_info.signedness == .signed); + }, + .intcast => { + const src_ty = self.air.typeOf(air_data[inst].ty_op.operand); + const src_info = src_ty.intInfo(self.target.*); + return @min(switch (src_info.signedness) { + .signed => switch (dst_info.signedness) { + .signed => src_info.bits, + .unsigned => src_info.bits - 1, + }, + .unsigned => switch (dst_info.signedness) { + .signed => src_info.bits + 1, + .unsigned => src_info.bits, + }, + }, dst_info.bits); + }, + else => {}, + } + } + return dst_info.bits; +} + fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result = result: { - if (self.liveness.isUnused(inst)) break :result .dead; - + const result = if (self.liveness.isUnused(inst)) .dead else result: { const tag = self.air.instructions.items(.tag)[inst]; - const ty = self.air.typeOfIndex(inst); - - if (ty.zigTypeTag() == .Float) { + const dst_ty = self.air.typeOfIndex(inst); + if (dst_ty.zigTypeTag() == .Float) break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); - } + + const dst_info = dst_ty.intInfo(self.target.*); + var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { + .signed => .int_signed, + .unsigned => .int_unsigned, + } }, .data = switch (tag) { + else => unreachable, + .mul, .mulwrap => std.math.max3( + self.activeIntBits(bin_op.lhs), + self.activeIntBits(bin_op.rhs), + dst_info.bits / 2, + ), + .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits, + } }; + const src_ty = Type.initPayload(&src_pl.base); try self.spillRegisters(&.{ .rax, .rdx }); - const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - - break :result try self.genMulDivBinOp(tag, inst, ty, lhs, rhs); + break :result try self.genMulDivBinOp(tag, inst, dst_ty, src_ty, lhs, rhs); }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -1795,7 +1839,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { break :cc .c; }; - const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, lhs_mcv, rhs_mcv); + const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv); const abi_size = @intCast(u32, @max(ty.abiSize(self.target.*), 2)); try self.asmCmovccRegisterRegister( registerAlias(dst_mcv.register, abi_size), @@ -1809,9 +1853,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; - const tag = self.air.instructions.items(.tag)[inst]; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; - const result = if (self.liveness.isUnused(inst)) .dead else result: { + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const tag = self.air.instructions.items(.tag)[inst]; const ty = self.air.typeOf(bin_op.lhs); const abi_size = ty.abiSize(self.target.*); switch (ty.zigTypeTag()) { @@ -1842,21 +1886,17 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const int_info = ty.intInfo(self.target.*); - if (math.isPowerOfTwo(int_info.bits) and int_info.bits >= 8) { + if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { self.eflags_inst = inst; - - const cc: Condition = switch (int_info.signedness) { - .unsigned => .c, - .signed => .o, - }; - break :result MCValue{ .register_overflow = .{ + break :result .{ .register_overflow = .{ .reg = partial.register, - .eflags = cc, + .eflags = switch (int_info.signedness) { + .unsigned => .c, + .signed => .o, + }, } }; } - self.eflags_inst = null; - const tuple_ty = self.air.typeOfIndex(inst); const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*)); const tuple_align = tuple_ty.abiAlignment(self.target.*); @@ -1865,12 +1905,11 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { try self.genSetStackTruncatedOverflowCompare(ty, stack_offset, overflow_bit_offset, partial.register); - break :result MCValue{ .stack_offset = stack_offset }; + break :result .{ .stack_offset = stack_offset }; }, else => unreachable, } }; - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -1931,48 +1970,56 @@ fn genSetStackTruncatedOverflowCompare( fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; - - if (self.liveness.isUnused(inst)) { - return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); - } - - const ty = self.air.typeOf(bin_op.lhs); - const abi_size = ty.abiSize(self.target.*); - const result: MCValue = result: { - switch (ty.zigTypeTag()) { + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const dst_ty = self.air.typeOf(bin_op.lhs); + switch (dst_ty.zigTypeTag()) { .Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}), .Int => { - if (abi_size > 8) { - return self.fail("TODO implement mul_with_overflow for Ints larger than 64bits", .{}); - } + try self.spillEflagsIfOccupied(); - const int_info = ty.intInfo(self.target.*); - - if (math.isPowerOfTwo(int_info.bits) and int_info.bits >= 8) { - try self.spillEflagsIfOccupied(); - self.eflags_inst = inst; + const dst_info = dst_ty.intInfo(self.target.*); + if (dst_info.bits >= 8 and math.isPowerOfTwo(dst_info.bits)) { + var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { + .signed => .int_signed, + .unsigned => .int_unsigned, + } }, .data = std.math.max3( + self.activeIntBits(bin_op.lhs), + self.activeIntBits(bin_op.rhs), + dst_info.bits / 2, + ) }; + const src_ty = Type.initPayload(&src_pl.base); try self.spillRegisters(&.{ .rax, .rdx }); - const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - const partial = try self.genMulDivBinOp(.mul, null, ty, lhs, rhs); - const cc: Condition = switch (int_info.signedness) { + const partial = try self.genMulDivBinOp(.mul, null, dst_ty, src_ty, lhs, rhs); + const cc: Condition = switch (dst_info.signedness) { .unsigned => .c, .signed => .o, }; - break :result MCValue{ .register_overflow = .{ - .reg = partial.register, - .eflags = cc, - } }; + switch (partial) { + .register => |reg| { + self.eflags_inst = inst; + break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; + }, + else => {}, + } + + const dst_abi_size = @intCast(i32, dst_ty.abiSize(self.target.*)); + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.genSetStack( + Type.u1, + dst_mcv.stack_offset - dst_abi_size, + .{ .eflags = cc }, + .{}, + ); + try self.genSetStack(dst_ty, dst_mcv.stack_offset, partial, .{}); + break :result dst_mcv; } - try self.spillEflagsIfOccupied(); - self.eflags_inst = null; - const dst_reg: Register = dst_reg: { - switch (int_info.signedness) { + switch (dst_info.signedness) { .signed => { const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); @@ -1985,14 +2032,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const dst_reg: Register = blk: { if (lhs.isRegister()) break :blk lhs.register; - break :blk try self.copyToTmpRegister(ty, lhs); + break :blk try self.copyToTmpRegister(dst_ty, lhs); }; const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg); defer self.register_manager.unlockReg(dst_reg_lock); const rhs_mcv: MCValue = blk: { if (rhs.isRegister() or rhs.isMemory()) break :blk rhs; - break :blk MCValue{ .register = try self.copyToTmpRegister(ty, rhs) }; + break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, rhs) }; }; const rhs_mcv_lock: ?RegisterLock = switch (rhs_mcv) { .register => |reg| self.register_manager.lockReg(reg), @@ -2010,7 +2057,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - const dst_mcv = try self.genMulDivBinOp(.mul, null, ty, lhs, rhs); + const dst_mcv = try self.genMulDivBinOp(.mul, null, dst_ty, dst_ty, lhs, rhs); break :dst_reg dst_mcv.register; }, } @@ -2022,14 +2069,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const overflow_bit_offset = @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)); const stack_offset = @intCast(i32, try self.allocMem(inst, tuple_size, tuple_align)); - try self.genSetStackTruncatedOverflowCompare(ty, stack_offset, overflow_bit_offset, dst_reg); + try self.genSetStackTruncatedOverflowCompare(dst_ty, stack_offset, overflow_bit_offset, dst_reg); - break :result MCValue{ .stack_offset = stack_offset }; + break :result .{ .stack_offset = stack_offset }; }, else => unreachable, } }; - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -2040,7 +2086,6 @@ fn genIntMulDivOpMir( self: *Self, tag: Mir.Inst.Tag, ty: Type, - signedness: std.builtin.Signedness, lhs: MCValue, rhs: MCValue, ) !void { @@ -2057,26 +2102,23 @@ fn genIntMulDivOpMir( try self.genSetReg(ty, .rax, lhs); } - switch (signedness) { - .signed => try self.asmOpOnly(.cqo), - .unsigned => try self.asmRegisterRegister(.xor, .rdx, .rdx), + switch (tag) { + else => unreachable, + .mul, .imul => {}, + .div => try self.asmRegisterRegister(.xor, .edx, .edx), + .idiv => try self.asmOpOnly(.cqo), } - const factor = switch (rhs) { - .register => rhs, - .stack_offset => rhs, - else => blk: { - const reg = try self.copyToTmpRegister(ty, rhs); - break :blk MCValue{ .register = reg }; - }, + const factor: MCValue = switch (rhs) { + .register, .stack_offset => rhs, + else => .{ .register = try self.copyToTmpRegister(ty, rhs) }, }; - switch (factor) { .register => |reg| try self.asmRegister(tag, reg), - .stack_offset => |off| try self.asmMemory(tag, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = .rbp, - .disp = -off, - })), + .stack_offset => |off| try self.asmMemory(tag, Memory.sib( + Memory.PtrSize.fromSize(abi_size), + .{ .base = .rbp, .disp = -off }, + )), else => unreachable, } } @@ -2102,7 +2144,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa try self.genIntMulDivOpMir(switch (signedness) { .signed => .idiv, .unsigned => .div, - }, Type.isize, signedness, .{ .register = dividend }, .{ .register = divisor }); + }, Type.isize, .{ .register = dividend }, .{ .register = divisor }); try self.asmRegisterRegister(.xor, divisor.to64(), dividend.to64()); try self.asmRegisterImmediate(.sar, divisor.to64(), Immediate.u(63)); @@ -3938,14 +3980,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { .register_overflow => |ro| { switch (index) { // Get wrapped value for overflow operation. - 0 => if (self.liveness.operandDies(inst, 0)) { - self.eflags_inst = null; - break :result .{ .register = ro.reg }; - } else break :result try self.copyToRegisterWithInstTracking( - inst, - Type.usize, - .{ .register = ro.reg }, - ), + 0 => break :result if (self.liveness.operandDies(inst, 0)) + .{ .register = ro.reg } + else + try self.copyToRegisterWithInstTracking( + inst, + Type.usize, + .{ .register = ro.reg }, + ), // Get overflow bit. 1 => if (self.liveness.operandDies(inst, 0)) { self.eflags_inst = inst; @@ -4318,20 +4360,26 @@ fn genMulDivBinOp( self: *Self, tag: Air.Inst.Tag, maybe_inst: ?Air.Inst.Index, - ty: Type, + dst_ty: Type, + src_ty: Type, lhs: MCValue, rhs: MCValue, ) !MCValue { - if (ty.zigTypeTag() == .Vector or ty.zigTypeTag() == .Float) { - return self.fail("TODO implement genMulDivBinOp for {}", .{ty.fmtDebug()}); - } - const abi_size = @intCast(u32, ty.abiSize(self.target.*)); - if (abi_size > 8) { - return self.fail("TODO implement genMulDivBinOp for {}", .{ty.fmtDebug()}); - } - if (tag == .div_float) { - return self.fail("TODO implement genMulDivBinOp for div_float", .{}); + if (dst_ty.zigTypeTag() == .Vector or dst_ty.zigTypeTag() == .Float) { + return self.fail("TODO implement genMulDivBinOp for {}", .{dst_ty.fmtDebug()}); } + const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); + const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); + if (switch (tag) { + else => unreachable, + .mul, .mulwrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2, + .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_abi_size != src_abi_size, + } or src_abi_size > 8) return self.fail("TODO implement genMulDivBinOp from {} to {}", .{ + src_ty.fmt(self.bin_file.options.module.?), + dst_ty.fmt(self.bin_file.options.module.?), + }); + const ty = if (dst_abi_size <= 8) dst_ty else src_ty; + const abi_size = if (dst_abi_size <= 8) dst_abi_size else src_abi_size; assert(self.register_manager.isRegFree(.rax)); assert(self.register_manager.isRegFree(.rdx)); @@ -4339,9 +4387,7 @@ fn genMulDivBinOp( const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx }); defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); - const int_info = ty.intInfo(self.target.*); - const signedness = int_info.signedness; - + const signedness = ty.intInfo(self.target.*).signedness; switch (tag) { .mul, .mulwrap, @@ -4349,11 +4395,12 @@ fn genMulDivBinOp( .div_trunc, .div_exact, => { - const track_inst_rax: ?Air.Inst.Index = switch (tag) { - .mul, .mulwrap, .div_exact, .div_trunc => maybe_inst, + const track_inst_rax = switch (tag) { + .mul, .mulwrap => if (dst_abi_size <= 8) maybe_inst else null, + .div_exact, .div_trunc => maybe_inst, else => null, }; - const track_inst_rdx: ?Air.Inst.Index = switch (tag) { + const track_inst_rdx = switch (tag) { .rem => maybe_inst, else => null, }; @@ -4373,13 +4420,24 @@ fn genMulDivBinOp( }, }; - try self.genIntMulDivOpMir(mir_tag, ty, .signed, lhs, rhs); + try self.genIntMulDivOpMir(mir_tag, ty, lhs, rhs); - return .{ .register = registerAlias(switch (tag) { + if (dst_abi_size <= 8) return .{ .register = registerAlias(switch (tag) { .mul, .mulwrap, .div_trunc, .div_exact => .rax, .rem => .rdx, else => unreachable, - }, abi_size) }; + }, dst_abi_size) }; + + const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); + try self.asmMemoryRegister(.mov, Memory.sib(.qword, .{ + .base = .rbp, + .disp = 0 - dst_mcv.stack_offset, + }), .rax); + try self.asmMemoryRegister(.mov, Memory.sib(.qword, .{ + .base = .rbp, + .disp = 8 - dst_mcv.stack_offset, + }), .rdx); + return dst_mcv; }, .mod => { @@ -4402,7 +4460,7 @@ fn genMulDivBinOp( return result; }, .unsigned => { - try self.genIntMulDivOpMir(.div, ty, .unsigned, lhs, rhs); + try self.genIntMulDivOpMir(.div, ty, lhs, rhs); return .{ .register = registerAlias(.rdx, abi_size) }; }, } @@ -4441,18 +4499,13 @@ fn genMulDivBinOp( }; defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); - const result: MCValue = result: { - switch (signedness) { - .signed => break :result try self.genInlineIntDivFloor(ty, lhs, actual_rhs), - .unsigned => { - try self.genIntMulDivOpMir(.div, ty, .unsigned, lhs, actual_rhs); - break :result MCValue{ - .register = registerAlias(.rax, @intCast(u32, ty.abiSize(self.target.*))), - }; - }, - } - }; - return result; + switch (signedness) { + .signed => return try self.genInlineIntDivFloor(ty, lhs, actual_rhs), + .unsigned => { + try self.genIntMulDivOpMir(.div, ty, lhs, actual_rhs); + return .{ .register = registerAlias(.rax, abi_size) }; + }, + } }, else => unreachable, @@ -6718,6 +6771,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE } fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: InlineMemcpyOpts) InnerError!void { + const base_reg = opts.dest_stack_base orelse .rbp; const abi_size = @intCast(u32, ty.abiSize(self.target.*)); switch (mcv) { .dead => unreachable, @@ -6733,12 +6787,17 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl 4 => 0xaaaaaaaa, else => unreachable, }; - return self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ - .base = opts.dest_stack_base orelse .rbp, - .disp = -stack_offset, - }), Immediate.u(value)); + return self.asmMemoryImmediate(.mov, Memory.sib( + Memory.PtrSize.fromSize(abi_size), + .{ .base = base_reg, .disp = -stack_offset }, + ), Immediate.u(value)); }, - 8 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaaaaaaaaaa }, opts), + 8 => return self.genSetStack( + ty, + stack_offset, + .{ .immediate = 0xaaaaaaaaaaaaaaaa }, + opts, + ), else => |x| return self.genInlineMemset( .{ .stack_offset = stack_offset }, .{ .immediate = 0xaa }, @@ -6766,12 +6825,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl .{}, ); }, - .eflags => { - const reg = try self.copyToTmpRegister(ty, mcv); - return self.genSetStack(ty, stack_offset, .{ .register = reg }, opts); - }, - .immediate => |x_big| { - const base_reg = opts.dest_stack_base orelse .rbp; + .eflags => |cc| try self.asmSetccMemory( + Memory.sib(.byte, .{ .base = base_reg, .disp = -stack_offset }), + cc, + ), + .immediate => |imm| { // TODO switch (abi_size) { 0 => { @@ -6779,13 +6837,13 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl try self.asmMemoryImmediate(.mov, Memory.sib(.byte, .{ .base = base_reg, .disp = -stack_offset, - }), Immediate.u(@truncate(u8, x_big))); + }), Immediate.u(@truncate(u8, imm))); }, 1, 2, 4 => { const immediate = if (ty.isSignedInt()) - Immediate.s(@truncate(i32, @bitCast(i64, x_big))) + Immediate.s(@truncate(i32, @bitCast(i64, imm))) else - Immediate.u(@intCast(u32, x_big)); + Immediate.u(@intCast(u32, imm)); try self.asmMemoryImmediate(.mov, Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg, .disp = -stack_offset, @@ -6795,27 +6853,32 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl else => { // 64 bit write to memory would take two mov's anyways so we // insted just use two 32 bit writes to avoid register allocation - var offset: i32 = 0; - while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate( - .mov, - Memory.sib(.dword, .{ .base = base_reg, .disp = offset - stack_offset }), - if (ty.isSignedInt()) - Immediate.s(@truncate( - i32, - @bitCast(i64, x_big) >> (math.cast(u6, offset * 8) orelse 63), - )) - else - Immediate.u(@truncate( - u32, - if (math.cast(u6, offset * 8)) |shift| x_big >> shift else 0, - )), - ); + if (std.math.cast(i32, @bitCast(i64, imm))) |small| { + try self.asmMemoryImmediate(.mov, Memory.sib( + Memory.PtrSize.fromSize(abi_size), + .{ .base = base_reg, .disp = -stack_offset }, + ), Immediate.s(small)); + } else { + var offset: i32 = 0; + while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate( + .mov, + Memory.sib(.dword, .{ .base = base_reg, .disp = offset - stack_offset }), + if (ty.isSignedInt()) + Immediate.s(@truncate( + i32, + @bitCast(i64, imm) >> (math.cast(u6, offset * 8) orelse 63), + )) + else + Immediate.u(@truncate( + u32, + if (math.cast(u6, offset * 8)) |shift| imm >> shift else 0, + )), + ); + } }, } }, .register => |reg| { - const base_reg = opts.dest_stack_base orelse .rbp; - switch (ty.zigTypeTag()) { .Float => { if (intrinsicsAllowed(self.target.*, ty)) { From 0e289cc8269c9c18358b511564718972808d2efe Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 05:15:26 -0400 Subject: [PATCH 186/216] x86_64: implement large add/sub with overflow --- src/arch/x86_64/CodeGen.zig | 36 +++++++++++++++++++++++------------- test/behavior/eval.zig | 1 + test/behavior/int128.zig | 1 - test/behavior/math.zig | 2 ++ 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 112c9ac106..436fe4ea56 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1857,18 +1857,15 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const tag = self.air.instructions.items(.tag)[inst]; const ty = self.air.typeOf(bin_op.lhs); - const abi_size = ty.abiSize(self.target.*); switch (ty.zigTypeTag()) { .Vector => return self.fail("TODO implement add/sub/shl with overflow for Vector type", .{}), .Int => { - if (abi_size > 8) { - return self.fail("TODO implement add/sub/shl with overflow for Ints larger than 64bits", .{}); - } - try self.spillEflagsIfOccupied(); if (tag == .shl_with_overflow) { try self.spillRegisters(&.{.rcx}); + // cf/of don't work for shifts other than 1 + return self.fail("TODO implement shl_with_overflow for x86_64", .{}); } const partial: MCValue = switch (tag) { @@ -1885,16 +1882,29 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { }; const int_info = ty.intInfo(self.target.*); - if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { - self.eflags_inst = inst; - break :result .{ .register_overflow = .{ - .reg = partial.register, - .eflags = switch (int_info.signedness) { - .unsigned => .c, - .signed => .o, + const cc: Condition = switch (int_info.signedness) { + .unsigned => .c, + .signed => .o, + }; + switch (partial) { + .register => |reg| { + self.eflags_inst = inst; + break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; }, - } }; + else => {}, + } + + const abi_size = @intCast(i32, ty.abiSize(self.target.*)); + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.genSetStack( + Type.u1, + dst_mcv.stack_offset - abi_size, + .{ .eflags = cc }, + .{}, + ); + try self.genSetStack(ty, dst_mcv.stack_offset, partial, .{}); + break :result dst_mcv; } const tuple_ty = self.air.typeOfIndex(inst); diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 7fa8066505..533d6080ae 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -488,6 +488,7 @@ test "comptime bitwise operators" { test "comptime shlWithOverflow" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const ct_shifted = @shlWithOverflow(~@as(u64, 0), 16)[0]; var a = ~@as(u64, 0); diff --git a/test/behavior/int128.zig b/test/behavior/int128.zig index 166b03809b..b21a480a16 100644 --- a/test/behavior/int128.zig +++ b/test/behavior/int128.zig @@ -40,7 +40,6 @@ test "undefined 128 bit int" { } test "int128" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 9e3c2b02fd..acdbb2748e 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1237,6 +1237,8 @@ fn testShlTrunc(x: u16) !void { } test "exact shift left" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + try testShlExact(0b00110101); comptime try testShlExact(0b00110101); } From f4359531b154951f9c242c487249169499f0852d Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 05:47:38 -0400 Subject: [PATCH 187/216] x86_64: implement shl with overflow --- src/arch/x86_64/CodeGen.zig | 133 +++++++++++++++++++++++++----------- test/behavior/eval.zig | 1 - test/behavior/math.zig | 2 - 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 436fe4ea56..c7dfa2c6a9 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -952,10 +952,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .neg, => try self.airUnaryMath(inst), - .add_with_overflow => try self.airAddSubShlWithOverflow(inst), - .sub_with_overflow => try self.airAddSubShlWithOverflow(inst), + .add_with_overflow => try self.airAddSubWithOverflow(inst), + .sub_with_overflow => try self.airAddSubWithOverflow(inst), .mul_with_overflow => try self.airMulWithOverflow(inst), - .shl_with_overflow => try self.airAddSubShlWithOverflow(inst), + .shl_with_overflow => try self.airShlWithOverflow(inst), .div_float, .div_trunc, .div_floor, .div_exact => try self.airMulDivBinOp(inst), @@ -1851,43 +1851,30 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } -fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { +fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const tag = self.air.instructions.items(.tag)[inst]; const ty = self.air.typeOf(bin_op.lhs); switch (ty.zigTypeTag()) { - .Vector => return self.fail("TODO implement add/sub/shl with overflow for Vector type", .{}), + .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}), .Int => { try self.spillEflagsIfOccupied(); - if (tag == .shl_with_overflow) { - try self.spillRegisters(&.{.rcx}); - // cf/of don't work for shifts other than 1 - return self.fail("TODO implement shl_with_overflow for x86_64", .{}); - } - - const partial: MCValue = switch (tag) { + const partial_mcv = switch (tag) { .add_with_overflow => try self.genBinOp(null, .add, bin_op.lhs, bin_op.rhs), .sub_with_overflow => try self.genBinOp(null, .sub, bin_op.lhs, bin_op.rhs), - .shl_with_overflow => blk: { - try self.register_manager.getReg(.rcx, null); - const lhs = try self.resolveInst(bin_op.lhs); - const rhs = try self.resolveInst(bin_op.rhs); - const shift_ty = self.air.typeOf(bin_op.rhs); - break :blk try self.genShiftBinOp(.shl, null, lhs, rhs, ty, shift_ty); - }, else => unreachable, }; - const int_info = ty.intInfo(self.target.*); + const cc: Condition = switch (int_info.signedness) { + .unsigned => .c, + .signed => .o, + }; + if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { - const cc: Condition = switch (int_info.signedness) { - .unsigned => .c, - .signed => .o, - }; - switch (partial) { + switch (partial_mcv) { .register => |reg| { self.eflags_inst = inst; break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; @@ -1903,7 +1890,7 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { .{ .eflags = cc }, .{}, ); - try self.genSetStack(ty, dst_mcv.stack_offset, partial, .{}); + try self.genSetStack(ty, dst_mcv.stack_offset, partial_mcv, .{}); break :result dst_mcv; } @@ -1913,7 +1900,78 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const overflow_bit_offset = @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)); const stack_offset = @intCast(i32, try self.allocMem(inst, tuple_size, tuple_align)); - try self.genSetStackTruncatedOverflowCompare(ty, stack_offset, overflow_bit_offset, partial.register); + try self.genSetStackTruncatedOverflowCompare(ty, stack_offset, overflow_bit_offset, partial_mcv.register, cc); + + break :result .{ .stack_offset = stack_offset }; + }, + else => unreachable, + } + }; + return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); +} + +fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const lhs_ty = self.air.typeOf(bin_op.lhs); + const rhs_ty = self.air.typeOf(bin_op.rhs); + switch (lhs_ty.zigTypeTag()) { + .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}), + .Int => { + try self.spillEflagsIfOccupied(); + + try self.register_manager.getReg(.rcx, null); + const lhs = try self.resolveInst(bin_op.lhs); + const rhs = try self.resolveInst(bin_op.rhs); + + const int_info = lhs_ty.intInfo(self.target.*); + + const partial_mcv = try self.genShiftBinOp(.shl, null, lhs, rhs, lhs_ty, rhs_ty); + const partial_lock = switch (partial_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (partial_lock) |lock| self.register_manager.unlockReg(lock); + + const tmp_mcv = try self.genShiftBinOp(.shr, null, partial_mcv, rhs, lhs_ty, rhs_ty); + const tmp_lock = switch (tmp_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock); + + try self.genBinOpMir(.cmp, lhs_ty, tmp_mcv, lhs); + const cc = Condition.ne; + + if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { + switch (partial_mcv) { + .register => |reg| { + self.eflags_inst = inst; + break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; + }, + else => {}, + } + + const abi_size = @intCast(i32, lhs_ty.abiSize(self.target.*)); + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.genSetStack( + Type.u1, + dst_mcv.stack_offset - abi_size, + .{ .eflags = cc }, + .{}, + ); + try self.genSetStack(lhs_ty, dst_mcv.stack_offset, partial_mcv, .{}); + break :result dst_mcv; + } + + const tuple_ty = self.air.typeOfIndex(inst); + const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*)); + const tuple_align = tuple_ty.abiAlignment(self.target.*); + const overflow_bit_offset = @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)); + const stack_offset = @intCast(i32, try self.allocMem(inst, tuple_size, tuple_align)); + + try self.genSetStackTruncatedOverflowCompare(lhs_ty, stack_offset, overflow_bit_offset, partial_mcv.register, cc); break :result .{ .stack_offset = stack_offset }; }, @@ -1929,6 +1987,7 @@ fn genSetStackTruncatedOverflowCompare( stack_offset: i32, overflow_bit_offset: i32, reg: Register, + cc: Condition, ) !void { const reg_lock = self.register_manager.lockReg(reg); defer if (reg_lock) |lock| self.register_manager.unlockReg(lock); @@ -1946,10 +2005,6 @@ fn genSetStackTruncatedOverflowCompare( }; const overflow_reg = temp_regs[0]; - const cc: Condition = switch (int_info.signedness) { - .signed => .o, - .unsigned => .c, - }; try self.asmSetccRegister(overflow_reg.to8(), cc); const scratch_reg = temp_regs[1]; @@ -1988,6 +2043,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { try self.spillEflagsIfOccupied(); const dst_info = dst_ty.intInfo(self.target.*); + const cc: Condition = switch (dst_info.signedness) { + .unsigned => .c, + .signed => .o, + }; if (dst_info.bits >= 8 and math.isPowerOfTwo(dst_info.bits)) { var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { .signed => .int_signed, @@ -2003,12 +2062,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - const partial = try self.genMulDivBinOp(.mul, null, dst_ty, src_ty, lhs, rhs); - const cc: Condition = switch (dst_info.signedness) { - .unsigned => .c, - .signed => .o, - }; - switch (partial) { + const partial_mcv = try self.genMulDivBinOp(.mul, null, dst_ty, src_ty, lhs, rhs); + switch (partial_mcv) { .register => |reg| { self.eflags_inst = inst; break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; @@ -2024,7 +2079,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { .{ .eflags = cc }, .{}, ); - try self.genSetStack(dst_ty, dst_mcv.stack_offset, partial, .{}); + try self.genSetStack(dst_ty, dst_mcv.stack_offset, partial_mcv, .{}); break :result dst_mcv; } @@ -2079,7 +2134,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { const overflow_bit_offset = @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)); const stack_offset = @intCast(i32, try self.allocMem(inst, tuple_size, tuple_align)); - try self.genSetStackTruncatedOverflowCompare(dst_ty, stack_offset, overflow_bit_offset, dst_reg); + try self.genSetStackTruncatedOverflowCompare(dst_ty, stack_offset, overflow_bit_offset, dst_reg, cc); break :result .{ .stack_offset = stack_offset }; }, diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 533d6080ae..7fa8066505 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -488,7 +488,6 @@ test "comptime bitwise operators" { test "comptime shlWithOverflow" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const ct_shifted = @shlWithOverflow(~@as(u64, 0), 16)[0]; var a = ~@as(u64, 0); diff --git a/test/behavior/math.zig b/test/behavior/math.zig index acdbb2748e..9e3c2b02fd 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1237,8 +1237,6 @@ fn testShlTrunc(x: u16) !void { } test "exact shift left" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - try testShlExact(0b00110101); comptime try testShlExact(0b00110101); } From f4b411314ccf8e852d3febddc8b31ce1f533938b Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 31 Mar 2023 16:23:01 -0400 Subject: [PATCH 188/216] Sema: defer stores to inferred allocs This lets us generate the store with knowledge of the type to be stored. Therefore, we can avoid generating garbage Air with stores through pointers to comptime-only types which backends cannot lower. Closes #13410 Closes #15122 --- src/Sema.zig | 67 +++++++++++++++++++++++------------------ src/codegen/c.zig | 8 +---- src/codegen/llvm.zig | 1 - test/behavior/if.zig | 6 ---- test/behavior/union.zig | 16 ++++++++++ 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index da93a2906a..972efcff72 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3866,8 +3866,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty); const empty_trash_count = trash_block.instructions.items.len; - for (placeholders, 0..) |bitcast_inst, i| { - const sub_ptr_ty = sema.typeOf(Air.indexToRef(bitcast_inst)); + for (peer_inst_list, placeholders) |peer_inst, placeholder_inst| { + const sub_ptr_ty = sema.typeOf(Air.indexToRef(placeholder_inst)); if (mut_final_ptr_ty.eql(sub_ptr_ty, sema.mod)) { // New result location type is the same as the old one; nothing @@ -3875,39 +3875,54 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com continue; } - var bitcast_block = block.makeSubBlock(); - defer bitcast_block.instructions.deinit(gpa); + var replacement_block = block.makeSubBlock(); + defer replacement_block.instructions.deinit(gpa); - trash_block.instructions.shrinkRetainingCapacity(empty_trash_count); - const sub_ptr = try sema.coerceResultPtr(&bitcast_block, src, ptr, dummy_ptr, peer_inst_list[i], &trash_block); + const result = switch (sema.air_instructions.items(.tag)[placeholder_inst]) { + .bitcast => result: { + trash_block.instructions.shrinkRetainingCapacity(empty_trash_count); + const sub_ptr = try sema.coerceResultPtr(&replacement_block, src, ptr, dummy_ptr, peer_inst, &trash_block); + + assert(replacement_block.instructions.items.len > 0); + break :result sub_ptr; + }, + .store => result: { + const bin_op = sema.air_instructions.items(.data)[placeholder_inst].bin_op; + try sema.storePtr2(&replacement_block, src, bin_op.lhs, src, bin_op.rhs, src, .bitcast); + break :result .void_value; + }, + else => unreachable, + }; - assert(bitcast_block.instructions.items.len > 0); // If only one instruction is produced then we can replace the bitcast // placeholder instruction with this instruction; no need for an entire block. - if (bitcast_block.instructions.items.len == 1) { - const only_inst = bitcast_block.instructions.items[0]; - sema.air_instructions.set(bitcast_inst, sema.air_instructions.get(only_inst)); + if (replacement_block.instructions.items.len == 1) { + const only_inst = replacement_block.instructions.items[0]; + sema.air_instructions.set(placeholder_inst, sema.air_instructions.get(only_inst)); continue; } // Here we replace the placeholder bitcast instruction with a block // that does the coerce_result_ptr logic. - _ = try bitcast_block.addBr(bitcast_inst, sub_ptr); - const ty_inst = sema.air_instructions.items(.data)[bitcast_inst].ty_op.ty; + _ = try replacement_block.addBr(placeholder_inst, result); + const ty_inst = if (result == .void_value) + .void_type + else + sema.air_instructions.items(.data)[placeholder_inst].ty_op.ty; try sema.air_extra.ensureUnusedCapacity( gpa, - @typeInfo(Air.Block).Struct.fields.len + bitcast_block.instructions.items.len, + @typeInfo(Air.Block).Struct.fields.len + replacement_block.instructions.items.len, ); - sema.air_instructions.set(bitcast_inst, .{ + sema.air_instructions.set(placeholder_inst, .{ .tag = .block, .data = .{ .ty_pl = .{ .ty = ty_inst, .payload = sema.addExtraAssumeCapacity(Air.Block{ - .body_len = @intCast(u32, bitcast_block.instructions.items.len), + .body_len = @intCast(u32, replacement_block.instructions.items.len), }), } }, }); - sema.air_extra.appendSliceAssumeCapacity(bitcast_block.instructions.items); + sema.air_extra.appendSliceAssumeCapacity(replacement_block.instructions.items); } }, else => unreachable, @@ -4916,7 +4931,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE }, .inferred_alloc => { const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; - return sema.storeToInferredAlloc(block, src, ptr, operand, inferred_alloc); + return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc); }, else => break :blk, } @@ -4945,7 +4960,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi }, .inferred_alloc => { const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; - return sema.storeToInferredAlloc(block, src, ptr, operand, inferred_alloc); + return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc); }, else => unreachable, } @@ -4954,27 +4969,19 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi fn storeToInferredAlloc( sema: *Sema, block: *Block, - src: LazySrcLoc, ptr: Air.Inst.Ref, operand: Air.Inst.Ref, inferred_alloc: *Value.Payload.InferredAlloc, ) CompileError!void { - const operand_ty = sema.typeOf(operand); - // Create a runtime bitcast instruction with exactly the type the pointer wants. - const target = sema.mod.getTarget(); - const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ - .pointee_type = operand_ty, - .@"align" = inferred_alloc.data.alignment, - .@"addrspace" = target_util.defaultAddressSpace(target, .local), - }); - const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr); + // Create a store instruction as a placeholder. This will be replaced by a + // proper store sequence once we know the stored type. + const dummy_store = try block.addBinOp(.store, ptr, operand); // Add the stored instruction to the set we will use to resolve peer types // for the inferred allocation. try inferred_alloc.data.prongs.append(sema.arena, .{ .stored_inst = operand, - .placeholder = Air.refToIndex(bitcasted_ptr).?, + .placeholder = Air.refToIndex(dummy_store).?, }); - return sema.storePtr2(block, src, bitcasted_ptr, src, operand, src, .bitcast); } fn storeToInferredAllocComptime( diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 704a1e31c5..a3758bac69 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -3597,10 +3597,6 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { const ptr_ty = f.air.typeOf(bin_op.lhs); const ptr_scalar_ty = ptr_ty.scalarType(); const ptr_info = ptr_scalar_ty.ptrInfo().data; - if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) { - try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); - return .none; - } const ptr_val = try f.resolveInst(bin_op.lhs); const src_ty = f.air.typeOf(bin_op.rhs); @@ -4461,9 +4457,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { const ty_op = f.air.instructions.items(.data)[inst].ty_op; const dest_ty = f.air.typeOfIndex(inst); - // No IgnoreComptime until Sema stops giving us garbage Air. - // https://github.com/ziglang/zig/issues/13410 - if (f.liveness.isUnused(inst) or !dest_ty.hasRuntimeBits()) { + if (f.liveness.isUnused(inst)) { try reap(f, inst, &.{ty_op.operand}); return .none; } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index ce49fcde78..f32047fe64 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -8216,7 +8216,6 @@ pub const FuncGen = struct { const dest_ptr = try self.resolveInst(bin_op.lhs); const ptr_ty = self.air.typeOf(bin_op.lhs); const operand_ty = ptr_ty.childType(); - if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null; // TODO Sema should emit a different instruction when the store should // possibly do the safety 0xaa bytes for undefined. diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 730c0713c6..2294a2bcfd 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -140,12 +140,6 @@ test "if-else expression with runtime condition result location is inferred opti } test "result location with inferred type ends up being pointer to comptime_int" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - var a: ?u32 = 1234; var b: u32 = 2000; var c = if (a) |d| blk: { diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 20ad0a60ff..e8a9f4c831 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1540,3 +1540,19 @@ test "access the tag of a global tagged union" { }; try expect(U.u == .a); } + +test "coerce enum literal to union in result loc" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + + const U = union(enum) { + a, + b: u8, + + fn doTest(c: bool) !void { + var u = if (c) .a else @This(){ .b = 0 }; + try expect(u == .a); + } + }; + try U.doTest(true); + comptime try U.doTest(true); +} From ad8dfd367384a104f588bdc393cabae90c47c82f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 3 Apr 2023 09:14:36 +0200 Subject: [PATCH 189/216] macho+coff: remove alignment from Atom as it is unused --- src/link/Coff.zig | 13 +++++-------- src/link/Coff/Atom.zig | 5 +---- src/link/MachO.zig | 29 +++++++++++++---------------- src/link/MachO/Atom.zig | 4 ---- 4 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 800f96e90c..76a86c8a0b 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -155,6 +155,7 @@ const LazySymbolTable = std.ArrayHashMapUnmanaged( const LazySymbolMetadata = struct { atom: Atom.Index, section: u16, + alignment: u32, }; const DeclMetadata = struct { @@ -625,7 +626,6 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme { const atom_ptr = self.getAtomPtr(atom_index); atom_ptr.size = new_atom_size; - atom_ptr.alignment = alignment; } if (atom.prev_index) |prev_index| { @@ -739,7 +739,6 @@ pub fn createAtom(self: *Coff) !Atom.Index { .sym_index = sym_index, .file = null, .size = 0, - .alignment = 0, .prev_index = null, .next_index = null, }; @@ -751,11 +750,10 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !Atom.Index { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = @sizeOf(u64); - atom.alignment = @alignOf(u64); const sym = atom.getSymbolPtr(self); sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1); - sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment); + sym.value = try self.allocateAtom(atom_index, atom.size, @sizeOf(u64)); log.debug("allocated GOT atom at 0x{x}", .{sym.value}); @@ -1116,9 +1114,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In const required_alignment = tv.ty.abiAlignment(self.base.options.target); const atom = self.getAtomPtr(atom_index); - atom.alignment = required_alignment; atom.size = @intCast(u32, code.len); - atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, atom.alignment); + atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment); errdefer self.freeAtom(atom_index); try unnamed_consts.append(gpa, atom_index); @@ -1228,7 +1225,7 @@ fn updateLazySymbol( }, }; - const required_alignment = atom.alignment; + const required_alignment = lazy_metadata.alignment; const code_len = @intCast(u32, code.len); const symbol = atom.getSymbolPtr(self); try self.setSymbolName(symbol, name); @@ -1271,8 +1268,8 @@ pub fn getOrCreateAtomForLazySymbol( .code => self.text_section_index.?, .const_data => self.rdata_section_index.?, }, + .alignment = alignment, }; - self.getAtomPtr(gop.value_ptr.atom).alignment = alignment; } return gop.value_ptr.atom; } diff --git a/src/link/Coff/Atom.zig b/src/link/Coff/Atom.zig index 4afc1f7cb2..9e55575755 100644 --- a/src/link/Coff/Atom.zig +++ b/src/link/Coff/Atom.zig @@ -19,12 +19,9 @@ sym_index: u32, /// null means symbol defined by Zig source. file: ?u32, -/// Used size of the atom +/// Size of the atom size: u32, -/// Alignment of the atom -alignment: u32, - /// Points to the previous and next neighbors, based on the `text_offset`. /// This can be used to find, for example, the capacity of this `Atom`. prev_index: ?Index, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 7840f5d89d..cd7639ae52 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -242,6 +242,7 @@ const LazySymbolTable = std.ArrayHashMapUnmanaged( const LazySymbolMetadata = struct { atom: Atom.Index, section: u8, + alignment: u32, }; const DeclMetadata = struct { @@ -1205,7 +1206,6 @@ pub fn createAtom(self: *MachO) !Atom.Index { .sym_index = sym_index, .file = null, .size = 0, - .alignment = 0, .prev_index = null, .next_index = null, }; @@ -1217,7 +1217,6 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = @sizeOf(u64); - atom.alignment = @alignOf(u64); const sym = atom.getSymbolPtr(self); sym.n_type = macho.N_SECT; @@ -1259,7 +1258,6 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = @sizeOf(u64); - atom.alignment = @alignOf(u64); const sym = atom.getSymbolPtr(self); sym.n_type = macho.N_SECT; @@ -1285,7 +1283,8 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = size; - atom.alignment = switch (arch) { + + const required_alignment: u32 = switch (arch) { .x86_64 => 1, .aarch64 => @alignOf(u32), else => unreachable, @@ -1392,7 +1391,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { } self.stub_helper_preamble_atom_index = atom_index; - sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); + sym.n_value = try self.allocateAtom(atom_index, size, required_alignment); log.debug("allocated stub preamble atom at 0x{x}", .{sym.n_value}); try self.writeAtom(atom_index, code); } @@ -1408,7 +1407,8 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = size; - atom.alignment = switch (arch) { + + const required_alignment: u32 = switch (arch) { .x86_64 => 1, .aarch64 => @alignOf(u32), else => unreachable, @@ -1470,7 +1470,7 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { else => unreachable, } - sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); + sym.n_value = try self.allocateAtom(atom_index, size, required_alignment); log.debug("allocated stub helper atom at 0x{x}", .{sym.n_value}); try self.writeAtom(atom_index, code); @@ -1481,7 +1481,6 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = @sizeOf(u64); - atom.alignment = @alignOf(u64); const sym = atom.getSymbolPtr(self); sym.n_type = macho.N_SECT; @@ -1523,7 +1522,8 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = size; - atom.alignment = switch (arch) { + + const required_alignment: u32 = switch (arch) { .x86_64 => 1, .aarch64 => @alignOf(u32), else => unreachable, // unhandled architecture type @@ -1587,7 +1587,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { else => unreachable, } - sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); + sym.n_value = try self.allocateAtom(atom_index, size, required_alignment); log.debug("allocated stub atom at 0x{x}", .{sym.n_value}); try self.writeAtom(atom_index, code); @@ -2217,7 +2217,6 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); const atom = self.getAtomPtr(atom_index); atom.size = code.len; - atom.alignment = required_alignment; // TODO: work out logic for disambiguating functions from function pointers // const sect_id = self.getDeclOutputSection(decl_index); const sect_id = self.data_const_section_index.?; @@ -2355,7 +2354,7 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy }, }; - const required_alignment = atom.alignment; + const required_alignment = lazy_metadata.alignment; const symbol = atom.getSymbolPtr(self); symbol.n_strx = name_str_index; symbol.n_type = macho.N_SECT; @@ -2398,8 +2397,8 @@ pub fn getOrCreateAtomForLazySymbol( .code => self.text_section_index.?, .const_data => self.data_const_section_index.?, }, + .alignment = alignment, }; - self.getAtomPtr(gop.value_ptr.atom).alignment = alignment; } return gop.value_ptr.atom; } @@ -3222,7 +3221,6 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm { const atom_ptr = self.getAtomPtr(atom_index); atom_ptr.size = new_atom_size; - atom_ptr.alignment = @intCast(u32, alignment); } if (atom.prev_index) |prev_index| { @@ -4510,12 +4508,11 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index) void { const atom = self.getAtom(atom_index); const sym = atom.getSymbol(self); const sym_name = atom.getName(self); - log.debug(" ATOM(%{?d}, '{s}') @ {x} (sizeof({x}), alignof({x})) in object({?d}) in sect({d})", .{ + log.debug(" ATOM(%{?d}, '{s}') @ {x} sizeof({x}) in object({?d}) in sect({d})", .{ atom.getSymbolIndex(), sym_name, sym.n_value, atom.size, - atom.alignment, atom.file, sym.n_sect, }); diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 698e961db4..c601cfa440 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -33,10 +33,6 @@ file: ?u32, /// the atom since macho.nlist_64 lacks this information. size: u64, -/// Alignment of this atom as a power of 2. -/// For instance, alignment of 0 should be read as 2^0 = 1 byte aligned. -alignment: u32, - /// Points to the previous and next neighbours /// TODO use the same trick as with symbols: reserve index 0 as null atom next_index: ?Index, From 72137824e5ee59798140aef1d2061adc1c8227b9 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 3 Apr 2023 10:07:49 +0200 Subject: [PATCH 190/216] macho: clean up code responsible for growing sections in file --- src/link/Coff.zig | 6 +--- src/link/MachO.zig | 89 ++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 76a86c8a0b..3a94feb841 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -622,11 +622,7 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme try self.growSection(sect_id, needed_size); maybe_last_atom_index.* = atom_index; } - - { - const atom_ptr = self.getAtomPtr(atom_index); - atom_ptr.size = new_atom_size; - } + self.getAtomPtr(atom_index).size = new_atom_size; if (atom.prev_index) |prev_index| { const prev = self.getAtomPtr(prev_index); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index cd7639ae52..2e1076cdf6 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3053,7 +3053,51 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts return section_id; } -fn moveSectionInVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void { +fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { + const header = &self.sections.items(.header)[sect_id]; + const segment_index = self.sections.items(.segment_index)[sect_id]; + const segment = &self.segments.items[segment_index]; + const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id]; + const sect_capacity = self.allocatedSize(header.offset); + + if (needed_size > sect_capacity) { + const new_offset = self.findFreeSpace(needed_size, self.page_size); + const current_size = if (maybe_last_atom_index) |last_atom_index| blk: { + const last_atom = self.getAtom(last_atom_index); + const sym = last_atom.getSymbol(self); + break :blk (sym.n_value + last_atom.size) - segment.vmaddr; + } else 0; + + log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{ + header.segName(), + header.sectName(), + header.offset, + new_offset, + }); + + const amt = try self.base.file.?.copyRangeAll( + header.offset, + self.base.file.?, + new_offset, + current_size, + ); + if (amt != current_size) return error.InputOutput; + header.offset = @intCast(u32, new_offset); + segment.fileoff = new_offset; + } + + const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); + if (needed_size > sect_vm_capacity) { + self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); + try self.growSectionVirtualMemory(sect_id, needed_size); + } + + header.size = needed_size; + segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); + segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); +} + +fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void { const header = &self.sections.items(.header)[sect_id]; const segment = self.getSegmentPtr(sect_id); const increased_size = padToIdeal(needed_size); @@ -3172,45 +3216,9 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm else true; if (expand_section) { - const sect_capacity = self.allocatedSize(header.offset); const needed_size = (vaddr + new_atom_size) - segment.vmaddr; - if (needed_size > sect_capacity) { - const new_offset = self.findFreeSpace(needed_size, self.page_size); - const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { - const last_atom = self.getAtom(last_atom_index); - const sym = last_atom.getSymbol(self); - break :blk (sym.n_value + last_atom.size) - segment.vmaddr; - } else 0; - - log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{ - header.segName(), - header.sectName(), - header.offset, - new_offset, - }); - - const amt = try self.base.file.?.copyRangeAll( - header.offset, - self.base.file.?, - new_offset, - current_size, - ); - if (amt != current_size) return error.InputOutput; - header.offset = @intCast(u32, new_offset); - segment.fileoff = new_offset; - } - - const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); - if (needed_size > sect_vm_capacity) { - self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); - try self.moveSectionInVirtualMemory(sect_id, needed_size); - } - - header.size = needed_size; - segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); - segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); + try self.growSection(sect_id, needed_size); maybe_last_atom_index.* = atom_index; - self.segment_table_dirty = true; } @@ -3218,10 +3226,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm if (header.@"align" < align_pow) { header.@"align" = align_pow; } - { - const atom_ptr = self.getAtomPtr(atom_index); - atom_ptr.size = new_atom_size; - } + self.getAtomPtr(atom_index).size = new_atom_size; if (atom.prev_index) |prev_index| { const prev = self.getAtomPtr(prev_index); From f5f0d95f0e882ce43146b269f994c6c242f9ed3b Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 20:36:41 -0400 Subject: [PATCH 191/216] x86_64: implement a more generic assembler for inline assembly --- src/arch/x86_64/CodeGen.zig | 199 ++++++++++++++++++++++++------------ 1 file changed, 135 insertions(+), 64 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index c7dfa2c6a9..8309fe7335 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -28,10 +28,11 @@ const Type = @import("../../type.zig").Type; const TypedValue = @import("../../TypedValue.zig"); const Value = @import("../../value.zig").Value; -const bits = @import("bits.zig"); const abi = @import("abi.zig"); -const errUnionPayloadOffset = codegen.errUnionPayloadOffset; +const bits = @import("bits.zig"); +const encoder = @import("encoder.zig"); const errUnionErrorOffset = codegen.errUnionErrorOffset; +const errUnionPayloadOffset = codegen.errUnionPayloadOffset; const Condition = bits.Condition; const Immediate = bits.Immediate; @@ -6570,7 +6571,8 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { return self.fail("unrecognized constraint: '{s}'", .{constraint}); args.putAssumeCapacity(name, mcv); switch (mcv) { - .register => |reg| _ = self.register_manager.lockRegAssumeUnused(reg), + .register => |reg| _ = if (RegisterManager.indexOfRegIntoTracked(reg)) |_| + self.register_manager.lockRegAssumeUnused(reg), else => {}, } if (output == .none) result = mcv; @@ -6609,70 +6611,139 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } const asm_source = mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; - var line_it = mem.tokenize(u8, asm_source, "\n\r"); + var line_it = mem.tokenize(u8, asm_source, "\n\r;"); while (line_it.next()) |line| { var mnem_it = mem.tokenize(u8, line, " \t"); - const mnem = mnem_it.next() orelse continue; - if (mem.startsWith(u8, mnem, "#")) continue; - var arg_it = mem.tokenize(u8, mnem_it.rest(), ", "); - if (std.ascii.eqlIgnoreCase(mnem, "syscall")) { - if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) - return self.fail("Too many operands: '{s}'", .{line}); - try self.asmOpOnly(.syscall); - } else if (std.ascii.eqlIgnoreCase(mnem, "push")) { - const src = arg_it.next() orelse - return self.fail("Not enough operands: '{s}'", .{line}); - if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) - return self.fail("Too many operands: '{s}'", .{line}); - if (mem.startsWith(u8, src, "$")) { - const imm = std.fmt.parseInt(u32, src["$".len..], 0) catch - return self.fail("Invalid immediate: '{s}'", .{src}); - try self.asmImmediate(.push, Immediate.u(imm)); - } else if (mem.startsWith(u8, src, "%%")) { - const reg = parseRegName(src["%%".len..]) orelse - return self.fail("Invalid register: '{s}'", .{src}); - try self.asmRegister(.push, reg); - } else return self.fail("Unsupported operand: '{s}'", .{src}); - } else if (std.ascii.eqlIgnoreCase(mnem, "pop")) { - const dst = arg_it.next() orelse - return self.fail("Not enough operands: '{s}'", .{line}); - if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) - return self.fail("Too many operands: '{s}'", .{line}); - if (mem.startsWith(u8, dst, "%%")) { - const reg = parseRegName(dst["%%".len..]) orelse - return self.fail("Invalid register: '{s}'", .{dst}); - try self.asmRegister(.pop, reg); - } else return self.fail("Unsupported operand: '{s}'", .{dst}); - } else if (std.ascii.eqlIgnoreCase(mnem, "movq")) { - const src = arg_it.next() orelse - return self.fail("Not enough operands: '{s}'", .{line}); - const dst = arg_it.next() orelse - return self.fail("Not enough operands: '{s}'", .{line}); - if (arg_it.next()) |trailing| if (!mem.startsWith(u8, trailing, "#")) - return self.fail("Too many operands: '{s}'", .{line}); - if (mem.startsWith(u8, src, "%%")) { - const colon = mem.indexOfScalarPos(u8, src, "%%".len + 2, ':'); - const src_reg = parseRegName(src["%%".len .. colon orelse src.len]) orelse - return self.fail("Invalid register: '{s}'", .{src}); + const mnem_str = mnem_it.next() orelse continue; + if (mem.startsWith(u8, mnem_str, "#")) continue; + + const mnem_size: ?Memory.PtrSize = if (mem.endsWith(u8, mnem_str, "b")) + .byte + else if (mem.endsWith(u8, mnem_str, "w")) + .word + else if (mem.endsWith(u8, mnem_str, "l")) + .dword + else if (mem.endsWith(u8, mnem_str, "q")) + .qword + else + null; + const mnem = std.meta.stringToEnum(Mir.Inst.Tag, mnem_str) orelse + (if (mnem_size) |_| + std.meta.stringToEnum(Mir.Inst.Tag, mnem_str[0 .. mnem_str.len - 1]) + else + null) orelse return self.fail("Invalid mnemonic: '{s}'", .{mnem_str}); + + var op_it = mem.tokenize(u8, mnem_it.rest(), ","); + var ops = [1]encoder.Instruction.Operand{.none} ** 4; + for (&ops) |*op| { + const op_str = mem.trim(u8, op_it.next() orelse break, " \t"); + if (mem.startsWith(u8, op_str, "#")) break; + if (mem.startsWith(u8, op_str, "%%")) { + const colon = mem.indexOfScalarPos(u8, op_str, "%%".len + 2, ':'); + const reg = parseRegName(op_str["%%".len .. colon orelse op_str.len]) orelse + return self.fail("Invalid register: '{s}'", .{op_str}); if (colon) |colon_pos| { - const src_disp = std.fmt.parseInt(i32, src[colon_pos + 1 ..], 0) catch - return self.fail("Invalid immediate: '{s}'", .{src}); - if (mem.startsWith(u8, dst, "%[") and mem.endsWith(u8, dst, "]")) { - switch (args.get(dst["%[".len .. dst.len - "]".len]) orelse - return self.fail("no matching constraint for: '{s}'", .{dst})) { - .register => |dst_reg| try self.asmRegisterMemory( - .mov, - dst_reg, - Memory.sib(.qword, .{ .base = src_reg, .disp = src_disp }), - ), - else => return self.fail("Invalid constraint: '{s}'", .{dst}), - } - } else return self.fail("Unsupported operand: '{s}'", .{dst}); - } else return self.fail("Unsupported operand: '{s}'", .{src}); - } - } else { - return self.fail("Unsupported instruction: '{s}'", .{mnem}); - } + const disp = std.fmt.parseInt(i32, op_str[colon_pos + 1 ..], 0) catch + return self.fail("Invalid displacement: '{s}'", .{op_str}); + op.* = .{ .mem = Memory.sib( + mnem_size orelse return self.fail("Unknown size: '{s}'", .{op_str}), + .{ .base = reg, .disp = disp }, + ) }; + } else { + if (mnem_size) |size| if (reg.bitSize() != size.bitSize()) + return self.fail("Invalid register size: '{s}'", .{op_str}); + op.* = .{ .reg = reg }; + } + } else if (mem.startsWith(u8, op_str, "%[") and mem.endsWith(u8, op_str, "]")) { + switch (args.get(op_str["%[".len .. op_str.len - "]".len]) orelse + return self.fail("No matching constraint: '{s}'", .{op_str})) { + .register => |reg| op.* = .{ .reg = reg }, + else => return self.fail("Invalid constraint: '{s}'", .{op_str}), + } + } else if (mem.startsWith(u8, op_str, "$")) { + if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| { + if (mnem_size) |size| { + const max = @as(u64, std.math.maxInt(u64)) >> + @intCast(u6, 64 - (size.bitSize() - 1)); + if ((if (s < 0) ~s else s) > max) + return self.fail("Invalid immediate size: '{s}'", .{op_str}); + } + op.* = .{ .imm = Immediate.s(s) }; + } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| { + if (mnem_size) |size| { + const max = @as(u64, std.math.maxInt(u64)) >> + @intCast(u6, 64 - size.bitSize()); + if (u > max) + return self.fail("Invalid immediate size: '{s}'", .{op_str}); + } + op.* = .{ .imm = Immediate.u(u) }; + } else |_| return self.fail("Invalid immediate: '{s}'", .{op_str}); + } else return self.fail("Invalid operand: '{s}'", .{op_str}); + } else if (op_it.next()) |op_str| return self.fail("Extra operand: '{s}'", .{op_str}); + + (switch (ops[0]) { + .none => self.asmOpOnly(mnem), + .reg => |reg0| switch (ops[1]) { + .none => self.asmRegister(mnem, reg0), + .reg => |reg1| switch (ops[2]) { + .none => self.asmRegisterRegister(mnem, reg1, reg0), + .reg => |reg2| switch (ops[3]) { + .none => self.asmRegisterRegisterRegister(mnem, reg2, reg1, reg0), + else => error.InvalidInstruction, + }, + .mem => |mem2| switch (ops[3]) { + .none => self.asmMemoryRegisterRegister(mnem, mem2, reg1, reg0), + else => error.InvalidInstruction, + }, + else => error.InvalidInstruction, + }, + .mem => |mem1| switch (ops[2]) { + .none => self.asmMemoryRegister(mnem, mem1, reg0), + else => error.InvalidInstruction, + }, + else => error.InvalidInstruction, + }, + .mem => |mem0| switch (ops[1]) { + .none => self.asmMemory(mnem, mem0), + .reg => |reg1| switch (ops[2]) { + .none => self.asmRegisterMemory(mnem, reg1, mem0), + else => error.InvalidInstruction, + }, + else => error.InvalidInstruction, + }, + .imm => |imm0| switch (ops[1]) { + .none => self.asmImmediate(mnem, imm0), + .reg => |reg1| switch (ops[2]) { + .none => self.asmRegisterImmediate(mnem, reg1, imm0), + .reg => |reg2| switch (ops[3]) { + .none => self.asmRegisterRegisterImmediate(mnem, reg2, reg1, imm0), + else => error.InvalidInstruction, + }, + .mem => |mem2| switch (ops[3]) { + .none => self.asmMemoryRegisterImmediate(mnem, mem2, reg1, imm0), + else => error.InvalidInstruction, + }, + else => error.InvalidInstruction, + }, + .mem => |mem1| switch (ops[2]) { + .none => self.asmMemoryImmediate(mnem, mem1, imm0), + else => error.InvalidInstruction, + }, + else => error.InvalidInstruction, + }, + }) catch |err| switch (err) { + error.InvalidInstruction => return self.fail( + "Invalid instruction: '{s} {s} {s} {s} {s}'", + .{ + @tagName(mnem), + @tagName(ops[0]), + @tagName(ops[1]), + @tagName(ops[2]), + @tagName(ops[3]), + }, + ), + else => |e| return e, + }; } } From 272acb7ee5368a32d9f4bc559e93d96759b80173 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 21:39:20 -0400 Subject: [PATCH 192/216] x86_64: implement storing large immediates --- src/arch/x86_64/CodeGen.zig | 241 +++++++++++++++--------------------- test/behavior/bugs/3007.zig | 1 - test/behavior/eval.zig | 3 - 3 files changed, 98 insertions(+), 147 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 8309fe7335..f3bd6a9e8a 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3669,52 +3669,67 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .none => unreachable, .dead => unreachable, .unreach => unreachable, - .eflags => |cc| { - try self.asmSetccMemory(Memory.sib( - Memory.PtrSize.fromSize(abi_size), - .{ .base = reg.to64() }, - ), cc); + .eflags => |cc| try self.asmSetccMemory( + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), + cc, + ), + .undef => if (self.wantSafety()) switch (abi_size) { + 1 => try self.store(ptr, .{ .immediate = 0xaa }, ptr_ty, value_ty), + 2 => try self.store(ptr, .{ .immediate = 0xaaaa }, ptr_ty, value_ty), + 4 => try self.store(ptr, .{ .immediate = 0xaaaaaaaa }, ptr_ty, value_ty), + 8 => try self.store(ptr, .{ .immediate = 0xaaaaaaaaaaaaaaaa }, ptr_ty, value_ty), + else => try self.genInlineMemset( + ptr, + .{ .immediate = 0xaa }, + .{ .immediate = abi_size }, + .{}, + ), }, - .undef => { - if (!self.wantSafety()) return; // The already existing value will do just fine. - switch (abi_size) { - 1 => try self.store(ptr, .{ .immediate = 0xaa }, ptr_ty, value_ty), - 2 => try self.store(ptr, .{ .immediate = 0xaaaa }, ptr_ty, value_ty), - 4 => try self.store(ptr, .{ .immediate = 0xaaaaaaaa }, ptr_ty, value_ty), - 8 => try self.store(ptr, .{ .immediate = 0xaaaaaaaaaaaaaaaa }, ptr_ty, value_ty), - else => try self.genInlineMemset(ptr, .{ .immediate = 0xaa }, .{ .immediate = abi_size }, .{}), - } - }, - .immediate => |imm| { - switch (abi_size) { - 1, 2, 4 => { - const immediate = if (value_ty.isSignedInt()) - Immediate.s(@intCast(i32, @bitCast(i64, imm))) - else - Immediate.u(@truncate(u32, imm)); - try self.asmMemoryImmediate(.mov, Memory.sib( - Memory.PtrSize.fromSize(abi_size), - .{ .base = reg.to64() }, - ), immediate); - }, - 8 => { - // TODO: optimization: if the imm is only using the lower - // 4 bytes and can be sign extended we can use a normal mov - // with indirect addressing (mov [reg64], imm32). - - // movabs does not support indirect register addressing - // so we need an extra register and an extra mov. - const tmp_reg = try self.copyToTmpRegister(value_ty, value); - return self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); - }, - else => { - return self.fail("TODO implement set pointee with immediate of ABI size {d}", .{abi_size}); - }, - } - }, - .register => |src_reg| { - try self.genInlineMemcpyRegisterRegister(value_ty, reg, src_reg, 0); + .immediate => |imm| switch (self.regBitSize(value_ty)) { + 8 => try self.asmMemoryImmediate( + .mov, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), + if (math.cast(i8, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u8, imm)), + ), + 16 => try self.asmMemoryImmediate( + .mov, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), + if (math.cast(i16, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u16, imm)), + ), + 32 => try self.asmMemoryImmediate( + .mov, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), + if (math.cast(i32, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u32, imm)), + ), + 64 => if (math.cast(i32, @bitCast(i64, imm))) |small| + try self.asmMemoryImmediate( + .mov, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), + Immediate.s(small), + ) + else + try self.asmMemoryRegister( + .mov, + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), + registerAlias(try self.copyToTmpRegister(value_ty, value), abi_size), + ), + else => unreachable, }, + .register => |src_reg| try self.genInlineMemcpyRegisterRegister( + value_ty, + reg, + src_reg, + 0, + ), .register_overflow => |ro| { const ro_reg_lock = self.register_manager.lockReg(ro.reg); defer if (ro_reg_lock) |lock| self.register_manager.unlockReg(lock); @@ -3765,8 +3780,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type defer self.register_manager.unlockReg(addr_reg_lock); try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); - - // To get the actual address of the value we want to modify we have to go through the GOT + // Load the pointer, which is stored in memory try self.asmRegisterMemory( .mov, addr_reg.to64(), @@ -3774,62 +3788,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type ); const new_ptr = MCValue{ .register = addr_reg.to64() }; - - switch (value) { - .immediate => |imm| { - if (abi_size > 8) { - return self.fail("TODO saving imm to memory for abi_size {}", .{abi_size}); - } - - if (abi_size == 8) { - // TODO - const top_bits: u32 = @intCast(u32, imm >> 32); - const can_extend = if (value_ty.isUnsignedInt()) - (top_bits == 0) and (imm & 0x8000_0000) == 0 - else - top_bits == 0xffff_ffff; - - if (!can_extend) { - return self.fail("TODO imm64 would get incorrectly sign extended", .{}); - } - } - try self.asmMemoryImmediate( - .mov, - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg.to64() }), - Immediate.u(@intCast(u32, imm)), - ); - }, - .register => { - return self.store(new_ptr, value, ptr_ty, value_ty); - }, - .linker_load, .memory => { - if (abi_size <= 8) { - const tmp_reg = try self.register_manager.allocReg(null, gp); - const tmp_reg_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); - defer self.register_manager.unlockReg(tmp_reg_lock); - - try self.loadMemPtrIntoRegister(tmp_reg, value_ty, value); - try self.asmRegisterMemory( - .mov, - tmp_reg, - Memory.sib(.qword, .{ .base = tmp_reg }), - ); - - return self.store(new_ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); - } - - try self.genInlineMemcpy(new_ptr, value, .{ .immediate = abi_size }, .{}); - }, - .stack_offset => { - if (abi_size <= 8) { - const tmp_reg = try self.copyToTmpRegister(value_ty, value); - return self.store(new_ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); - } - - try self.genInlineMemcpy(new_ptr, value, .{ .immediate = abi_size }, .{}); - }, - else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}), - } + return self.store(new_ptr, value, ptr_ty, value_ty); }, } } @@ -4887,41 +4846,39 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s registerAlias(src_reg, abi_size), ), }, - .immediate => |imm| { - switch (self.regBitSize(ty)) { - 8 => try self.asmRegisterImmediate( - mir_tag, - dst_alias, - if (math.cast(i8, @bitCast(i64, imm))) |small| - Immediate.s(small) - else - Immediate.u(@intCast(u8, imm)), - ), - 16 => try self.asmRegisterImmediate( - mir_tag, - dst_alias, - if (math.cast(i16, @bitCast(i64, imm))) |small| - Immediate.s(small) - else - Immediate.u(@intCast(u16, imm)), - ), - 32 => try self.asmRegisterImmediate( - mir_tag, - dst_alias, - if (math.cast(i32, @bitCast(i64, imm))) |small| - Immediate.s(small) - else - Immediate.u(@intCast(u32, imm)), - ), - 64 => if (math.cast(i32, @bitCast(i64, imm))) |small| - try self.asmRegisterImmediate(mir_tag, dst_alias, Immediate.s(small)) + .immediate => |imm| switch (self.regBitSize(ty)) { + 8 => try self.asmRegisterImmediate( + mir_tag, + dst_alias, + if (math.cast(i8, @bitCast(i64, imm))) |small| + Immediate.s(small) else - try self.asmRegisterRegister(mir_tag, dst_alias, registerAlias( - try self.copyToTmpRegister(ty, src_mcv), - abi_size, - )), - else => unreachable, - } + Immediate.u(@intCast(u8, imm)), + ), + 16 => try self.asmRegisterImmediate( + mir_tag, + dst_alias, + if (math.cast(i16, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u16, imm)), + ), + 32 => try self.asmRegisterImmediate( + mir_tag, + dst_alias, + if (math.cast(i32, @bitCast(i64, imm))) |small| + Immediate.s(small) + else + Immediate.u(@intCast(u32, imm)), + ), + 64 => if (math.cast(i32, @bitCast(i64, imm))) |small| + try self.asmRegisterImmediate(mir_tag, dst_alias, Immediate.s(small)) + else + try self.asmRegisterRegister(mir_tag, dst_alias, registerAlias( + try self.copyToTmpRegister(ty, src_mcv), + abi_size, + )), + else => unreachable, }, .memory, .linker_load, .eflags => { assert(abi_size <= 8); @@ -4931,13 +4888,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s const reg = try self.copyToTmpRegister(ty, src_mcv); return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = reg }); }, - .stack_offset => |off| { - try self.asmRegisterMemory( - mir_tag, - registerAlias(dst_reg, abi_size), - Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), - ); - }, + .stack_offset => |off| try self.asmRegisterMemory( + mir_tag, + registerAlias(dst_reg, abi_size), + Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), + ), } }, .memory, .linker_load, .stack_offset => { diff --git a/test/behavior/bugs/3007.zig b/test/behavior/bugs/3007.zig index df6a63b640..3ae1562e9b 100644 --- a/test/behavior/bugs/3007.zig +++ b/test/behavior/bugs/3007.zig @@ -21,7 +21,6 @@ fn get_foo() Foo.FooError!*Foo { test "fixed" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO default_foo = get_foo() catch null; // This Line diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 7fa8066505..214f2beb07 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -967,7 +967,6 @@ test "closure capture type of runtime-known parameter" { } test "comptime break passing through runtime condition converted to runtime break" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { @@ -999,7 +998,6 @@ test "comptime break passing through runtime condition converted to runtime brea } test "comptime break to outer loop passing through runtime condition converted to runtime break" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -1218,7 +1216,6 @@ test "storing an array of type in a field" { } test "pass pointer to field of comptime-only type as a runtime parameter" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From 1980f5479b2139112ff67de5d5f2e6af09fb215e Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 22:25:35 -0400 Subject: [PATCH 193/216] x86_64: implement store to immediate address --- src/arch/x86_64/CodeGen.zig | 32 ++++++++++++-------------------- test/behavior/inttoptr.zig | 1 - 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f3bd6a9e8a..44362f9bc0 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3651,10 +3651,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .dead => unreachable, .eflags => unreachable, .register_overflow => unreachable, - .immediate => |imm| { - try self.setRegOrMem(value_ty, .{ .memory = imm }, value); - }, - .stack_offset => { + .immediate, .stack_offset => { const reg = try self.copyToTmpRegister(ptr_ty, ptr); try self.store(.{ .register = reg }, value, ptr_ty, value_ty); }, @@ -3748,23 +3745,18 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type -@intCast(i32, overflow_bit_offset), ); }, - .linker_load, - .memory, - .stack_offset, - => { - if (abi_size <= 8) { - const tmp_reg = try self.copyToTmpRegister(value_ty, value); - return self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); - } - - try self.genInlineMemcpy(.{ .stack_offset = 0 }, value, .{ .immediate = abi_size }, .{ - .source_stack_base = .rbp, - .dest_stack_base = reg.to64(), - }); - }, + .linker_load, .memory, .stack_offset => if (abi_size <= 8) { + const tmp_reg = try self.copyToTmpRegister(value_ty, value); + try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); + } else try self.genInlineMemcpy( + .{ .stack_offset = 0 }, + value, + .{ .immediate = abi_size }, + .{ .source_stack_base = .rbp, .dest_stack_base = reg.to64() }, + ), .ptr_stack_offset => { const tmp_reg = try self.copyToTmpRegister(value_ty, value); - return self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); + try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); }, } }, @@ -3788,7 +3780,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type ); const new_ptr = MCValue{ .register = addr_reg.to64() }; - return self.store(new_ptr, value, ptr_ty, value_ty); + try self.store(new_ptr, value, ptr_ty, value_ty); }, } } diff --git a/test/behavior/inttoptr.zig b/test/behavior/inttoptr.zig index e1281c406d..29a263b2ce 100644 --- a/test/behavior/inttoptr.zig +++ b/test/behavior/inttoptr.zig @@ -11,7 +11,6 @@ fn addressToFunction() void { } test "mutate through ptr initialized with constant intToPtr value" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From fde1ec5d0e57471b43bab226a78da2eb61e6bb66 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 2 Apr 2023 22:25:53 -0400 Subject: [PATCH 194/216] x86_64: remove returns from naked functions --- lib/std/os/linux/x86.zig | 16 ++++++++++++---- lib/std/os/linux/x86_64.zig | 7 +++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/std/os/linux/x86.zig b/lib/std/os/linux/x86.zig index 6ad3c9fa31..2e67fa6b5b 100644 --- a/lib/std/os/linux/x86.zig +++ b/lib/std/os/linux/x86.zig @@ -125,36 +125,44 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * pub fn restore() callconv(.Naked) void { switch (@import("builtin").zig_backend) { - .stage2_c => return asm volatile ( + .stage2_c => asm volatile ( \\ movl %[number], %%eax \\ int $0x80 + \\ ret : : [number] "i" (@enumToInt(SYS.sigreturn)), : "memory" ), - else => return asm volatile ("int $0x80" + else => asm volatile ( + \\ int $0x80 + \\ ret : : [number] "{eax}" (@enumToInt(SYS.sigreturn)), : "memory" ), } + unreachable; } pub fn restore_rt() callconv(.Naked) void { switch (@import("builtin").zig_backend) { - .stage2_c => return asm volatile ( + .stage2_c => asm volatile ( \\ movl %[number], %%eax \\ int $0x80 + \\ ret : : [number] "i" (@enumToInt(SYS.rt_sigreturn)), : "memory" ), - else => return asm volatile ("int $0x80" + else => asm volatile ( + \\ int $0x80 + \\ ret : : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), : "memory" ), } + unreachable; } pub const O = struct { diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig index bc1bccf53f..09047bda83 100644 --- a/lib/std/os/linux/x86_64.zig +++ b/lib/std/os/linux/x86_64.zig @@ -109,7 +109,7 @@ pub const restore = restore_rt; pub fn restore_rt() callconv(.Naked) void { switch (@import("builtin").zig_backend) { - .stage2_c => return asm volatile ( + .stage2_c => asm volatile ( \\ movl %[number], %%eax \\ syscall \\ retq @@ -117,12 +117,15 @@ pub fn restore_rt() callconv(.Naked) void { : [number] "i" (@enumToInt(SYS.rt_sigreturn)), : "rcx", "r11", "memory" ), - else => return asm volatile ("syscall" + else => asm volatile ( + \\ syscall + \\ retq : : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)), : "rcx", "r11", "memory" ), } + unreachable; } pub const mode_t = usize; From cd24ab7f6e56c8365896a9b2dfc506a787346ecb Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 01:34:05 -0400 Subject: [PATCH 195/216] x86_64: canonicalise loops --- src/arch/x86_64/CodeGen.zig | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 44362f9bc0..a2d0d4da41 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -6132,7 +6132,28 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void { const loop = self.air.extraData(Air.Block, ty_pl.payload); const body = self.air.extra[loop.end..][0..loop.data.body_len]; const jmp_target = @intCast(u32, self.mir_instructions.len); - try self.genBody(body); + + { + try self.branch_stack.append(.{}); + errdefer _ = self.branch_stack.pop(); + + try self.genBody(body); + } + + var branch = self.branch_stack.pop(); + defer branch.deinit(self.gpa); + + log.debug("airLoop: %{d}", .{inst}); + log.debug("Upper branches:", .{}); + for (self.branch_stack.items) |bs| { + log.debug("{}", .{bs.fmtDebug()}); + } + log.debug("Loop branch: {}", .{branch.fmtDebug()}); + + var dummy_branch = Branch{}; + defer dummy_branch.deinit(self.gpa); + try self.canonicaliseBranches(true, &dummy_branch, &branch, true, false); + _ = try self.asmJmpReloc(jmp_target); return self.finishAirBookkeeping(); } From f0d13489f819ecd1c0d1c23914127c225f507241 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 04:55:15 -0400 Subject: [PATCH 196/216] Elf: add program headers for the program header table --- lib/std/start.zig | 1 - src/link/Elf.zig | 297 +++++++++++------- .../hello_world_with_updates.0.zig | 2 +- .../hello_world_with_updates.0.zig | 2 +- .../hello_world_with_updates.0.zig | 2 +- .../hello_world_with_updates.0.zig | 2 +- 6 files changed, 181 insertions(+), 125 deletions(-) diff --git a/lib/std/start.zig b/lib/std/start.zig index b3a064c7f0..e79dd1b9a7 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -19,7 +19,6 @@ const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start"; // self-hosted is capable enough to handle all of the real start.zig logic. pub const simplified_logic = builtin.zig_backend == .stage2_wasm or - builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_x86 or builtin.zig_backend == .stage2_aarch64 or builtin.zig_backend == .stage2_arm or diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 3b7c2efa0e..8079b09166 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -106,7 +106,12 @@ shdr_table_offset: ?u64 = null, /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. /// Same order as in the file. program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, -phdr_table_offset: ?u64 = null, +/// The index into the program headers of the PT_PHDR program header +phdr_table_index: ?u16 = null, +/// The index into the program headers of the PT_LOAD program header containing the phdr +/// Most linkers would merge this with phdr_load_ro_index, +/// but hot swap means we can't ensure they are consecutive. +phdr_table_load_index: ?u16 = null, /// The index into the program headers of a PT_LOAD program header with Read and Execute flags phdr_load_re_index: ?u16 = null, /// The index into the program headers of the global offset table. @@ -386,9 +391,10 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { const end = start + padToIdeal(size); - if (self.shdr_table_offset) |off| { - const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); - const tight_size = self.sections.slice().len * shdr_size; + if (self.phdr_table_index) |index| { + const off = self.program_headers.items[index].p_offset; + const phdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Phdr) else @sizeOf(elf.Elf64_Phdr); + const tight_size = self.program_headers.items.len * phdr_size; const increased_size = padToIdeal(tight_size); const test_end = off + increased_size; if (end > off and start < test_end) { @@ -396,9 +402,9 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { } } - if (self.phdr_table_offset) |off| { - const phdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Phdr) else @sizeOf(elf.Elf64_Phdr); - const tight_size = self.sections.slice().len * phdr_size; + if (self.shdr_table_offset) |off| { + const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); + const tight_size = self.sections.slice().len * shdr_size; const increased_size = padToIdeal(tight_size); const test_end = off + increased_size; if (end > off and start < test_end) { @@ -427,10 +433,11 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { if (start == 0) return 0; var min_pos: u64 = std.math.maxInt(u64); - if (self.shdr_table_offset) |off| { + if (self.phdr_table_index) |index| { + const off = self.program_headers.items[index].p_offset; if (off > start and off < min_pos) min_pos = off; } - if (self.phdr_table_offset) |off| { + if (self.shdr_table_offset) |off| { if (off > start and off < min_pos) min_pos = off; } for (self.sections.items(.shdr)) |section| { @@ -462,96 +469,146 @@ pub fn populateMissingMetadata(self: *Elf) !void { }; const ptr_size: u8 = self.ptrWidthBytes(); - if (self.phdr_load_re_index == null) { - self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len); - const file_size = self.base.options.program_code_size_hint; - const p_align = self.page_size; - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size }); - const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = entry_addr, - .p_paddr = entry_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_X | elf.PF_R | elf.PF_W, - }); - self.entry_addr = null; - self.phdr_table_dirty = true; - } + { // Program Headers + var new_phdr_table_index: ?u16 = null; + if (self.phdr_table_index == null) { + new_phdr_table_index = @intCast(u16, self.program_headers.items.len); + const phalign: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Phdr), + .p64 => @alignOf(elf.Elf64_Phdr), + }; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_PHDR, + .p_offset = undefined, + .p_filesz = undefined, + .p_vaddr = undefined, + .p_paddr = undefined, + .p_memsz = undefined, + .p_align = phalign, + .p_flags = elf.PF_R, + }); + self.phdr_table_dirty = true; + } - if (self.phdr_got_index == null) { - self.phdr_got_index = @intCast(u16, self.program_headers.items.len); - const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; - // We really only need ptr alignment but since we are using PROGBITS, linux requires - // page align. - const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD GOT free space 0x{x} to 0x{x}", .{ off, off + file_size }); - // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. - // we'll need to re-use that function anyway, in case the GOT grows and overlaps something - // else in virtual memory. - const got_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x4000000 else 0x8000; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = got_addr, - .p_paddr = got_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R | elf.PF_W, - }); - self.phdr_table_dirty = true; - } + if (self.phdr_table_load_index == null) { + self.phdr_table_load_index = @intCast(u16, self.program_headers.items.len); + // TODO Same as for GOT + const phdr_addr: u64 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x1000000 else 0x1000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = undefined, + .p_filesz = undefined, + .p_vaddr = phdr_addr, + .p_paddr = phdr_addr, + .p_memsz = undefined, + .p_align = self.page_size, + .p_flags = elf.PF_R, + }); + self.phdr_table_dirty = true; + } - if (self.phdr_load_ro_index == null) { - self.phdr_load_ro_index = @intCast(u16, self.program_headers.items.len); - // TODO Find a hint about how much data need to be in rodata ? - const file_size = 1024; - // Same reason as for GOT - const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}", .{ off, off + file_size }); - // TODO Same as for GOT - const rodata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0xc000000 else 0xa000; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = rodata_addr, - .p_paddr = rodata_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R | elf.PF_W, - }); - self.phdr_table_dirty = true; - } + if (self.phdr_load_re_index == null) { + self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len); + const file_size = self.base.options.program_code_size_hint; + const p_align = self.page_size; + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size }); + const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = entry_addr, + .p_paddr = entry_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_X | elf.PF_R | elf.PF_W, + }); + self.entry_addr = null; + self.phdr_table_dirty = true; + } - if (self.phdr_load_rw_index == null) { - self.phdr_load_rw_index = @intCast(u16, self.program_headers.items.len); - // TODO Find a hint about how much data need to be in data ? - const file_size = 1024; - // Same reason as for GOT - const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}", .{ off, off + file_size }); - // TODO Same as for GOT - const rwdata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x10000000 else 0xc000; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = rwdata_addr, - .p_paddr = rwdata_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R | elf.PF_W, - }); - self.phdr_table_dirty = true; + if (self.phdr_got_index == null) { + self.phdr_got_index = @intCast(u16, self.program_headers.items.len); + const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; + // We really only need ptr alignment but since we are using PROGBITS, linux requires + // page align. + const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD GOT free space 0x{x} to 0x{x}", .{ off, off + file_size }); + // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. + // we'll need to re-use that function anyway, in case the GOT grows and overlaps something + // else in virtual memory. + const got_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x4000000 else 0x8000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = got_addr, + .p_paddr = got_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R | elf.PF_W, + }); + self.phdr_table_dirty = true; + } + + if (self.phdr_load_ro_index == null) { + self.phdr_load_ro_index = @intCast(u16, self.program_headers.items.len); + // TODO Find a hint about how much data need to be in rodata ? + const file_size = 1024; + // Same reason as for GOT + const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}", .{ off, off + file_size }); + // TODO Same as for GOT + const rodata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0xc000000 else 0xa000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = rodata_addr, + .p_paddr = rodata_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R | elf.PF_W, + }); + self.phdr_table_dirty = true; + } + + if (self.phdr_load_rw_index == null) { + self.phdr_load_rw_index = @intCast(u16, self.program_headers.items.len); + // TODO Find a hint about how much data need to be in data ? + const file_size = 1024; + // Same reason as for GOT + const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}", .{ off, off + file_size }); + // TODO Same as for GOT + const rwdata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x10000000 else 0xc000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = rwdata_addr, + .p_paddr = rwdata_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R | elf.PF_W, + }); + self.phdr_table_dirty = true; + } + + if (new_phdr_table_index) |index| { + const phsize: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Phdr), + .p64 => @sizeOf(elf.Elf64_Phdr), + }; + const phdr_table = &self.program_headers.items[index]; + phdr_table.p_offset = self.findFreeSpace(self.program_headers.items.len * phsize, @intCast(u32, phdr_table.p_align)); + self.phdr_table_index = index; + self.phdr_table_dirty = true; + } } if (self.shstrtab_index == null) { @@ -849,19 +906,6 @@ pub fn populateMissingMetadata(self: *Elf) !void { self.shdr_table_dirty = true; } - const phsize: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Phdr), - .p64 => @sizeOf(elf.Elf64_Phdr), - }; - const phalign: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Phdr), - .p64 => @alignOf(elf.Elf64_Phdr), - }; - if (self.phdr_table_offset == null) { - self.phdr_table_offset = self.findFreeSpace(self.program_headers.items.len * phsize, phalign); - self.phdr_table_dirty = true; - } - { // Iterate over symbols, populating free_list and last_text_block. if (self.local_symbols.items.len != 1) { @@ -1132,18 +1176,30 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node .p32 => @sizeOf(elf.Elf32_Phdr), .p64 => @sizeOf(elf.Elf64_Phdr), }; - const phalign: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Phdr), - .p64 => @alignOf(elf.Elf64_Phdr), - }; - const allocated_size = self.allocatedSize(self.phdr_table_offset.?); + + const phdr_table_index = self.phdr_table_index.?; + const phdr_table = &self.program_headers.items[phdr_table_index]; + const phdr_table_load = &self.program_headers.items[self.phdr_table_load_index.?]; + + const allocated_size = self.allocatedSize(phdr_table.p_offset); const needed_size = self.program_headers.items.len * phsize; if (needed_size > allocated_size) { - self.phdr_table_offset = null; // free the space - self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); + self.phdr_table_index = null; // free the space + defer self.phdr_table_index = phdr_table_index; + phdr_table.p_offset = self.findFreeSpace(needed_size, @intCast(u32, phdr_table.p_align)); } + phdr_table_load.p_offset = mem.alignBackwardGeneric(u64, phdr_table.p_offset, phdr_table_load.p_align); + const load_align_offset = phdr_table.p_offset - phdr_table_load.p_offset; + phdr_table_load.p_filesz = load_align_offset + needed_size; + phdr_table_load.p_memsz = load_align_offset + needed_size; + + phdr_table.p_filesz = needed_size; + phdr_table.p_vaddr = phdr_table_load.p_vaddr + load_align_offset; + phdr_table.p_paddr = phdr_table_load.p_paddr + load_align_offset; + phdr_table.p_memsz = needed_size; + switch (self.ptr_width) { .p32 => { const buf = try gpa.alloc(elf.Elf32_Phdr, self.program_headers.items.len); @@ -1155,7 +1211,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); } } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); }, .p64 => { const buf = try gpa.alloc(elf.Elf64_Phdr, self.program_headers.items.len); @@ -1167,7 +1223,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); } } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); }, } self.phdr_table_dirty = false; @@ -1992,13 +2048,14 @@ fn writeElfHeader(self: *Elf) !void { const e_entry = if (elf_type == .REL) 0 else self.entry_addr.?; + const phdr_table_offset = self.program_headers.items[self.phdr_table_index.?].p_offset; switch (self.ptr_width) { .p32 => { mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, e_entry), endian); index += 4; // e_phoff - mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, self.phdr_table_offset.?), endian); + mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, phdr_table_offset), endian); index += 4; // e_shoff @@ -2011,7 +2068,7 @@ fn writeElfHeader(self: *Elf) !void { index += 8; // e_phoff - mem.writeInt(u64, hdr_buf[index..][0..8], self.phdr_table_offset.?, endian); + mem.writeInt(u64, hdr_buf[index..][0..8], phdr_table_offset, endian); index += 8; // e_shoff diff --git a/test/cases/aarch64-macos/hello_world_with_updates.0.zig b/test/cases/aarch64-macos/hello_world_with_updates.0.zig index 90aa14ab65..9f516ff139 100644 --- a/test/cases/aarch64-macos/hello_world_with_updates.0.zig +++ b/test/cases/aarch64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=aarch64-macos // -// :110:9: error: root struct of file 'tmp' has no member named 'main' +// :109:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-linux/hello_world_with_updates.0.zig b/test/cases/x86_64-linux/hello_world_with_updates.0.zig index 16c280774e..40abdd6c1f 100644 --- a/test/cases/x86_64-linux/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-linux/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-linux // -// :110:9: error: root struct of file 'tmp' has no member named 'main' +// :109:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-macos/hello_world_with_updates.0.zig b/test/cases/x86_64-macos/hello_world_with_updates.0.zig index d91bd9dc91..e0680c81d7 100644 --- a/test/cases/x86_64-macos/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-macos // -// :110:9: error: root struct of file 'tmp' has no member named 'main' +// :109:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-windows/hello_world_with_updates.0.zig b/test/cases/x86_64-windows/hello_world_with_updates.0.zig index 0c4d2c2bc2..04e1d4cfad 100644 --- a/test/cases/x86_64-windows/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-windows/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-windows // -// :131:9: error: root struct of file 'tmp' has no member named 'main' +// :130:9: error: root struct of file 'tmp' has no member named 'main' From 562170681a3d0c8502892f8975f369c4b269fe1a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 06:02:38 -0400 Subject: [PATCH 197/216] link: cleanup lazy symbols We now only update one lazy symbol in flushModule. Updating the rest from updateDecl is TBD. --- src/Module.zig | 2 +- src/link.zig | 26 ++++++------ src/link/Coff.zig | 99 +++++++++++++++++++++---------------------- src/link/Elf.zig | 92 +++++++++++++++++++++------------------- src/link/MachO.zig | 102 ++++++++++++++++++++++----------------------- 5 files changed, 158 insertions(+), 163 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 9dab3edccd..70732369ca 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -555,7 +555,7 @@ pub const Decl = struct { _, pub fn init(oi: ?Index) OptionalIndex { - return oi orelse .none; + return @intToEnum(OptionalIndex, @enumToInt(oi orelse return .none)); } pub fn unwrap(oi: OptionalIndex) ?Index { diff --git a/src/link.zig b/src/link.zig index 7ca94f4f6d..45873fec26 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1106,23 +1106,21 @@ pub const File = struct { }; pub const LazySymbol = struct { - kind: enum { code, const_data }, + pub const Kind = enum { code, const_data }; + + kind: Kind, ty: Type, - pub const Context = struct { - mod: *Module, + pub fn initDecl(kind: Kind, decl: Module.Decl.OptionalIndex, mod: *Module) LazySymbol { + return .{ .kind = kind, .ty = if (decl.unwrap()) |decl_index| + mod.declPtr(decl_index).val.castTag(.ty).?.data + else + Type.anyerror }; + } - pub fn hash(ctx: @This(), sym: LazySymbol) u32 { - var hasher = std.hash.Wyhash.init(0); - std.hash.autoHash(&hasher, sym.kind); - sym.ty.hashWithHasher(&hasher, ctx.mod); - return @truncate(u32, hasher.final()); - } - - pub fn eql(ctx: @This(), lhs: LazySymbol, rhs: LazySymbol, _: usize) bool { - return lhs.kind == rhs.kind and lhs.ty.eql(rhs.ty, ctx.mod); - } - }; + pub fn getDecl(self: LazySymbol) Module.Decl.OptionalIndex { + return Module.Decl.OptionalIndex.init(self.ty.getOwnerDeclOrNull()); + } }; pub const C = @import("link/C.zig"); diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 3a94feb841..825afff36d 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -145,16 +145,11 @@ const Section = struct { free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, }; -const LazySymbolTable = std.ArrayHashMapUnmanaged( - link.File.LazySymbol, - LazySymbolMetadata, - link.File.LazySymbol.Context, - true, -); +const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); const LazySymbolMetadata = struct { - atom: Atom.Index, - section: u16, + text_atom: ?Atom.Index = null, + rdata_atom: ?Atom.Index = null, alignment: u32, }; @@ -1176,10 +1171,28 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); } -fn updateLazySymbol( +fn updateLazySymbol(self: *Coff, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void { + const mod = self.base.options.module.?; + if (metadata.text_atom) |atom| try self.updateLazySymbolAtom( + link.File.LazySymbol.initDecl(.code, decl, mod), + atom, + self.text_section_index.?, + metadata.alignment, + ); + if (metadata.rdata_atom) |atom| try self.updateLazySymbolAtom( + link.File.LazySymbol.initDecl(.const_data, decl, mod), + atom, + self.rdata_section_index.?, + metadata.alignment, + ); +} + +fn updateLazySymbolAtom( self: *Coff, - lazy_sym: link.File.LazySymbol, - lazy_metadata: LazySymbolMetadata, + sym: link.File.LazySymbol, + atom_index: Atom.Index, + section_index: u16, + required_alignment: u32, ) !void { const gpa = self.base.allocator; const mod = self.base.options.module.?; @@ -1188,16 +1201,15 @@ fn updateLazySymbol( defer code_buffer.deinit(); const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ - @tagName(lazy_sym.kind), - lazy_sym.ty.fmt(mod), + @tagName(sym.kind), + sym.ty.fmt(mod), }); defer gpa.free(name); - const atom_index = lazy_metadata.atom; const atom = self.getAtomPtr(atom_index); const local_sym_index = atom.getSymbolIndex().?; - const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl| + const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl| mod.declPtr(owner_decl).srcLoc() else Module.SrcLoc{ @@ -1205,14 +1217,9 @@ fn updateLazySymbol( .parent_decl_node = undefined, .lazy = .unneeded, }; - const res = try codegen.generateLazySymbol( - &self.base, - src, - lazy_sym, - &code_buffer, - .none, - .{ .parent_atom_index = local_sym_index }, - ); + const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{ + .parent_atom_index = local_sym_index, + }); const code = switch (res) { .ok => code_buffer.items, .fail => |em| { @@ -1221,11 +1228,10 @@ fn updateLazySymbol( }, }; - const required_alignment = lazy_metadata.alignment; const code_len = @intCast(u32, code.len); const symbol = atom.getSymbolPtr(self); try self.setSymbolName(symbol, name); - symbol.section_number = @intToEnum(coff.SectionNumber, lazy_metadata.section + 1); + symbol.section_number = @intToEnum(coff.SectionNumber, section_index + 1); symbol.type = .{ .complex_type = .NULL, .base_type = .NULL }; const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); @@ -1250,24 +1256,18 @@ fn updateLazySymbol( pub fn getOrCreateAtomForLazySymbol( self: *Coff, - lazy_sym: link.File.LazySymbol, + sym: link.File.LazySymbol, alignment: u32, ) !Atom.Index { - const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{ - .mod = self.base.options.module.?, - }); + const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl()); errdefer _ = self.lazy_syms.pop(); - if (!gop.found_existing) { - gop.value_ptr.* = .{ - .atom = try self.createAtom(), - .section = switch (lazy_sym.kind) { - .code => self.text_section_index.?, - .const_data => self.rdata_section_index.?, - }, - .alignment = alignment, - }; - } - return gop.value_ptr.atom; + if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment }; + const atom = switch (sym.kind) { + .code => &gop.value_ptr.text_atom, + .const_data => &gop.value_ptr.rdata_atom, + }; + if (atom.* == null) atom.* = try self.createAtom(); + return atom.*.?; } pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index { @@ -1600,17 +1600,13 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod sub_prog_node.activate(); defer sub_prog_node.end(); - { - var lazy_it = self.lazy_syms.iterator(); - while (lazy_it.next()) |lazy_entry| { - self.updateLazySymbol( - lazy_entry.key_ptr.*, - lazy_entry.value_ptr.*, - ) catch |err| switch (err) { - error.CodegenFail => return error.FlushFailure, - else => |e| return e, - }; - } + // Most lazy symbols can be updated when the corresponding decl is, + // so we only have to worry about the one without an associated decl. + if (self.lazy_syms.get(.none)) |metadata| { + self.updateLazySymbol(.none, metadata) catch |err| switch (err) { + error.CodegenFail => return error.FlushFailure, + else => |e| return e, + }; } const gpa = self.base.allocator; @@ -2489,6 +2485,7 @@ const Module = @import("../Module.zig"); const Object = @import("Coff/Object.zig"); const Relocation = @import("Coff/Relocation.zig"); const StringTable = @import("strtab.zig").StringTable; +const Type = @import("../type.zig").Type; const TypedValue = @import("../TypedValue.zig"); pub const base_tag: link.File.Tag = .coff; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 8079b09166..ec05f5895a 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -64,8 +64,8 @@ const Section = struct { }; const LazySymbolMetadata = struct { - atom: Atom.Index, - shdr: u16, + text_atom: ?Atom.Index = null, + rodata_atom: ?Atom.Index = null, alignment: u32, }; @@ -208,7 +208,7 @@ relocs: RelocTable = .{}, const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc)); const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); -const LazySymbolTable = std.ArrayHashMapUnmanaged(File.LazySymbol, LazySymbolMetadata, File.LazySymbol.Context, true); +const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); /// When allocating, the ideal_capacity is calculated by /// actual_capacity + (actual_capacity / ideal_factor) @@ -1065,17 +1065,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node sub_prog_node.activate(); defer sub_prog_node.end(); - { - var lazy_it = self.lazy_syms.iterator(); - while (lazy_it.next()) |lazy_entry| { - self.updateLazySymbol( - lazy_entry.key_ptr.*, - lazy_entry.value_ptr.*, - ) catch |err| switch (err) { - error.CodegenFail => return error.FlushFailure, - else => |e| return e, - }; - } + // Most lazy symbols can be updated when the corresponding decl is, + // so we only have to worry about the one without an associated decl. + if (self.lazy_syms.get(.none)) |metadata| { + self.updateLazySymbol(.none, metadata) catch |err| switch (err) { + error.CodegenFail => return error.FlushFailure, + else => |e| return e, + }; } // TODO This linker code currently assumes there is only 1 compilation unit and it @@ -2424,22 +2420,16 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void { } } -pub fn getOrCreateAtomForLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, alignment: u32) !Atom.Index { - const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{ - .mod = self.base.options.module.?, - }); +pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol, alignment: u32) !Atom.Index { + const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl()); errdefer _ = self.lazy_syms.pop(); - if (!gop.found_existing) { - gop.value_ptr.* = .{ - .atom = try self.createAtom(), - .shdr = switch (lazy_sym.kind) { - .code => self.text_section_index.?, - .const_data => self.rodata_section_index.?, - }, - .alignment = alignment, - }; - } - return gop.value_ptr.atom; + if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment }; + const atom = switch (sym.kind) { + .code => &gop.value_ptr.text_atom, + .const_data => &gop.value_ptr.rodata_atom, + }; + if (atom.* == null) atom.* = try self.createAtom(); + return atom.*.?; } pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index { @@ -2708,7 +2698,29 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); } -fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void { +fn updateLazySymbol(self: *Elf, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void { + const mod = self.base.options.module.?; + if (metadata.text_atom) |atom| try self.updateLazySymbolAtom( + File.LazySymbol.initDecl(.code, decl, mod), + atom, + self.text_section_index.?, + metadata.alignment, + ); + if (metadata.rodata_atom) |atom| try self.updateLazySymbolAtom( + File.LazySymbol.initDecl(.const_data, decl, mod), + atom, + self.rodata_section_index.?, + metadata.alignment, + ); +} + +fn updateLazySymbolAtom( + self: *Elf, + sym: File.LazySymbol, + atom_index: Atom.Index, + shdr_index: u16, + required_alignment: u32, +) !void { const gpa = self.base.allocator; const mod = self.base.options.module.?; @@ -2717,19 +2729,18 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy const name_str_index = blk: { const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ - @tagName(lazy_sym.kind), - lazy_sym.ty.fmt(mod), + @tagName(sym.kind), + sym.ty.fmt(mod), }); defer gpa.free(name); break :blk try self.shstrtab.insert(gpa, name); }; const name = self.shstrtab.get(name_str_index).?; - const atom_index = lazy_metadata.atom; const atom = self.getAtom(atom_index); const local_sym_index = atom.getSymbolIndex().?; - const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl| + const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl| mod.declPtr(owner_decl).srcLoc() else Module.SrcLoc{ @@ -2737,14 +2748,9 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy .parent_decl_node = undefined, .lazy = .unneeded, }; - const res = try codegen.generateLazySymbol( - &self.base, - src, - lazy_sym, - &code_buffer, - .none, - .{ .parent_atom_index = local_sym_index }, - ); + const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{ + .parent_atom_index = local_sym_index, + }); const code = switch (res) { .ok => code_buffer.items, .fail => |em| { @@ -2753,7 +2759,6 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy }, }; - const shdr_index = lazy_metadata.shdr; const phdr_index = self.sections.items(.phdr_index)[shdr_index]; const local_sym = atom.getSymbolPtr(self); local_sym.* = .{ @@ -2764,7 +2769,6 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy .st_value = 0, .st_size = 0, }; - const required_alignment = lazy_metadata.alignment; const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment); errdefer self.freeAtom(atom_index); log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr }); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2e1076cdf6..b0a05e4050 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -232,16 +232,11 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) { else => false, }; -const LazySymbolTable = std.ArrayHashMapUnmanaged( - link.File.LazySymbol, - LazySymbolMetadata, - link.File.LazySymbol.Context, - true, -); +const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); const LazySymbolMetadata = struct { - atom: Atom.Index, - section: u8, + text_atom: ?Atom.Index = null, + data_const_atom: ?Atom.Index = null, alignment: u32, }; @@ -513,17 +508,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No sub_prog_node.activate(); defer sub_prog_node.end(); - { - var lazy_it = self.lazy_syms.iterator(); - while (lazy_it.next()) |lazy_entry| { - self.updateLazySymbol( - lazy_entry.key_ptr.*, - lazy_entry.value_ptr.*, - ) catch |err| switch (err) { - error.CodegenFail => return error.FlushFailure, - else => |e| return e, - }; - } + // Most lazy symbols can be updated when the corresponding decl is, + // so we only have to worry about the one without an associated decl. + if (self.lazy_syms.get(.none)) |metadata| { + self.updateLazySymbol(.none, metadata) catch |err| switch (err) { + error.CodegenFail => return error.FlushFailure, + else => |e| return e, + }; } const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; @@ -2309,7 +2300,29 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); } -fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void { +fn updateLazySymbol(self: *MachO, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void { + const mod = self.base.options.module.?; + if (metadata.text_atom) |atom| try self.updateLazySymbolAtom( + File.LazySymbol.initDecl(.code, decl, mod), + atom, + self.text_section_index.?, + metadata.alignment, + ); + if (metadata.data_const_atom) |atom| try self.updateLazySymbolAtom( + File.LazySymbol.initDecl(.const_data, decl, mod), + atom, + self.data_const_section_index.?, + metadata.alignment, + ); +} + +fn updateLazySymbolAtom( + self: *MachO, + sym: File.LazySymbol, + atom_index: Atom.Index, + section_index: u8, + required_alignment: u32, +) !void { const gpa = self.base.allocator; const mod = self.base.options.module.?; @@ -2318,19 +2331,18 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy const name_str_index = blk: { const name = try std.fmt.allocPrint(gpa, "___lazy_{s}_{}", .{ - @tagName(lazy_sym.kind), - lazy_sym.ty.fmt(mod), + @tagName(sym.kind), + sym.ty.fmt(mod), }); defer gpa.free(name); break :blk try self.strtab.insert(gpa, name); }; const name = self.strtab.get(name_str_index).?; - const atom_index = lazy_metadata.atom; const atom = self.getAtomPtr(atom_index); const local_sym_index = atom.getSymbolIndex().?; - const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl| + const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl| mod.declPtr(owner_decl).srcLoc() else Module.SrcLoc{ @@ -2338,14 +2350,9 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy .parent_decl_node = undefined, .lazy = .unneeded, }; - const res = try codegen.generateLazySymbol( - &self.base, - src, - lazy_sym, - &code_buffer, - .none, - .{ .parent_atom_index = local_sym_index }, - ); + const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{ + .parent_atom_index = local_sym_index, + }); const code = switch (res) { .ok => code_buffer.items, .fail => |em| { @@ -2354,11 +2361,10 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy }, }; - const required_alignment = lazy_metadata.alignment; const symbol = atom.getSymbolPtr(self); symbol.n_strx = name_str_index; symbol.n_type = macho.N_SECT; - symbol.n_sect = lazy_metadata.section + 1; + symbol.n_sect = section_index + 1; symbol.n_desc = 0; const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment); @@ -2381,26 +2387,16 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy try self.writeAtom(atom_index, code); } -pub fn getOrCreateAtomForLazySymbol( - self: *MachO, - lazy_sym: File.LazySymbol, - alignment: u32, -) !Atom.Index { - const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{ - .mod = self.base.options.module.?, - }); +pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol, alignment: u32) !Atom.Index { + const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl()); errdefer _ = self.lazy_syms.pop(); - if (!gop.found_existing) { - gop.value_ptr.* = .{ - .atom = try self.createAtom(), - .section = switch (lazy_sym.kind) { - .code => self.text_section_index.?, - .const_data => self.data_const_section_index.?, - }, - .alignment = alignment, - }; - } - return gop.value_ptr.atom; + if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment }; + const atom = switch (sym.kind) { + .code => &gop.value_ptr.text_atom, + .const_data => &gop.value_ptr.data_const_atom, + }; + if (atom.* == null) atom.* = try self.createAtom(); + return atom.*.?; } pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { From 5900dc05804a4089eb7d1ccd8a36b4ade16c02e4 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 04:55:27 -0400 Subject: [PATCH 198/216] x86_64: fix typos --- src/arch/x86_64/CodeGen.zig | 4 ++-- src/print_air.zig | 1 + test/behavior/bugs/12776.zig | 1 - test/behavior/bugs/1442.zig | 1 - test/behavior/error.zig | 4 ---- test/behavior/struct.zig | 3 --- test/behavior/switch_prong_err_enum.zig | 1 - test/behavior/switch_prong_implicit_cast.zig | 1 - 8 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index a2d0d4da41..748f996032 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2528,7 +2528,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { const dst_lock = self.register_manager.lockReg(dst_reg); defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); - const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); + const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*)); const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); try self.asmRegisterMemory( .lea, @@ -5602,7 +5602,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { const rhs_mcv = try self.resolveInst(bin_op.rhs); const rhs_lock = switch (rhs_mcv) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + .register => |reg| self.register_manager.lockReg(reg), else => null, }; defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); diff --git a/src/print_air.zig b/src/print_air.zig index 803a0f2886..2493d234eb 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -804,6 +804,7 @@ const Writer = struct { var case_i: u32 = 0; try w.writeOperand(s, inst, 0, pl_op.operand); + if (w.skip_body) return s.writeAll(", ..."); const old_indent = w.indent; w.indent += 2; diff --git a/test/behavior/bugs/12776.zig b/test/behavior/bugs/12776.zig index f95709a2a4..1611fe27ee 100644 --- a/test/behavior/bugs/12776.zig +++ b/test/behavior/bugs/12776.zig @@ -31,7 +31,6 @@ const CPU = packed struct { test { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; var ram = try RAM.new(); diff --git a/test/behavior/bugs/1442.zig b/test/behavior/bugs/1442.zig index 5f788f6cef..f9bef6ec50 100644 --- a/test/behavior/bugs/1442.zig +++ b/test/behavior/bugs/1442.zig @@ -9,7 +9,6 @@ const Union = union(enum) { test "const error union field alignment" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO var union_or_err: anyerror!Union = Union{ .Color = 1234 }; try std.testing.expect((union_or_err catch unreachable).Color == 1234); diff --git a/test/behavior/error.zig b/test/behavior/error.zig index b1f77f33a8..0cd9be05ca 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -370,7 +370,6 @@ fn intLiteral(str: []const u8) !?i64 { } test "nested error union function call in optional unwrap" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -499,7 +498,6 @@ test "function pointer with return type that is error union with payload which i } test "return result loc as peer result loc in inferred error set function" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -531,7 +529,6 @@ test "return result loc as peer result loc in inferred error set function" { } test "error payload type is correctly resolved" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -665,7 +662,6 @@ test "coerce error set to the current inferred error set" { } test "error union payload is properly aligned" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 37b24a1ed5..1dcfce53dd 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1116,7 +1116,6 @@ test "for loop over pointers to struct, getting field from struct pointer" { } test "anon init through error unions and optionals" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -1162,7 +1161,6 @@ test "anon init through optional" { } test "anon init through error union" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -1182,7 +1180,6 @@ test "anon init through error union" { } test "typed init through error unions and optionals" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/switch_prong_err_enum.zig b/test/behavior/switch_prong_err_enum.zig index ddcc76634e..15d366d04f 100644 --- a/test/behavior/switch_prong_err_enum.zig +++ b/test/behavior/switch_prong_err_enum.zig @@ -23,7 +23,6 @@ fn doThing(form_id: u64) anyerror!FormValue { test "switch prong returns error enum" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO switch (doThing(17) catch unreachable) { diff --git a/test/behavior/switch_prong_implicit_cast.zig b/test/behavior/switch_prong_implicit_cast.zig index 26ec57676b..54107bb6bd 100644 --- a/test/behavior/switch_prong_implicit_cast.zig +++ b/test/behavior/switch_prong_implicit_cast.zig @@ -17,7 +17,6 @@ fn foo(id: u64) !FormValue { test "switch prong implicit cast" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const result = switch (foo(2) catch unreachable) { From c0e9b849974cdbc93053919f54f0cf3830243572 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 3 Apr 2023 18:30:48 +0200 Subject: [PATCH 199/216] elf: preallocate offsets for PT_PHDR and PT_LOAD (empty) segment Otherwise, we will be using `undefined` as the offset to allocate remaining phdrs and shdrs. --- src/link/Elf.zig | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ec05f5895a..74a538b8cc 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -110,7 +110,7 @@ program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, phdr_table_index: ?u16 = null, /// The index into the program headers of the PT_LOAD program header containing the phdr /// Most linkers would merge this with phdr_load_ro_index, -/// but hot swap means we can't ensure they are consecutive. +/// but incremental linking means we can't ensure they are consecutive. phdr_table_load_index: ?u16 = null, /// The index into the program headers of a PT_LOAD program header with Read and Execute flags phdr_load_re_index: ?u16 = null, @@ -473,18 +473,19 @@ pub fn populateMissingMetadata(self: *Elf) !void { var new_phdr_table_index: ?u16 = null; if (self.phdr_table_index == null) { new_phdr_table_index = @intCast(u16, self.program_headers.items.len); - const phalign: u16 = switch (self.ptr_width) { + const p_align: u16 = switch (self.ptr_width) { .p32 => @alignOf(elf.Elf32_Phdr), .p64 => @alignOf(elf.Elf64_Phdr), }; + const off = self.findFreeSpace(1, p_align); try self.program_headers.append(gpa, .{ .p_type = elf.PT_PHDR, - .p_offset = undefined, - .p_filesz = undefined, - .p_vaddr = undefined, - .p_paddr = undefined, - .p_memsz = undefined, - .p_align = phalign, + .p_offset = off, + .p_filesz = 1, + .p_vaddr = 0, + .p_paddr = 0, + .p_memsz = 0, + .p_align = p_align, .p_flags = elf.PF_R, }); self.phdr_table_dirty = true; @@ -494,14 +495,18 @@ pub fn populateMissingMetadata(self: *Elf) !void { self.phdr_table_load_index = @intCast(u16, self.program_headers.items.len); // TODO Same as for GOT const phdr_addr: u64 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x1000000 else 0x1000; + const p_align = self.page_size; + const off = self.findFreeSpace(1, p_align); + const file_size: u32 = 1; + log.debug("found PT_LOAD free space 0x{x} to 0x{x}", .{ off, off + file_size }); try self.program_headers.append(gpa, .{ .p_type = elf.PT_LOAD, - .p_offset = undefined, - .p_filesz = undefined, + .p_offset = off, + .p_filesz = file_size, .p_vaddr = phdr_addr, .p_paddr = phdr_addr, - .p_memsz = undefined, - .p_align = self.page_size, + .p_memsz = file_size, + .p_align = p_align, .p_flags = elf.PF_R, }); self.phdr_table_dirty = true; From 9fd460821f992c51b35a54ba93562af93ac478f6 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 13:55:20 -0400 Subject: [PATCH 200/216] elf: cleanup phdr tracking Since one of the program header entries is now the program header table itself, we can avoid tracking it explicitly and just track it as yet another program segment. --- src/link/Elf.zig | 285 +++++++++++++++++++++-------------------------- 1 file changed, 128 insertions(+), 157 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 74a538b8cc..7a3a0b0fdd 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -391,17 +391,6 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { const end = start + padToIdeal(size); - if (self.phdr_table_index) |index| { - const off = self.program_headers.items[index].p_offset; - const phdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Phdr) else @sizeOf(elf.Elf64_Phdr); - const tight_size = self.program_headers.items.len * phdr_size; - const increased_size = padToIdeal(tight_size); - const test_end = off + increased_size; - if (end > off and start < test_end) { - return test_end; - } - } - if (self.shdr_table_offset) |off| { const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); const tight_size = self.sections.slice().len * shdr_size; @@ -433,10 +422,6 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { if (start == 0) return 0; var min_pos: u64 = std.math.maxInt(u64); - if (self.phdr_table_index) |index| { - const off = self.program_headers.items[index].p_offset; - if (off > start and off < min_pos) min_pos = off; - } if (self.shdr_table_offset) |off| { if (off > start and off < min_pos) min_pos = off; } @@ -469,151 +454,133 @@ pub fn populateMissingMetadata(self: *Elf) !void { }; const ptr_size: u8 = self.ptrWidthBytes(); - { // Program Headers - var new_phdr_table_index: ?u16 = null; - if (self.phdr_table_index == null) { - new_phdr_table_index = @intCast(u16, self.program_headers.items.len); - const p_align: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Phdr), - .p64 => @alignOf(elf.Elf64_Phdr), - }; - const off = self.findFreeSpace(1, p_align); - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_PHDR, - .p_offset = off, - .p_filesz = 1, - .p_vaddr = 0, - .p_paddr = 0, - .p_memsz = 0, - .p_align = p_align, - .p_flags = elf.PF_R, - }); - self.phdr_table_dirty = true; - } + if (self.phdr_table_index == null) { + self.phdr_table_index = @intCast(u16, self.program_headers.items.len); + const p_align: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Phdr), + .p64 => @alignOf(elf.Elf64_Phdr), + }; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_PHDR, + .p_offset = 0, + .p_filesz = 0, + .p_vaddr = 0, + .p_paddr = 0, + .p_memsz = 0, + .p_align = p_align, + .p_flags = elf.PF_R, + }); + self.phdr_table_dirty = true; + } - if (self.phdr_table_load_index == null) { - self.phdr_table_load_index = @intCast(u16, self.program_headers.items.len); - // TODO Same as for GOT - const phdr_addr: u64 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x1000000 else 0x1000; - const p_align = self.page_size; - const off = self.findFreeSpace(1, p_align); - const file_size: u32 = 1; - log.debug("found PT_LOAD free space 0x{x} to 0x{x}", .{ off, off + file_size }); - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = phdr_addr, - .p_paddr = phdr_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R, - }); - self.phdr_table_dirty = true; - } + if (self.phdr_table_load_index == null) { + self.phdr_table_load_index = @intCast(u16, self.program_headers.items.len); + // TODO Same as for GOT + const phdr_addr: u64 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x1000000 else 0x1000; + const p_align = self.page_size; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = 0, + .p_filesz = 0, + .p_vaddr = phdr_addr, + .p_paddr = phdr_addr, + .p_memsz = 0, + .p_align = p_align, + .p_flags = elf.PF_R, + }); + self.phdr_table_dirty = true; + } - if (self.phdr_load_re_index == null) { - self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len); - const file_size = self.base.options.program_code_size_hint; - const p_align = self.page_size; - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size }); - const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = entry_addr, - .p_paddr = entry_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_X | elf.PF_R | elf.PF_W, - }); - self.entry_addr = null; - self.phdr_table_dirty = true; - } + if (self.phdr_load_re_index == null) { + self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len); + const file_size = self.base.options.program_code_size_hint; + const p_align = self.page_size; + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size }); + const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = entry_addr, + .p_paddr = entry_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_X | elf.PF_R | elf.PF_W, + }); + self.entry_addr = null; + self.phdr_table_dirty = true; + } - if (self.phdr_got_index == null) { - self.phdr_got_index = @intCast(u16, self.program_headers.items.len); - const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; - // We really only need ptr alignment but since we are using PROGBITS, linux requires - // page align. - const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD GOT free space 0x{x} to 0x{x}", .{ off, off + file_size }); - // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. - // we'll need to re-use that function anyway, in case the GOT grows and overlaps something - // else in virtual memory. - const got_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x4000000 else 0x8000; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = got_addr, - .p_paddr = got_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R | elf.PF_W, - }); - self.phdr_table_dirty = true; - } + if (self.phdr_got_index == null) { + self.phdr_got_index = @intCast(u16, self.program_headers.items.len); + const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; + // We really only need ptr alignment but since we are using PROGBITS, linux requires + // page align. + const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD GOT free space 0x{x} to 0x{x}", .{ off, off + file_size }); + // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. + // we'll need to re-use that function anyway, in case the GOT grows and overlaps something + // else in virtual memory. + const got_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x4000000 else 0x8000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = got_addr, + .p_paddr = got_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R | elf.PF_W, + }); + self.phdr_table_dirty = true; + } - if (self.phdr_load_ro_index == null) { - self.phdr_load_ro_index = @intCast(u16, self.program_headers.items.len); - // TODO Find a hint about how much data need to be in rodata ? - const file_size = 1024; - // Same reason as for GOT - const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}", .{ off, off + file_size }); - // TODO Same as for GOT - const rodata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0xc000000 else 0xa000; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = rodata_addr, - .p_paddr = rodata_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R | elf.PF_W, - }); - self.phdr_table_dirty = true; - } + if (self.phdr_load_ro_index == null) { + self.phdr_load_ro_index = @intCast(u16, self.program_headers.items.len); + // TODO Find a hint about how much data need to be in rodata ? + const file_size = 1024; + // Same reason as for GOT + const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}", .{ off, off + file_size }); + // TODO Same as for GOT + const rodata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0xc000000 else 0xa000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = rodata_addr, + .p_paddr = rodata_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R | elf.PF_W, + }); + self.phdr_table_dirty = true; + } - if (self.phdr_load_rw_index == null) { - self.phdr_load_rw_index = @intCast(u16, self.program_headers.items.len); - // TODO Find a hint about how much data need to be in data ? - const file_size = 1024; - // Same reason as for GOT - const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}", .{ off, off + file_size }); - // TODO Same as for GOT - const rwdata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x10000000 else 0xc000; - try self.program_headers.append(gpa, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = rwdata_addr, - .p_paddr = rwdata_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R | elf.PF_W, - }); - self.phdr_table_dirty = true; - } - - if (new_phdr_table_index) |index| { - const phsize: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Phdr), - .p64 => @sizeOf(elf.Elf64_Phdr), - }; - const phdr_table = &self.program_headers.items[index]; - phdr_table.p_offset = self.findFreeSpace(self.program_headers.items.len * phsize, @intCast(u32, phdr_table.p_align)); - self.phdr_table_index = index; - self.phdr_table_dirty = true; - } + if (self.phdr_load_rw_index == null) { + self.phdr_load_rw_index = @intCast(u16, self.program_headers.items.len); + // TODO Find a hint about how much data need to be in data ? + const file_size = 1024; + // Same reason as for GOT + const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}", .{ off, off + file_size }); + // TODO Same as for GOT + const rwdata_addr: u32 = if (self.base.options.target.cpu.arch.ptrBitWidth() >= 32) 0x10000000 else 0xc000; + try self.program_headers.append(gpa, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = rwdata_addr, + .p_paddr = rwdata_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R | elf.PF_W, + }); + self.phdr_table_dirty = true; } if (self.shstrtab_index == null) { @@ -1186,8 +1153,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node const needed_size = self.program_headers.items.len * phsize; if (needed_size > allocated_size) { - self.phdr_table_index = null; // free the space - defer self.phdr_table_index = phdr_table_index; + phdr_table.p_offset = 0; // free the space phdr_table.p_offset = self.findFreeSpace(needed_size, @intCast(u32, phdr_table.p_align)); } @@ -1227,6 +1193,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); }, } + + // We don't actually care if the phdr load section overlaps, only the phdr section matters. + phdr_table_load.p_offset = 0; + phdr_table_load.p_filesz = 0; + self.phdr_table_dirty = false; } From 821eb595f4bd65d003a2cb499c7953f4f57a4c4a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 14:14:55 -0400 Subject: [PATCH 201/216] x86_64: implement cmp_lt_errors_len --- src/arch/x86_64/CodeGen.zig | 63 ++++++++++++++++++++++++++++++++++--- src/codegen.zig | 10 ++++-- test/behavior/cast.zig | 1 - 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 748f996032..8a3e0852a2 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5650,9 +5650,62 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; - const operand = try self.resolveInst(un_op); - _ = operand; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const addr_reg = try self.register_manager.allocReg(null, gp); + const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); + defer self.register_manager.unlockReg(addr_lock); + + if (self.bin_file.cast(link.File.Elf)) |elf_file| { + const atom_index = try elf_file.getOrCreateAtomForLazySymbol( + .{ .kind = .const_data, .ty = Type.anyerror }, + 4, // dword alignment + ); + const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file); + try self.asmRegisterMemory(.mov, addr_reg.to64(), Memory.sib(.qword, .{ + .base = .ds, + .disp = @intCast(i32, got_addr), + })); + } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { + const atom_index = try coff_file.getOrCreateAtomForLazySymbol( + .{ .kind = .const_data, .ty = Type.anyerror }, + 4, // dword alignment + ); + const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; + try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ + .type = .got, + .sym_index = sym_index, + } }); + } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { + const atom_index = try macho_file.getOrCreateAtomForLazySymbol( + .{ .kind = .const_data, .ty = Type.anyerror }, + 4, // dword alignment + ); + const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; + try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ + .type = .got, + .sym_index = sym_index, + } }); + } else { + return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); + } + + try self.spillEflagsIfOccupied(); + self.eflags_inst = inst; + + const op_ty = self.air.typeOf(un_op); + const op_abi_size = @intCast(u32, op_ty.abiSize(self.target.*)); + const op_mcv = try self.resolveInst(un_op); + const dst_reg = switch (op_mcv) { + .register => |reg| reg, + else => try self.copyToTmpRegister(op_ty, op_mcv), + }; + try self.asmRegisterMemory( + .cmp, + registerAlias(dst_reg, op_abi_size), + Memory.sib(Memory.PtrSize.fromSize(op_abi_size), .{ .base = addr_reg }), + ); + break :result .{ .eflags = .b }; + }; return self.finishAir(inst, result, .{ un_op, .none, .none }); } @@ -8027,12 +8080,12 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { try self.asmRegisterMemory(.mov, start_reg.to32(), Memory.sib(.dword, .{ .base = addr_reg.to64(), .scale_index = .{ .scale = 4, .index = err_reg.to64() }, - .disp = 0, + .disp = 4, })); try self.asmRegisterMemory(.mov, end_reg.to32(), Memory.sib(.dword, .{ .base = addr_reg.to64(), .scale_index = .{ .scale = 4, .index = err_reg.to64() }, - .disp = 4, + .disp = 8, })); try self.asmRegisterRegister(.sub, end_reg.to32(), start_reg.to32()); try self.asmRegisterMemory(.lea, start_reg.to64(), Memory.sib(.byte, .{ diff --git a/src/codegen.zig b/src/codegen.zig index 67ada2fedd..57c33ad524 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -124,13 +124,17 @@ pub fn generateLazySymbol( if (lazy_sym.kind == .const_data and lazy_sym.ty.isAnyError()) { const err_names = mod.error_name_list.items; - try code.resize(err_names.len * 4); - for (err_names, 0..) |err_name, index| { - mem.writeInt(u32, code.items[index * 4 ..][0..4], @intCast(u32, code.items.len), endian); + mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian); + var offset = code.items.len; + try code.resize((1 + err_names.len + 1) * 4); + for (err_names) |err_name| { + mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian); + offset += 4; try code.ensureUnusedCapacity(err_name.len + 1); code.appendSliceAssumeCapacity(err_name); code.appendAssumeCapacity(0); } + mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian); return Result.ok; } else return .{ .fail = try ErrorMsg.create( bin_file.allocator, diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 470b17e0b6..8027515730 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -402,7 +402,6 @@ test "expected [*c]const u8, found [*:0]const u8" { test "explicit cast from integer to error type" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO From c91929090db337810aa3b55f9bd26f5fd0af4fff Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 3 Apr 2023 14:17:00 -0400 Subject: [PATCH 202/216] start: disable extra start logic on various x86_64 subtargets --- lib/std/start.zig | 1 + test/cases/aarch64-macos/hello_world_with_updates.0.zig | 2 +- test/cases/x86_64-linux/hello_world_with_updates.0.zig | 5 ++++- test/cases/x86_64-macos/hello_world_with_updates.0.zig | 2 +- test/cases/x86_64-windows/hello_world_with_updates.0.zig | 4 +++- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/std/start.zig b/lib/std/start.zig index e79dd1b9a7..1b686e43f5 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -19,6 +19,7 @@ const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start"; // self-hosted is capable enough to handle all of the real start.zig logic. pub const simplified_logic = builtin.zig_backend == .stage2_wasm or + (builtin.zig_backend == .stage2_x86_64 and (builtin.link_libc or builtin.os.tag == .plan9)) or builtin.zig_backend == .stage2_x86 or builtin.zig_backend == .stage2_aarch64 or builtin.zig_backend == .stage2_arm or diff --git a/test/cases/aarch64-macos/hello_world_with_updates.0.zig b/test/cases/aarch64-macos/hello_world_with_updates.0.zig index 9f516ff139..90aa14ab65 100644 --- a/test/cases/aarch64-macos/hello_world_with_updates.0.zig +++ b/test/cases/aarch64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=aarch64-macos // -// :109:9: error: root struct of file 'tmp' has no member named 'main' +// :110:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-linux/hello_world_with_updates.0.zig b/test/cases/x86_64-linux/hello_world_with_updates.0.zig index 40abdd6c1f..e498eacf93 100644 --- a/test/cases/x86_64-linux/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-linux/hello_world_with_updates.0.zig @@ -2,4 +2,7 @@ // output_mode=Exe // target=x86_64-linux // -// :109:9: error: root struct of file 'tmp' has no member named 'main' +// :604:45: error: root struct of file 'tmp' has no member named 'main' +// :553:12: note: called from here +// :503:36: note: called from here +// :466:17: note: called from here diff --git a/test/cases/x86_64-macos/hello_world_with_updates.0.zig b/test/cases/x86_64-macos/hello_world_with_updates.0.zig index e0680c81d7..d91bd9dc91 100644 --- a/test/cases/x86_64-macos/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-macos // -// :109:9: error: root struct of file 'tmp' has no member named 'main' +// :110:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-windows/hello_world_with_updates.0.zig b/test/cases/x86_64-windows/hello_world_with_updates.0.zig index 04e1d4cfad..320057b86e 100644 --- a/test/cases/x86_64-windows/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-windows/hello_world_with_updates.0.zig @@ -2,4 +2,6 @@ // output_mode=Exe // target=x86_64-windows // -// :130:9: error: root struct of file 'tmp' has no member named 'main' +// :604:45: error: root struct of file 'tmp' has no member named 'main' +// :553:12: note: called from here +// :389:65: note: called from here From 771d07268f7ecc9535ad6fbb8448c76581bf5188 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 25 Mar 2023 17:15:41 +0000 Subject: [PATCH 203/216] std: freebsd MAP* constants update, MAP_ALIGNED_SUPER and the MAP_ALIGNED macro. --- lib/std/c/freebsd.zig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index a76f8a4871..ccf9153f92 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -622,6 +622,11 @@ pub const MAP = struct { pub const NOCORE = 0x00020000; pub const PREFAULT_READ = 0x00040000; pub const @"32BIT" = 0x00080000; + + pub fn ALIGNED(alignment: u32) u32 { + return alignment << 24; + } + pub const ALIGNED_SUPER = ALIGNED(1); }; pub const MSF = struct { From 49b56f88b92eb0f0e66e7cfa329392c918c1777e Mon Sep 17 00:00:00 2001 From: Ganesan Rajagopal Date: Tue, 4 Apr 2023 15:41:25 +0530 Subject: [PATCH 204/216] GPA: Catch invalid frees * GPA: Catch invalid frees Fix #14791: Catch cases where an invalid slice is passed to free(). This was silently ignored before but now logs an error. This change uses a AutoHashMap to keep track of the sizes which seems to be an overkill but seems like the easiest way to catch these errors. * GPA: Add wrong alignment checks to free/resize Implement @Inkryption's suggestion to catch free/resize with the wrong alignment. I also changed the naming to match large allocations. --- lib/std/heap/general_purpose_allocator.zig | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/lib/std/heap/general_purpose_allocator.zig b/lib/std/heap/general_purpose_allocator.zig index fed6eba47b..f8bd1fe1ca 100644 --- a/lib/std/heap/general_purpose_allocator.zig +++ b/lib/std/heap/general_purpose_allocator.zig @@ -160,6 +160,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { backing_allocator: Allocator = std.heap.page_allocator, buckets: [small_bucket_count]?*BucketHeader = [1]?*BucketHeader{null} ** small_bucket_count, large_allocations: LargeAllocTable = .{}, + small_allocations: if (config.safety) SmallAllocTable else void = if (config.safety) .{} else {}, empty_buckets: if (config.retain_metadata) ?*BucketHeader else void = if (config.retain_metadata) null else {}, @@ -194,6 +195,11 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { const small_bucket_count = math.log2(page_size); const largest_bucket_object_size = 1 << (small_bucket_count - 1); + const SmallAlloc = struct { + requested_size: usize, + log2_ptr_align: u8, + }; + const LargeAlloc = struct { bytes: []u8, requested_size: if (config.enable_memory_limit) usize else void, @@ -227,6 +233,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { } }; const LargeAllocTable = std.AutoHashMapUnmanaged(usize, LargeAlloc); + const SmallAllocTable = std.AutoHashMapUnmanaged(usize, SmallAlloc); // Bucket: In memory, in order: // * BucketHeader @@ -430,6 +437,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { self.freeRetainedMetadata(); } self.large_allocations.deinit(self.backing_allocator); + if (config.safety) { + self.small_allocations.deinit(self.backing_allocator); + } self.* = undefined; return leaks; } @@ -706,6 +716,34 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { } // Definitely an in-use small alloc now. + if (config.safety) { + const entry = self.small_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse + @panic("Invalid free"); + if (old_mem.len != entry.value_ptr.requested_size or log2_old_align != entry.value_ptr.log2_ptr_align) { + var addresses: [stack_n]usize = [1]usize{0} ** stack_n; + var free_stack_trace = StackTrace{ + .instruction_addresses = &addresses, + .index = 0, + }; + std.debug.captureStackTrace(ret_addr, &free_stack_trace); + if (old_mem.len != entry.value_ptr.requested_size) { + log.err("Allocation size {d} bytes does not match resize size {d}. Allocation: {} Resize: {}", .{ + entry.value_ptr.requested_size, + old_mem.len, + bucketStackTrace(bucket, size_class, slot_index, .alloc), + free_stack_trace, + }); + } + if (log2_old_align != entry.value_ptr.log2_ptr_align) { + log.err("Allocation alignment {d} does not match resize alignment {d}. Allocation: {} Resize: {}", .{ + @as(usize, 1) << @intCast(math.Log2Int(usize), entry.value_ptr.log2_ptr_align), + @as(usize, 1) << @intCast(math.Log2Int(usize), log2_old_align), + bucketStackTrace(bucket, size_class, slot_index, .alloc), + free_stack_trace, + }); + } + } + } const prev_req_bytes = self.total_requested_bytes; if (config.enable_memory_limit) { const new_req_bytes = prev_req_bytes + new_size - old_mem.len; @@ -726,6 +764,10 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { old_mem.len, old_mem.ptr, new_size, }); } + if (config.safety) { + const entry = self.small_allocations.getEntry(@ptrToInt(old_mem.ptr)).?; + entry.value_ptr.requested_size = new_size; + } return true; } @@ -796,6 +838,35 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { } // Definitely an in-use small alloc now. + if (config.safety) { + const entry = self.small_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse + @panic("Invalid free"); + if (old_mem.len != entry.value_ptr.requested_size or log2_old_align != entry.value_ptr.log2_ptr_align) { + var addresses: [stack_n]usize = [1]usize{0} ** stack_n; + var free_stack_trace = StackTrace{ + .instruction_addresses = &addresses, + .index = 0, + }; + std.debug.captureStackTrace(ret_addr, &free_stack_trace); + if (old_mem.len != entry.value_ptr.requested_size) { + log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {} Free: {}", .{ + entry.value_ptr.requested_size, + old_mem.len, + bucketStackTrace(bucket, size_class, slot_index, .alloc), + free_stack_trace, + }); + } + if (log2_old_align != entry.value_ptr.log2_ptr_align) { + log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {} Free: {}", .{ + @as(usize, 1) << @intCast(math.Log2Int(usize), entry.value_ptr.log2_ptr_align), + @as(usize, 1) << @intCast(math.Log2Int(usize), log2_old_align), + bucketStackTrace(bucket, size_class, slot_index, .alloc), + free_stack_trace, + }); + } + } + } + if (config.enable_memory_limit) { self.total_requested_bytes -= old_mem.len; } @@ -840,6 +911,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { } else { @memset(old_mem.ptr, undefined, old_mem.len); } + if (config.safety) { + assert(self.small_allocations.remove(@ptrToInt(old_mem.ptr))); + } if (config.verbose_log) { log.info("small free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr }); } @@ -903,8 +977,16 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { return slice.ptr; } + if (config.safety) { + try self.small_allocations.ensureUnusedCapacity(self.backing_allocator, 1); + } const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); const ptr = try self.allocSlot(new_size_class, ret_addr); + if (config.safety) { + const gop = self.small_allocations.getOrPutAssumeCapacity(@ptrToInt(ptr)); + gop.value_ptr.requested_size = len; + gop.value_ptr.log2_ptr_align = log2_ptr_align; + } if (config.verbose_log) { log.info("small alloc {d} bytes at {*}", .{ len, ptr }); } From 3a8362e751d210f1cecfce7c33cae2e582bd4b94 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 4 Apr 2023 09:32:26 +0200 Subject: [PATCH 205/216] macho+zld: refactor how we resolve dyld_stub_binder symbol --- src/link/MachO/zld.zig | 63 ++++++++++++------------------------------ 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 47dd4dd54f..475b3396fd 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -590,9 +590,9 @@ pub const Zld = struct { } fn createDyldStubBinderGotAtom(self: *Zld) !void { - const sym_index = self.dyld_stub_binder_index orelse return; const gpa = self.gpa; - const target = SymbolWithLoc{ .sym_index = sym_index }; + const global_index = self.dyld_stub_binder_index orelse return; + const target = self.globals.items[global_index]; const atom_index = try self.createGotAtom(); const got_index = @intCast(u32, self.got_entries.items.len); try self.got_entries.append(gpa, .{ @@ -661,7 +661,8 @@ pub const Zld = struct { break :blk sym.n_value; }; const dyld_stub_binder_got_addr = blk: { - const index = self.got_table.get(.{ .sym_index = self.dyld_stub_binder_index.? }).?; + const sym_loc = self.globals.items[self.dyld_stub_binder_index.?]; + const index = self.got_table.get(sym_loc).?; const entry = self.got_entries.items[index]; break :blk entry.getAtomSymbol(self).n_value; }; @@ -932,12 +933,12 @@ pub const Zld = struct { } } - fn forceSymbolDefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void { + fn addUndefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void { const sym_index = try self.allocateSymbol(); const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; const sym = self.getSymbolPtr(sym_loc); sym.n_strx = try self.strtab.insert(self.gpa, name); - sym.n_type = macho.N_UNDF | macho.N_EXT; + sym.n_type = macho.N_UNDF; const global_index = try self.addGlobal(sym_loc); try resolver.table.putNoClobber(name, global_index); try resolver.unresolved.putNoClobber(global_index, {}); @@ -949,12 +950,12 @@ pub const Zld = struct { // on the linker line. if (self.options.output_mode == .Exe) { const entry_name = self.options.entry orelse load_commands.default_entry_point; - try self.forceSymbolDefined(entry_name, resolver); + try self.addUndefined(entry_name, resolver); } // Force resolution of any symbols requested by the user. for (self.options.force_undefined_symbols.keys()) |sym_name| { - try self.forceSymbolDefined(sym_name, resolver); + try self.addUndefined(sym_name, resolver); } for (self.objects.items, 0..) |_, object_id| { @@ -962,8 +963,17 @@ pub const Zld = struct { } try self.resolveSymbolsInArchives(resolver); - try self.resolveDyldStubBinder(resolver); + + // Finally, force resolution of dyld_stub_binder if there are imports + // requested. + if (resolver.unresolved.count() > 0) { + try self.addUndefined("dyld_stub_binder", resolver); + } + try self.resolveSymbolsInDylibs(resolver); + + self.dyld_stub_binder_index = resolver.table.get("dyld_stub_binder"); + try self.createMhExecuteHeaderSymbol(resolver); try self.createDsoHandleSymbol(resolver); try self.resolveSymbolsAtLoading(resolver); @@ -1241,43 +1251,6 @@ pub const Zld = struct { global.* = sym_loc; } - fn resolveDyldStubBinder(self: *Zld, resolver: *SymbolResolver) !void { - if (self.dyld_stub_binder_index != null) return; - if (resolver.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports - - const gpa = self.gpa; - const sym_name = "dyld_stub_binder"; - const sym_index = try self.allocateSymbol(); - const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; - const sym = self.getSymbolPtr(sym_loc); - sym.n_strx = try self.strtab.insert(gpa, sym_name); - sym.n_type = macho.N_UNDF; - - const global = SymbolWithLoc{ .sym_index = sym_index }; - try self.globals.append(gpa, global); - - for (self.dylibs.items, 0..) |dylib, id| { - if (!dylib.symbols.contains(sym_name)) continue; - - const dylib_id = @intCast(u16, id); - if (!self.referenced_dylibs.contains(dylib_id)) { - try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {}); - } - - const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; - sym.n_type |= macho.N_EXT; - sym.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; - self.dyld_stub_binder_index = sym_index; - - break; - } - - if (self.dyld_stub_binder_index == null) { - log.err("undefined reference to symbol '{s}'", .{sym_name}); - return error.UndefinedSymbolReference; - } - } - pub fn deinit(self: *Zld) void { const gpa = self.gpa; From 83b7dbe52f75161a2ac6f5d8f39b275fd9473c15 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Tue, 4 Apr 2023 11:39:02 -0400 Subject: [PATCH 206/216] cases: disable failing incremental tests Enabling start.zig logic breaks incremental compilation See #15174 --- .../cases/aarch64-macos/hello_world_with_updates.0.zig | 2 +- test/cases/x86_64-linux/hello_world_with_updates.0.zig | 8 ++++---- test/cases/x86_64-macos/hello_world_with_updates.0.zig | 2 +- .../x86_64-windows/hello_world_with_updates.0.zig | 6 +++--- test/src/Cases.zig | 10 ++++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/test/cases/aarch64-macos/hello_world_with_updates.0.zig b/test/cases/aarch64-macos/hello_world_with_updates.0.zig index 90aa14ab65..f939a7fa71 100644 --- a/test/cases/aarch64-macos/hello_world_with_updates.0.zig +++ b/test/cases/aarch64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=aarch64-macos // -// :110:9: error: root struct of file 'tmp' has no member named 'main' +// :?:?: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-linux/hello_world_with_updates.0.zig b/test/cases/x86_64-linux/hello_world_with_updates.0.zig index e498eacf93..c330234fdb 100644 --- a/test/cases/x86_64-linux/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-linux/hello_world_with_updates.0.zig @@ -2,7 +2,7 @@ // output_mode=Exe // target=x86_64-linux // -// :604:45: error: root struct of file 'tmp' has no member named 'main' -// :553:12: note: called from here -// :503:36: note: called from here -// :466:17: note: called from here +// :?:?: error: root struct of file 'tmp' has no member named 'main' +// :?:?: note: called from here +// :?:?: note: called from here +// :?:?: note: called from here diff --git a/test/cases/x86_64-macos/hello_world_with_updates.0.zig b/test/cases/x86_64-macos/hello_world_with_updates.0.zig index d91bd9dc91..7fc13a4fa5 100644 --- a/test/cases/x86_64-macos/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-macos // -// :110:9: error: root struct of file 'tmp' has no member named 'main' +// :?:?: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-windows/hello_world_with_updates.0.zig b/test/cases/x86_64-windows/hello_world_with_updates.0.zig index 320057b86e..d322de2d1b 100644 --- a/test/cases/x86_64-windows/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-windows/hello_world_with_updates.0.zig @@ -2,6 +2,6 @@ // output_mode=Exe // target=x86_64-windows // -// :604:45: error: root struct of file 'tmp' has no member named 'main' -// :553:12: note: called from here -// :389:65: note: called from here +// :?:?: error: root struct of file 'tmp' has no member named 'main' +// :?:?: note: called from here +// :?:?: note: called from here diff --git a/test/src/Cases.zig b/test/src/Cases.zig index c3a4c1df47..890f4f6f89 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -1045,8 +1045,7 @@ pub fn main() !void { var ctx = Cases.init(gpa, arena); var test_it = TestIterator{ .filenames = filenames.items }; - while (test_it.next()) |maybe_batch| { - const batch = maybe_batch orelse break; + while (try test_it.next()) |batch| { const strategy: TestStrategy = if (batch.len > 1) .incremental else .independent; var cases = std.ArrayList(usize).init(arena); @@ -1084,6 +1083,11 @@ pub fn main() !void { for (cases.items) |case_index| { const case = &ctx.cases.items[case_index]; + if (strategy == .incremental and case.backend == .stage2 and case.target.getCpuArch() == .x86_64 and !case.link_libc and case.target.getOsTag() != .plan9) { + // https://github.com/ziglang/zig/issues/15174 + continue; + } + switch (manifest.type) { .compile => { case.addCompile(src); @@ -1115,8 +1119,6 @@ pub fn main() !void { } } } - } else |err| { - return err; } return runCases(&ctx, zig_exe_path); From f372995e1ef2a6dda4bc30eeaf817b0d947704e7 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 4 Apr 2023 10:30:03 +0200 Subject: [PATCH 207/216] macho: refactor adding GOT and stub entries Don't special-case resolving of `dyld_stub_binder`. --- src/link/MachO.zig | 429 +++++++++++---------------------------------- 1 file changed, 99 insertions(+), 330 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index b0a05e4050..7192ce58e1 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -142,7 +142,7 @@ data_section_index: ?u8 = null, locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, resolver: std.StringHashMapUnmanaged(u32) = .{}, -unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, +unresolved: std.AutoArrayHashMapUnmanaged(u32, ResolveAction.Kind) = .{}, locals_free_list: std.ArrayListUnmanaged(u32) = .{}, globals_free_list: std.ArrayListUnmanaged(u32) = .{}, @@ -295,10 +295,15 @@ const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.A const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); const RelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); -const PendingUpdate = union(enum) { - resolve_undef: u32, - add_stub_entry: u32, - add_got_entry: u32, +const ResolveAction = struct { + kind: Kind, + target: SymbolWithLoc, + + const Kind = enum { + none, + add_got, + add_stub, + }; }; pub const SymbolWithLoc = struct { @@ -603,16 +608,29 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); } + if (self.dyld_stub_binder_index == null) { + self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got); + } + try self.createMhExecuteHeaderSymbol(); - try self.resolveDyldStubBinder(); - try self.createDyldPrivateAtom(); - try self.createStubHelperPreambleAtom(); - try self.resolveSymbolsInDylibs(); + + var actions = std.ArrayList(ResolveAction).init(self.base.allocator); + defer actions.deinit(); + try self.resolveSymbolsInDylibs(&actions); if (self.unresolved.count() > 0) { return error.UndefinedSymbolReference; } + try self.createDyldPrivateAtom(); + try self.createStubHelperPreambleAtom(); + + for (actions.items) |action| switch (action.kind) { + .none => {}, + .add_got => try self.addGotEntry(action.target), + .add_stub => try self.addStubEntry(action.target), + }; + try self.allocateSpecialSymbols(); for (self.relocs.keys()) |atom_index| { @@ -1242,8 +1260,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { return atom_index; } -pub fn createDyldPrivateAtom(self: *MachO) !void { - if (self.dyld_stub_binder_index == null) return; +fn createDyldPrivateAtom(self: *MachO) !void { if (self.dyld_private_atom_index != null) return; const atom_index = try self.createAtom(); @@ -1260,8 +1277,7 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { try self.writePtrWidthAtom(atom_index); } -pub fn createStubHelperPreambleAtom(self: *MachO) !void { - if (self.dyld_stub_binder_index == null) return; +fn createStubHelperPreambleAtom(self: *MachO) !void { if (self.stub_helper_preamble_atom_index != null) return; const gpa = self.base.allocator; @@ -1285,10 +1301,8 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { sym.n_type = macho.N_SECT; sym.n_sect = self.stub_helper_section_index.? + 1; - const dyld_private_sym_index = if (self.dyld_private_atom_index) |dyld_index| - self.getAtom(dyld_index).getSymbolIndex().? - else - unreachable; + const dyld_private = self.getAtom(self.dyld_private_atom_index.?).getSymbolWithLoc(); + const dyld_stub_binder = self.globals.items[self.dyld_stub_binder_index.?]; const code = try gpa.alloc(u8, size); defer gpa.free(code); @@ -1309,14 +1323,14 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { try Atom.addRelocations(self, atom_index, 2, .{ .{ .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), - .target = .{ .sym_index = dyld_private_sym_index, .file = null }, + .target = dyld_private, .offset = 3, .addend = 0, .pcrel = true, .length = 2, }, .{ .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_GOT), - .target = .{ .sym_index = self.dyld_stub_binder_index.?, .file = null }, + .target = dyld_stub_binder, .offset = 11, .addend = 0, .pcrel = true, @@ -1349,28 +1363,28 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { try Atom.addRelocations(self, atom_index, 4, .{ .{ .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), - .target = .{ .sym_index = dyld_private_sym_index, .file = null }, + .target = dyld_private, .offset = 0, .addend = 0, .pcrel = true, .length = 2, }, .{ .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12), - .target = .{ .sym_index = dyld_private_sym_index, .file = null }, + .target = dyld_private, .offset = 4, .addend = 0, .pcrel = false, .length = 2, }, .{ .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), - .target = .{ .sym_index = self.dyld_stub_binder_index.?, .file = null }, + .target = dyld_stub_binder, .offset = 12, .addend = 0, .pcrel = true, .length = 2, }, .{ .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), - .target = .{ .sym_index = self.dyld_stub_binder_index.?, .file = null }, + .target = dyld_stub_binder, .offset = 16, .addend = 0, .pcrel = false, @@ -1387,7 +1401,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { try self.writeAtom(atom_index, code); } -pub fn createStubHelperAtom(self: *MachO) !Atom.Index { +fn createStubHelperAtom(self: *MachO) !Atom.Index { const gpa = self.base.allocator; const arch = self.base.options.target.cpu.arch; const size: u4 = switch (arch) { @@ -1468,7 +1482,7 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { return atom_index; } -pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !Atom.Index { +fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !Atom.Index { const atom_index = try self.createAtom(); const atom = self.getAtomPtr(atom_index); atom.size = @sizeOf(u64); @@ -1502,7 +1516,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi return atom_index; } -pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { +fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { const gpa = self.base.allocator; const arch = self.base.options.target.cpu.arch; const size: u4 = switch (arch) { @@ -1585,7 +1599,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { return atom_index; } -pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { +fn createMhExecuteHeaderSymbol(self: *MachO) !void { if (self.base.options.output_mode != .Exe) return; if (self.getGlobal("__mh_execute_header")) |global| { const sym = self.getSymbol(global); @@ -1608,7 +1622,7 @@ pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { gop.value_ptr.* = sym_loc; } -pub fn createDsoHandleSymbol(self: *MachO) !void { +fn createDsoHandleSymbol(self: *MachO) !void { const global = self.getGlobalPtr("___dso_handle") orelse return; if (!self.getSymbol(global.*).undf()) return; @@ -1636,7 +1650,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { if (!gop.found_existing) { gop.value_ptr.* = current; if (sym.undf() and !sym.tentative()) { - try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, false); + try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, .none); } return; } @@ -1683,7 +1697,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { gop.value_ptr.* = current; } -pub fn resolveSymbolsInDylibs(self: *MachO) !void { +fn resolveSymbolsInDylibs(self: *MachO, actions: *std.ArrayList(ResolveAction)) !void { if (self.dylibs.items.len == 0) return; const gpa = self.base.allocator; @@ -1711,19 +1725,8 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { } if (self.unresolved.fetchSwapRemove(global_index)) |entry| blk: { - if (!entry.value) break :blk; if (!sym.undf()) break :blk; - if (self.stubs_table.contains(global)) break :blk; - - const stub_index = try self.allocateStubEntry(global); - const stub_helper_atom_index = try self.createStubHelperAtom(); - const stub_helper_atom = self.getAtom(stub_helper_atom_index); - const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, global); - const laptr_atom = self.getAtom(laptr_atom_index); - const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?); - const stub_atom = self.getAtom(stub_atom_index); - self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?; - self.markRelocsDirtyByTarget(global); + try actions.append(.{ .kind = entry.value, .target = global }); } continue :loop; @@ -1733,101 +1736,6 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { } } -pub fn resolveSymbolsAtLoading(self: *MachO) !void { - const is_lib = self.base.options.output_mode == .Lib; - const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; - const allow_undef = is_dyn_lib and (self.base.options.allow_shlib_undefined orelse false); - - var next_sym: usize = 0; - while (next_sym < self.unresolved.count()) { - const global_index = self.unresolved.keys()[next_sym]; - const global = self.globals.items[global_index]; - const sym = self.getSymbolPtr(global); - const sym_name = self.getSymbolName(global); - - if (sym.discarded()) { - sym.* = .{ - .n_strx = 0, - .n_type = macho.N_UNDF, - .n_sect = 0, - .n_desc = 0, - .n_value = 0, - }; - _ = self.unresolved.swapRemove(global_index); - continue; - } else if (allow_undef) { - const n_desc = @bitCast( - u16, - macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP * @intCast(i16, macho.N_SYMBOL_RESOLVER), - ); - // TODO allow_shlib_undefined is an ELF flag so figure out macOS specific flags too. - sym.n_type = macho.N_EXT; - sym.n_desc = n_desc; - _ = self.unresolved.swapRemove(global_index); - continue; - } - - log.err("undefined reference to symbol '{s}'", .{sym_name}); - if (global.file) |file| { - log.err(" first referenced in '{s}'", .{self.objects.items[file].name}); - } - - next_sym += 1; - } -} - -pub fn resolveDyldStubBinder(self: *MachO) !void { - if (self.dyld_stub_binder_index != null) return; - if (self.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports - - log.debug("resolving dyld_stub_binder", .{}); - - const gpa = self.base.allocator; - const sym_index = try self.allocateSymbol(); - const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; - const sym = self.getSymbolPtr(sym_loc); - const sym_name = "dyld_stub_binder"; - sym.* = .{ - .n_strx = try self.strtab.insert(gpa, sym_name), - .n_type = macho.N_UNDF, - .n_sect = 0, - .n_desc = 0, - .n_value = 0, - }; - const gop = try self.getOrPutGlobalPtr(sym_name); - gop.value_ptr.* = sym_loc; - const global = gop.value_ptr.*; - - for (self.dylibs.items, 0..) |dylib, id| { - if (!dylib.symbols.contains(sym_name)) continue; - - const dylib_id = @intCast(u16, id); - if (!self.referenced_dylibs.contains(dylib_id)) { - try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {}); - } - - const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; - sym.n_type |= macho.N_EXT; - sym.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; - self.dyld_stub_binder_index = sym_index; - - break; - } - - if (self.dyld_stub_binder_index == null) { - log.err("undefined reference to symbol '{s}'", .{sym_name}); - return error.UndefinedSymbolReference; - } - - // Add dyld_stub_binder as the final GOT entry. - const got_index = try self.allocateGotEntry(global); - const got_atom_index = try self.createGotAtom(global); - const got_atom = self.getAtom(got_atom_index); - self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; - - try self.writePtrWidthAtom(got_atom_index); -} - pub fn deinit(self: *MachO) void { const gpa = self.base.allocator; @@ -2016,7 +1924,7 @@ fn growAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignment: return self.allocateAtom(atom_index, new_atom_size, alignment); } -pub fn allocateSymbol(self: *MachO) !u32 { +fn allocateSymbol(self: *MachO) !u32 { try self.locals.ensureUnusedCapacity(self.base.allocator, 1); const index = blk: { @@ -2065,7 +1973,7 @@ fn allocateGlobal(self: *MachO) !u32 { return index; } -pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { +fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { const gpa = self.base.allocator; try self.got_entries.ensureUnusedCapacity(gpa, 1); @@ -2087,7 +1995,17 @@ pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { return index; } -pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { +fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { + if (self.got_entries_table.contains(target)) return; + + const got_index = try self.allocateGotEntry(target); + const got_atom_index = try self.createGotAtom(target); + const got_atom = self.getAtom(got_atom_index); + self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; + try self.writePtrWidthAtom(got_atom_index); +} + +fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { try self.stubs.ensureUnusedCapacity(self.base.allocator, 1); const index = blk: { @@ -2108,6 +2026,20 @@ pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { return index; } +fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { + if (self.stubs_table.contains(target)) return; + + const stub_index = try self.allocateStubEntry(target); + const stub_helper_atom_index = try self.createStubHelperAtom(); + const stub_helper_atom = self.getAtom(stub_helper_atom_index); + const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target); + const laptr_atom = self.getAtom(laptr_atom_index); + const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?); + const stub_atom = self.getAtom(stub_atom_index); + self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?; + self.markRelocsDirtyByTarget(target); +} + pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { if (build_options.skip_non_native and builtin.object_format != .macho) { @panic("Attempted to compile for object format that was disabled by build configuration"); @@ -2376,13 +2308,7 @@ fn updateLazySymbolAtom( atom.size = code.len; symbol.n_value = vaddr; - const got_target = SymbolWithLoc{ .sym_index = local_sym_index, .file = null }; - const got_index = try self.allocateGotEntry(got_target); - const got_atom_index = try self.createGotAtom(got_target); - const got_atom = self.getAtom(got_atom_index); - self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; - try self.writePtrWidthAtom(got_atom_index); - + try self.addGotEntry(.{ .sym_index = local_sym_index }); self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); try self.writeAtom(atom_index, code); } @@ -2445,114 +2371,6 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 { return sect_id; } -pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 { - const segname = sect.segName(); - const sectname = sect.sectName(); - const sect_id: ?u8 = blk: { - if (mem.eql(u8, "__LLVM", segname)) { - log.debug("TODO LLVM section: type 0x{x}, name '{s},{s}'", .{ - sect.flags, segname, sectname, - }); - break :blk null; - } - - if (sect.isCode()) { - if (self.text_section_index == null) { - self.text_section_index = try self.initSection("__TEXT", "__text", .{ - .flags = macho.S_REGULAR | - macho.S_ATTR_PURE_INSTRUCTIONS | - macho.S_ATTR_SOME_INSTRUCTIONS, - }); - } - break :blk self.text_section_index.?; - } - - if (sect.isDebug()) { - // TODO debug attributes - if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { - log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ - sect.flags, segname, sectname, - }); - } - break :blk null; - } - - switch (sect.type()) { - macho.S_4BYTE_LITERALS, - macho.S_8BYTE_LITERALS, - macho.S_16BYTE_LITERALS, - => { - if (self.getSectionByName("__TEXT", "__const")) |sect_id| break :blk sect_id; - break :blk try self.initSection("__TEXT", "__const", .{}); - }, - macho.S_CSTRING_LITERALS => { - if (mem.startsWith(u8, sectname, "__objc")) { - if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; - break :blk try self.initSection(segname, sectname, .{}); - } - if (self.getSectionByName("__TEXT", "__cstring")) |sect_id| break :blk sect_id; - break :blk try self.initSection("__TEXT", "__cstring", .{ - .flags = macho.S_CSTRING_LITERALS, - }); - }, - macho.S_MOD_INIT_FUNC_POINTERS, - macho.S_MOD_TERM_FUNC_POINTERS, - => { - if (self.getSectionByName("__DATA_CONST", sectname)) |sect_id| break :blk sect_id; - break :blk try self.initSection("__DATA_CONST", sectname, .{ - .flags = sect.flags, - }); - }, - macho.S_LITERAL_POINTERS, - macho.S_ZEROFILL, - macho.S_THREAD_LOCAL_VARIABLES, - macho.S_THREAD_LOCAL_VARIABLE_POINTERS, - macho.S_THREAD_LOCAL_REGULAR, - macho.S_THREAD_LOCAL_ZEROFILL, - => { - if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; - break :blk try self.initSection(segname, sectname, .{ .flags = sect.flags }); - }, - macho.S_COALESCED => { - if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; - break :blk try self.initSection(segname, sectname, .{}); - }, - macho.S_REGULAR => { - if (mem.eql(u8, segname, "__TEXT")) { - if (mem.eql(u8, sectname, "__rodata") or - mem.eql(u8, sectname, "__typelink") or - mem.eql(u8, sectname, "__itablink") or - mem.eql(u8, sectname, "__gosymtab") or - mem.eql(u8, sectname, "__gopclntab")) - { - if (self.getSectionByName("__DATA_CONST", "__const")) |sect_id| break :blk sect_id; - break :blk try self.initSection("__DATA_CONST", "__const", .{}); - } - } - if (mem.eql(u8, segname, "__DATA")) { - if (mem.eql(u8, sectname, "__const") or - mem.eql(u8, sectname, "__cfstring") or - mem.eql(u8, sectname, "__objc_classlist") or - mem.eql(u8, sectname, "__objc_imageinfo")) - { - if (self.getSectionByName("__DATA_CONST", sectname)) |sect_id| break :blk sect_id; - break :blk try self.initSection("__DATA_CONST", sectname, .{}); - } else if (mem.eql(u8, sectname, "__data")) { - if (self.data_section_index == null) { - self.data_section_index = try self.initSection(segname, sectname, .{}); - } - break :blk self.data_section_index.?; - } - } - if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; - break :blk try self.initSection(segname, sectname, .{}); - }, - else => break :blk null, - } - }; - return sect_id; -} - fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 { const gpa = self.base.allocator; const mod = self.base.options.module.?; @@ -2619,12 +2437,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 self.getAtomPtr(atom_index).size = code_len; sym.n_value = vaddr; - const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; - const got_index = try self.allocateGotEntry(got_target); - const got_atom_index = try self.createGotAtom(got_target); - const got_atom = self.getAtom(got_atom_index); - self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; - try self.writePtrWidthAtom(got_atom_index); + try self.addGotEntry(.{ .sym_index = sym_index }); } self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); @@ -2837,7 +2650,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil return 0; } -pub fn populateMissingMetadata(self: *MachO) !void { +fn populateMissingMetadata(self: *MachO) !void { assert(self.mode == .incremental); const gpa = self.base.allocator; @@ -3273,79 +3086,12 @@ fn getSectionPrecedence(header: macho.section_64) u4 { } } -const InitSectionOpts = struct { - flags: u32 = macho.S_REGULAR, - reserved1: u32 = 0, - reserved2: u32 = 0, -}; - -pub fn initSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: InitSectionOpts) !u8 { - const segment_id = self.getSegmentByName(segname).?; - const seg = &self.segments.items[segment_id]; - const index = try self.insertSection(segment_id, .{ - .sectname = makeStaticString(sectname), - .segname = seg.segname, - .flags = opts.flags, - .reserved1 = opts.reserved1, - .reserved2 = opts.reserved2, - }); - seg.cmdsize += @sizeOf(macho.section_64); - seg.nsects += 1; - return index; -} - -fn insertSection(self: *MachO, segment_index: u8, header: macho.section_64) !u8 { - const precedence = getSectionPrecedence(header); - const indexes = self.getSectionIndexes(segment_index); - const insertion_index = for (self.sections.items(.header)[indexes.start..indexes.end], 0..) |hdr, i| { - if (getSectionPrecedence(hdr) > precedence) break @intCast(u8, i + indexes.start); - } else indexes.end; - log.debug("inserting section '{s},{s}' at index {d}", .{ - header.segName(), - header.sectName(), - insertion_index, - }); - for (&[_]*?u8{ - &self.text_section_index, - &self.stubs_section_index, - &self.stub_helper_section_index, - &self.got_section_index, - &self.la_symbol_ptr_section_index, - &self.data_section_index, - }) |maybe_index| { - const index = maybe_index.* orelse continue; - if (insertion_index <= index) maybe_index.* = index + 1; - } - try self.sections.insert(self.base.allocator, insertion_index, .{ - .segment_index = segment_index, - .header = header, - }); - return insertion_index; -} - pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { _ = lib_name; const gpa = self.base.allocator; - const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); defer gpa.free(sym_name); - const gop = try self.getOrPutGlobalPtr(sym_name); - const global_index = self.getGlobalIndex(sym_name).?; - - if (gop.found_existing) { - return global_index; - } - - const sym_index = try self.allocateSymbol(); - const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; - gop.value_ptr.* = sym_loc; - - const sym = self.getSymbolPtr(sym_loc); - sym.n_strx = try self.strtab.insert(gpa, sym_name); - - try self.unresolved.putNoClobber(gpa, global_index, true); - - return global_index; + return self.addUndefined(sym_name, .add_stub); } fn writeSegmentHeaders(self: *MachO, writer: anytype) !void { @@ -3953,6 +3699,29 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { self.hot_state.mach_task = null; } +fn addUndefined(self: *MachO, name: []const u8, action: ResolveAction.Kind) !u32 { + const gpa = self.base.allocator; + + const gop = try self.getOrPutGlobalPtr(name); + const global_index = self.getGlobalIndex(name).?; + + if (gop.found_existing) { + return global_index; + } + + const sym_index = try self.allocateSymbol(); + const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; + gop.value_ptr.* = sym_loc; + + const sym = self.getSymbolPtr(sym_loc); + sym.n_strx = try self.strtab.insert(gpa, name); + sym.n_type = macho.N_UNDF; + + try self.unresolved.putNoClobber(gpa, global_index, action); + + return global_index; +} + pub fn makeStaticString(bytes: []const u8) [16]u8 { var buf = [_]u8{0} ** 16; assert(bytes.len <= buf.len); From a503724801e7b221aababd88aefe790a33c4135e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 4 Apr 2023 19:31:26 +0200 Subject: [PATCH 208/216] macho: reapply relocation dirtying logic from coff linker --- src/link/MachO.zig | 17 +++++++++++++++-- src/link/MachO/Atom.zig | 11 +++++++---- src/link/MachO/Relocation.zig | 8 +++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 7192ce58e1..e8fab08912 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1128,8 +1128,15 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { const file_offset = section.header.offset + sym.n_value - section.header.addr; log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); - if (self.relocs.get(atom_index)) |relocs| { - Atom.resolveRelocations(self, atom_index, relocs.items, code); + // Gather relocs which can be resolved. + var relocs = std.ArrayList(*Relocation).init(self.base.allocator); + defer relocs.deinit(); + + if (self.relocs.getPtr(atom_index)) |rels| { + try relocs.ensureTotalCapacityPrecise(rels.items.len); + for (rels.items) |*reloc| { + if (reloc.isResolvable(self)) relocs.appendAssumeCapacity(reloc); + } } if (is_hot_update_compatible) { @@ -1144,7 +1151,13 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { } } + Atom.resolveRelocations(self, atom_index, relocs.items, code); try self.base.file.?.pwriteAll(code, file_offset); + + // Now we can mark the relocs as resolved. + while (relocs.popOrNull()) |reloc| { + reloc.dirty = false; + } } fn updateAtomInMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void { diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index c601cfa440..bd1a21a04f 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -179,12 +179,15 @@ pub fn addLazyBinding(macho_file: *MachO, atom_index: Index, binding: Binding) ! try gop.value_ptr.append(gpa, binding); } -pub fn resolveRelocations(macho_file: *MachO, atom_index: Index, relocs: []Relocation, code: []u8) void { +pub fn resolveRelocations( + macho_file: *MachO, + atom_index: Index, + relocs: []*const Relocation, + code: []u8, +) void { log.debug("relocating '{s}'", .{macho_file.getAtom(atom_index).getName(macho_file)}); - for (relocs) |*reloc| { - if (!reloc.dirty) continue; + for (relocs) |reloc| { reloc.resolve(macho_file, atom_index, code); - reloc.dirty = false; } } diff --git a/src/link/MachO/Relocation.zig b/src/link/MachO/Relocation.zig index cc565742d1..32f24f243d 100644 --- a/src/link/MachO/Relocation.zig +++ b/src/link/MachO/Relocation.zig @@ -21,6 +21,12 @@ pcrel: bool, length: u2, dirty: bool = true, +/// Returns true if and only if the reloc is dirty AND the target address is available. +pub fn isResolvable(self: Relocation, macho_file: *MachO) bool { + _ = self.getTargetAtomIndex(macho_file) orelse return false; + return self.dirty; +} + pub fn fmtType(self: Relocation, target: std.Target) []const u8 { switch (target.cpu.arch) { .aarch64 => return @tagName(@intToEnum(macho.reloc_type_arm64, self.type)), @@ -56,7 +62,7 @@ pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, cod const source_sym = atom.getSymbol(macho_file); const source_addr = source_sym.n_value + self.offset; - const target_atom_index = self.getTargetAtomIndex(macho_file) orelse return; + const target_atom_index = self.getTargetAtomIndex(macho_file).?; // Oops, you didn't check if the relocation can be resolved with isResolvable(). const target_atom = macho_file.getAtom(target_atom_index); const target_addr = @intCast(i64, target_atom.getSymbol(macho_file).n_value) + self.addend; From ad5fb4879b03267f196004a78762de7be3b03de7 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Tue, 4 Apr 2023 22:12:32 -0400 Subject: [PATCH 209/216] std: fix memory bugs This fixes logged errors during CI based on the new GPA checks. --- lib/std/fs/path.zig | 16 +++++------- lib/std/heap/arena_allocator.zig | 45 ++++++++++++++++---------------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 150eada38b..4d780b2ead 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -1088,21 +1088,19 @@ pub fn relativeWindows(allocator: Allocator, from: []const u8, to: []const u8) ! if (ascii.eqlIgnoreCase(from_component, to_component)) continue; } - var up_count: usize = 1; + var up_index_end = "..".len; while (from_it.next()) |_| { - up_count += 1; + up_index_end += "\\..".len; } - const up_index_end = up_count * "..\\".len; - const result = try allocator.alloc(u8, up_index_end + to_rest.len); + const result = try allocator.alloc(u8, up_index_end + @boolToInt(to_rest.len > 0) + to_rest.len); errdefer allocator.free(result); - var result_index: usize = 0; + result[0..2].* = "..".*; + var result_index: usize = 2; while (result_index < up_index_end) { - result[result_index..][0..3].* = "..\\".*; + result[result_index..][0..3].* = "\\..".*; result_index += 3; } - // shave off the trailing slash - result_index -= 1; var rest_it = mem.tokenize(u8, to_rest, "/\\"); while (rest_it.next()) |to_component| { @@ -1112,7 +1110,7 @@ pub fn relativeWindows(allocator: Allocator, from: []const u8, to: []const u8) ! result_index += to_component.len; } - return result[0..result_index]; + return allocator.realloc(result, result_index); } return [_]u8{}; diff --git a/lib/std/heap/arena_allocator.zig b/lib/std/heap/arena_allocator.zig index 7e40c1f53b..d07c45cb70 100644 --- a/lib/std/heap/arena_allocator.zig +++ b/lib/std/heap/arena_allocator.zig @@ -12,7 +12,7 @@ pub const ArenaAllocator = struct { /// Inner state of ArenaAllocator. Can be stored rather than the entire ArenaAllocator /// as a memory-saving optimization. pub const State = struct { - buffer_list: std.SinglyLinkedList([]u8) = @as(std.SinglyLinkedList([]u8), .{}), + buffer_list: std.SinglyLinkedList(usize) = .{}, end_index: usize = 0, pub fn promote(self: State, child_allocator: Allocator) ArenaAllocator { @@ -34,7 +34,7 @@ pub const ArenaAllocator = struct { }; } - const BufNode = std.SinglyLinkedList([]u8).Node; + const BufNode = std.SinglyLinkedList(usize).Node; pub fn init(child_allocator: Allocator) ArenaAllocator { return (State{}).promote(child_allocator); @@ -47,7 +47,9 @@ pub const ArenaAllocator = struct { while (it) |node| { // this has to occur before the free because the free frees node const next_it = node.next; - self.child_allocator.free(node.data); + const align_bits = std.math.log2_int(usize, @alignOf(BufNode)); + const alloc_buf = @ptrCast([*]u8, node)[0..node.data]; + self.child_allocator.rawFree(alloc_buf, align_bits, @returnAddress()); it = next_it; } } @@ -73,7 +75,7 @@ pub const ArenaAllocator = struct { while (it) |node| : (it = node.next) { // Compute the actually allocated size excluding the // linked list node. - size += node.data.len - @sizeOf(BufNode); + size += node.data - @sizeOf(BufNode); } return size; } @@ -121,6 +123,7 @@ pub const ArenaAllocator = struct { .retain_with_limit => |limit| std.math.min(limit, current_capacity), .free_all => unreachable, }; + const align_bits = std.math.log2_int(usize, @alignOf(BufNode)); // Free all nodes except for the last one var it = self.state.buffer_list.first; const maybe_first_node = while (it) |node| { @@ -128,7 +131,8 @@ pub const ArenaAllocator = struct { const next_it = node.next; if (next_it == null) break node; - self.child_allocator.free(node.data); + const alloc_buf = @ptrCast([*]u8, node)[0..node.data]; + self.child_allocator.rawFree(alloc_buf, align_bits, @returnAddress()); it = next_it; } else null; std.debug.assert(maybe_first_node == null or maybe_first_node.?.next == null); @@ -136,23 +140,21 @@ pub const ArenaAllocator = struct { self.state.end_index = 0; if (maybe_first_node) |first_node| { // perfect, no need to invoke the child_allocator - if (first_node.data.len == total_size) + if (first_node.data == total_size) return true; - const align_bits = std.math.log2_int(usize, @alignOf(BufNode)); - if (self.child_allocator.rawResize(first_node.data, align_bits, total_size, @returnAddress())) { + const first_alloc_buf = @ptrCast([*]u8, first_node)[0..first_node.data]; + if (self.child_allocator.rawResize(first_alloc_buf, align_bits, total_size, @returnAddress())) { // successful resize - first_node.data.len = total_size; + first_node.data = total_size; } else { // manual realloc const new_ptr = self.child_allocator.rawAlloc(total_size, align_bits, @returnAddress()) orelse { // we failed to preheat the arena properly, signal this to the user. return false; }; - self.child_allocator.rawFree(first_node.data, align_bits, @returnAddress()); + self.child_allocator.rawFree(first_alloc_buf, align_bits, @returnAddress()); const node = @ptrCast(*BufNode, @alignCast(@alignOf(BufNode), new_ptr)); - node.* = BufNode{ - .data = new_ptr[0..total_size], - }; + node.* = .{ .data = total_size }; self.state.buffer_list.first = node; } } @@ -167,10 +169,7 @@ pub const ArenaAllocator = struct { const ptr = self.child_allocator.rawAlloc(len, log2_align, @returnAddress()) orelse return null; const buf_node = @ptrCast(*BufNode, @alignCast(@alignOf(BufNode), ptr)); - buf_node.* = BufNode{ - .data = ptr[0..len], - .next = null, - }; + buf_node.* = .{ .data = len }; self.state.buffer_list.prepend(buf_node); self.state.end_index = 0; return buf_node; @@ -186,7 +185,8 @@ pub const ArenaAllocator = struct { else (self.createNode(0, n + ptr_align) orelse return null); while (true) { - const cur_buf = cur_node.data[@sizeOf(BufNode)..]; + const cur_alloc_buf = @ptrCast([*]u8, cur_node)[0..cur_node.data]; + const cur_buf = cur_alloc_buf[@sizeOf(BufNode)..]; const addr = @ptrToInt(cur_buf.ptr) + self.state.end_index; const adjusted_addr = mem.alignForward(addr, ptr_align); const adjusted_index = self.state.end_index + (adjusted_addr - addr); @@ -199,8 +199,9 @@ pub const ArenaAllocator = struct { } const bigger_buf_size = @sizeOf(BufNode) + new_end_index; - if (self.child_allocator.resize(cur_node.data, bigger_buf_size)) { - cur_node.data.len = bigger_buf_size; + const log2_align = comptime std.math.log2_int(usize, @alignOf(BufNode)); + if (self.child_allocator.rawResize(cur_alloc_buf, log2_align, bigger_buf_size, @returnAddress())) { + cur_node.data = bigger_buf_size; } else { // Allocate a new node if that's not possible cur_node = self.createNode(cur_buf.len, n + ptr_align) orelse return null; @@ -214,7 +215,7 @@ pub const ArenaAllocator = struct { _ = ret_addr; const cur_node = self.state.buffer_list.first orelse return false; - const cur_buf = cur_node.data[@sizeOf(BufNode)..]; + const cur_buf = @ptrCast([*]u8, cur_node)[@sizeOf(BufNode)..cur_node.data]; if (@ptrToInt(cur_buf.ptr) + self.state.end_index != @ptrToInt(buf.ptr) + buf.len) { // It's not the most recent allocation, so it cannot be expanded, // but it's fine if they want to make it smaller. @@ -239,7 +240,7 @@ pub const ArenaAllocator = struct { const self = @ptrCast(*ArenaAllocator, @alignCast(@alignOf(ArenaAllocator), ctx)); const cur_node = self.state.buffer_list.first orelse return; - const cur_buf = cur_node.data[@sizeOf(BufNode)..]; + const cur_buf = @ptrCast([*]u8, cur_node)[@sizeOf(BufNode)..cur_node.data]; if (@ptrToInt(cur_buf.ptr) + self.state.end_index == @ptrToInt(buf.ptr) + buf.len) { self.state.end_index -= buf.len; From f86f531e9c3878089d13ac48505a9e8845f81f28 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 27 Mar 2023 22:07:29 +0100 Subject: [PATCH 210/216] std: add a subset of the apple's QOS api --- lib/std/c/darwin.zig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index e72bdbe843..a6ab1fc6c5 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -853,6 +853,21 @@ pub const EAI = enum(c_int) { pub const EAI_MAX = 15; +pub const qos_class_t = enum(c_uint) { + /// highest priority QOS class for critical tasks + QOS_CLASS_USER_INTERACTIVE = 0x21, + /// slightly more moderate priority QOS class + QOS_CLASS_USER_INITIATED = 0x19, + /// default QOS class when none is set + QOS_CLASS_DEFAULT = 0x15, + /// more energy efficient QOS class than default + QOS_CLASS_UTILITY = 0x11, + /// QOS class more appropriate for background tasks + QOS_CLASS_BACKGROUND = 0x09, + /// QOS class as a return value + QOS_CLASS_UNSPECIFIED = 0x00, +}; + pub const pthread_mutex_t = extern struct { __sig: c_long = 0x32AAABA7, __opaque: [__PTHREAD_MUTEX_SIZE__]u8 = [_]u8{0} ** __PTHREAD_MUTEX_SIZE__, @@ -877,6 +892,10 @@ pub const pthread_attr_t = extern struct { pub extern "c" fn pthread_threadid_np(thread: ?std.c.pthread_t, thread_id: *u64) c_int; pub extern "c" fn pthread_setname_np(name: [*:0]const u8) E; pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E; +pub extern "c" fn pthread_attr_set_qos_class_np(attr: *pthread_attr_t, qos_class: qos_class_t, relative_priority: c_int) c_int; +pub extern "c" fn pthread_attr_get_qos_class_np(attr: *pthread_attr_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int; +pub extern "c" fn pthread_set_qos_class_self_np(qos_class: qos_class_t, relative_priority: c_int) c_int; +pub extern "c" fn pthread_get_qos_class_np(pthread: std.c.pthread_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int; pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; From 080136e4adf1efd93867ef5002153d6e02fe21ae Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Tue, 4 Apr 2023 21:37:34 +0100 Subject: [PATCH 211/216] std: add madvise flags to freebsd --- lib/std/c/freebsd.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index ccf9153f92..9a13e3658b 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -629,6 +629,20 @@ pub const MAP = struct { pub const ALIGNED_SUPER = ALIGNED(1); }; +pub const MADV = struct { + pub const NORMAL = 0; + pub const RANDOM = 1; + pub const SEQUENTIAL = 2; + pub const WILLNEED = 3; + pub const DONTNEED = 4; + pub const FREE = 5; + pub const NOSYNC = 6; + pub const AUTOSYNC = 7; + pub const NOCORE = 8; + pub const CORE = 9; + pub const PROTECT = 10; +}; + pub const MSF = struct { pub const ASYNC = 1; pub const INVALIDATE = 2; From 82a6acca93683fa7272976879f338a0e66e3f82b Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 4 Apr 2023 13:39:06 +0300 Subject: [PATCH 212/216] Sema: implement inline switch capture at comptime Closes #15157 --- src/Sema.zig | 20 ++++++++++++++++++++ test/behavior/switch.zig | 12 ++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 972efcff72..e816a167ec 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9963,6 +9963,26 @@ fn zirSwitchCapture( const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?); const union_obj = operand_ty.cast(Type.Payload.Union).?.data; const field_ty = union_obj.fields.values()[field_index].ty; + if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| { + if (is_ref) { + const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ + .pointee_type = field_ty, + .mutable = operand_ptr_ty.ptrIsMutable(), + .@"volatile" = operand_ptr_ty.isVolatilePtr(), + .@"addrspace" = operand_ptr_ty.ptrAddressSpace(), + }); + return sema.addConstant( + ptr_field_ty, + try Value.Tag.field_ptr.create(sema.arena, .{ + .container_ptr = union_val, + .container_ty = operand_ty, + .field_index = field_index, + }), + ); + } + const tag_and_val = union_val.castTag(.@"union").?.data; + return sema.addConstant(field_ty, tag_and_val.val); + } if (is_ref) { const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = field_ty, diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index e02a66f54b..b69add6fdf 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -694,3 +694,15 @@ test "switch item sizeof" { try S.doTheTest(); comptime try S.doTheTest(); } + +test "comptime inline switch" { + const U = union(enum) { a: type, b: type }; + const value = comptime blk: { + var u: U = .{ .a = u32 }; + break :blk switch (u) { + inline .a, .b => |v| v, + }; + }; + + try expectEqual(u32, value); +} From 66520c8342193827f703274aabfff6ad8656aee1 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 4 Apr 2023 18:42:07 +0300 Subject: [PATCH 213/216] Sema: validate array element types Fixes the compiler crash part of #15175 --- src/Sema.zig | 10 ++++++++++ .../compile_errors/invalid_array_elem_type.zig | 13 +++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 test/cases/compile_errors/invalid_array_elem_type.zig diff --git a/src/Sema.zig b/src/Sema.zig index e816a167ec..c3c9345205 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -7819,6 +7819,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node }; const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime-known"); const elem_type = try sema.resolveType(block, elem_src, extra.rhs); + try sema.validateArrayElemType(block, elem_type, elem_src); const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod); return sema.addType(array_ty); @@ -7835,6 +7836,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node }; const len = try sema.resolveInt(block, len_src, extra.len, Type.usize, "array length must be comptime-known"); const elem_type = try sema.resolveType(block, elem_src, extra.elem_type); + try sema.validateArrayElemType(block, elem_type, elem_src); const uncasted_sentinel = try sema.resolveInst(extra.sentinel); const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src); const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime-known"); @@ -7843,6 +7845,14 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil return sema.addType(array_ty); } +fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void { + if (elem_type.zigTypeTag() == .Opaque) { + return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(sema.mod)}); + } else if (elem_type.zigTypeTag() == .NoReturn) { + return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{}); + } +} + fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); diff --git a/test/cases/compile_errors/invalid_array_elem_type.zig b/test/cases/compile_errors/invalid_array_elem_type.zig new file mode 100644 index 0000000000..cbf27aeaa6 --- /dev/null +++ b/test/cases/compile_errors/invalid_array_elem_type.zig @@ -0,0 +1,13 @@ +comptime { + _ = [1]anyopaque; +} +comptime { + _ = [1]noreturn; +} + +// error +// backend=stage2 +// target=native +// +// :2:12: error: array of opaque type 'anyopaque' not allowed +// :5:12: error: array of 'noreturn' not allowed From d92b5fcfb00a5adc2442bd39fe33c72037bb0c6a Mon Sep 17 00:00:00 2001 From: Nikita Ronja Date: Thu, 30 Mar 2023 21:57:37 +0200 Subject: [PATCH 214/216] Add NetBSD termios constants to std.c.netbsd --- lib/std/c/netbsd.zig | 137 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig index 579e25d416..02d334cff4 100644 --- a/lib/std/c/netbsd.zig +++ b/lib/std/c/netbsd.zig @@ -915,6 +915,143 @@ pub const T = struct { pub const IOCXMTFRAME = 0x80087444; }; +// Term +const V = struct { + pub const EOF = 0; // ICANON + pub const EOL = 1; // ICANON + pub const EOL2 = 2; // ICANON + pub const ERASE = 3; // ICANON + pub const WERASE = 4; // ICANON + pub const KILL = 5; // ICANON + pub const REPRINT = 6; // ICANON + // 7 spare 1 + pub const INTR = 8; // ISIG + pub const QUIT = 9; // ISIG + pub const SUSP = 10; // ISIG + pub const DSUSP = 11; // ISIG + pub const START = 12; // IXON, IXOFF + pub const STOP = 13; // IXON, IXOFF + pub const LNEXT = 14; // IEXTEN + pub const DISCARD = 15; // IEXTEN + pub const MIN = 16; // !ICANON + pub const TIME = 17; // !ICANON + pub const STATUS = 18; // ICANON + // 19 spare 2 +}; + +// Input flags - software input processing +pub const IGNBRK: tcflag_t = 0x00000001; // ignore BREAK condition +pub const BRKINT: tcflag_t = 0x00000002; // map BREAK to SIGINT +pub const IGNPAR: tcflag_t = 0x00000004; // ignore (discard) parity errors +pub const PARMRK: tcflag_t = 0x00000008; // mark parity and framing errors +pub const INPCK: tcflag_t = 0x00000010; // enable checking of parity errors +pub const ISTRIP: tcflag_t = 0x00000020; // strip 8th bit off chars +pub const INLCR: tcflag_t = 0x00000040; // map NL into CR +pub const IGNCR: tcflag_t = 0x00000080; // ignore CR +pub const ICRNL: tcflag_t = 0x00000100; // map CR to NL (ala CRMOD) +pub const IXON: tcflag_t = 0x00000200; // enable output flow control +pub const IXOFF: tcflag_t = 0x00000400; // enable input flow control +pub const IXANY: tcflag_t = 0x00000800; // any char will restart after stop +pub const IMAXBEL: tcflag_t = 0x00002000; // ring bell on input queue full + +// Output flags - software output processing +pub const OPOST: tcflag_t = 0x00000001; // enable following output processing +pub const ONLCR: tcflag_t = 0x00000002; // map NL to CR-NL (ala CRMOD) +pub const OXTABS: tcflag_t = 0x00000004; // expand tabs to spaces +pub const ONOEOT: tcflag_t = 0x00000008; // discard EOT's (^D) on output +pub const OCRNL: tcflag_t = 0x00000010; // map CR to NL +pub const ONOCR: tcflag_t = 0x00000040; // discard CR's when on column 0 +pub const ONLRET: tcflag_t = 0x00000080; // move to column 0 on CR + +// Control flags - hardware control of terminal +pub const CIGNORE: tcflag_t = 0x00000001; // ignore control flags +pub const CSIZE: tcflag_t = 0x00000300; // character size mask +pub const CS5: tcflag_t = 0x00000000; // 5 bits (pseudo) +pub const CS6: tcflag_t = 0x00000100; // 6 bits +pub const CS7: tcflag_t = 0x00000200; // 7 bits +pub const CS8: tcflag_t = 0x00000300; // 8 bits +pub const CSTOPB: tcflag_t = 0x00000400; // send 2 stop bits +pub const CREAD: tcflag_t = 0x00000800; // enable receiver +pub const PARENB: tcflag_t = 0x00001000; // parity enable +pub const PARODD: tcflag_t = 0x00002000; // odd parity, else even +pub const HUPCL: tcflag_t = 0x00004000; // hang up on last close +pub const CLOCAL: tcflag_t = 0x00008000; // ignore modem status lines +pub const CRTSCTS: tcflag_t = 0x00010000; // RTS/CTS full-duplex flow control +pub const CRTS_IFLOW: tcflag_t = CRTSCTS; // XXX compat +pub const CCTS_OFLOW: tcflag_t = CRTSCTS; // XXX compat +pub const CDTRCTS: tcflag_t = 0x00020000; // DTR/CTS full-duplex flow control +pub const MDMBUF: tcflag_t = 0x00100000; // DTR/DCD hardware flow control +pub const CHWFLOW: tcflag_t = (MDMBUF | CRTSCTS | CDTRCTS); // all types of hw flow control + +pub const tcflag_t = c_uint; +pub const speed_t = c_uint; +pub const cc_t = u8; + +pub const NCCS = 20; + +pub const termios = extern struct { + iflag: tcflag_t, // input flags + oflag: tcflag_t, // output flags + cflag: tcflag_t, // control flags + lflag: tcflag_t, // local flags + cc: [NCCS]cc_t, // control chars + ispeed: c_int, // input speed + ospeed: c_int, // output speed +}; + +// Commands passed to tcsetattr() for setting the termios structure. +pub const TCSA = struct { + pub const NOW = 0; // make change immediate + pub const DRAIN = 1; // drain output, then chage + pub const FLUSH = 2; // drain output, flush input + pub const SOFT = 0x10; // flag - don't alter h.w. state +}; + +// Standard speeds +pub const B0: c_uint = 0; +pub const B50: c_uint = 50; +pub const B75: c_uint = 75; +pub const B110: c_uint = 110; +pub const B134: c_uint = 134; +pub const B150: c_uint = 150; +pub const B200: c_uint = 200; +pub const B300: c_uint = 300; +pub const B600: c_uint = 600; +pub const B1200: c_uint = 1200; +pub const B1800: c_uint = 1800; +pub const B2400: c_uint = 2400; +pub const B4800: c_uint = 4800; +pub const B9600: c_uint = 9600; +pub const B19200: c_uint = 19200; +pub const B38400: c_uint = 38400; +pub const B7200: c_uint = 7200; +pub const B14400: c_uint = 14400; +pub const B28800: c_uint = 28800; +pub const B57600: c_uint = 57600; +pub const B76800: c_uint = 76800; +pub const B115200: c_uint = 115200; +pub const B230400: c_uint = 230400; +pub const B460800: c_uint = 460800; +pub const B500000: c_uint = 500000; +pub const B921600: c_uint = 921600; +pub const B1000000: c_uint = 1000000; +pub const B1500000: c_uint = 1500000; +pub const B2000000: c_uint = 2000000; +pub const B2500000: c_uint = 2500000; +pub const B3000000: c_uint = 3000000; +pub const B3500000: c_uint = 3500000; +pub const B4000000: c_uint = 4000000; +pub const EXTA: c_uint = 19200; +pub const EXTB: c_uint = 38400; + +pub const TCIFLUSH = 1; +pub const TCOFLUSH = 2; +pub const TCIOFLUSH = 3; +pub const TCOOFF = 1; +pub const TCOON = 2; +pub const TCIOFF = 3; +pub const TCION = 4; + pub const winsize = extern struct { ws_row: u16, ws_col: u16, From 3e467c778a83fac08ae2f124af05a4cf6dc95470 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 5 Apr 2023 13:13:30 +0100 Subject: [PATCH 215/216] std: add os_log/signpost api (sort of linux's perf event equivalent) subset. --- lib/std/c/darwin.zig | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index a6ab1fc6c5..a46337b721 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -3814,3 +3814,35 @@ pub fn machTaskForPid(pid: std.os.pid_t) MachError!MachTask { pub fn machTaskForSelf() MachTask { return .{ .port = mach_task_self() }; } + +pub const os_signpost_id_t = u64; + +pub const OS_SIGNPOST_ID_NULL: os_signpost_id_t = 0; +pub const OS_SIGNPOST_ID_INVALID: os_signpost_id_t = !0; +pub const OS_SIGNPOST_ID_EXCLUSIVE: os_signpost_id_t = 0xeeeeb0b5b2b2eeee; + +pub const os_log_t = opaque {}; +pub const os_log_type_t = enum(u8) { + /// default messages always captures + OS_LOG_TYPE_DEFAULT = 0x00, + /// messages with additional infos + OS_LOG_TYPE_INFO = 0x01, + /// debug messages + OS_LOG_TYPE_DEBUG = 0x02, + /// error messages + OS_LOG_TYPE_ERROR = 0x10, + /// unexpected conditions messages + OS_LOG_TYPE_FAULT = 0x11, +}; + +pub const OS_LOG_CATEGORY_POINTS_OF_INTEREST: *const u8 = "PointsOfInterest"; +pub const OS_LOG_CATEGORY_DYNAMIC_TRACING: *const u8 = "DynamicTracing"; +pub const OS_LOG_CATEGORY_DYNAMIC_STACK_TRACING: *const u8 = "DynamicStackTracing"; + +pub extern "c" fn os_log_create(subsystem: [*]const u8, category: [*]const u8) os_log_t; +pub extern "c" fn os_log_type_enabled(log: os_log_t, tpe: os_log_type_t) bool; +pub extern "c" fn os_signpost_id_generate(log: os_log_t) os_signpost_id_t; +pub extern "c" fn os_signpost_interval_begin(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void; +pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void; +pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t; +pub extern "c" fn os_signpost_enabled(log: os_log_t) bool; From 348751462632234f2bee10f5faad3711eff89172 Mon Sep 17 00:00:00 2001 From: jim price Date: Wed, 29 Mar 2023 00:46:25 -0700 Subject: [PATCH 216/216] std.os: add mincore syscall The mincore syscall is available on some UNIX like operating systems and allows a user to determine if a page is resident in memory. --- lib/std/c/linux.zig | 6 ++++++ lib/std/os.zig | 29 +++++++++++++++++++++++++++++ lib/std/os/linux.zig | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index 470c5e8437..3eeb3bd68b 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -289,6 +289,12 @@ pub extern "c" fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: *con pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; pub extern "c" fn malloc_usable_size(?*const anyopaque) usize; +pub extern "c" fn mincore( + addr: *align(std.mem.page_size) anyopaque, + length: usize, + vec: [*]u8, +) c_int; + pub extern "c" fn madvise( addr: *align(std.mem.page_size) anyopaque, length: usize, diff --git a/lib/std/os.zig b/lib/std/os.zig index 2b604f19fe..36a54adde9 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -6974,6 +6974,35 @@ pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void } } +pub const MincoreError = error{ + /// A kernel resource was temporarily unavailable. + SystemResources, + /// vec points to an invalid address. + InvalidAddress, + /// addr is not page-aligned. + InvalidSyscall, + /// One of the following: + /// * length is greater than user space TASK_SIZE - addr + /// * addr + length contains unmapped memory + OutOfMemory, + /// The mincore syscall is not available on this version and configuration + /// of this UNIX-like kernel. + MincoreUnavailable, +} || UnexpectedError; + +/// Determine whether pages are resident in memory. +pub fn mincore(ptr: [*]align(mem.page_size) u8, length: usize, vec: [*]u8) MincoreError!void { + return switch (errno(system.mincore(ptr, length, vec))) { + .SUCCESS => {}, + .AGAIN => error.SystemResources, + .FAULT => error.InvalidAddress, + .INVAL => error.InvalidSyscall, + .NOMEM => error.OutOfMemory, + .NOSYS => error.MincoreUnavailable, + else => |err| unexpectedErrno(err), + }; +} + pub const MadviseError = error{ /// advice is MADV.REMOVE, but the specified address range is not a shared writable mapping. AccessDenied, diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 53f6030b5f..b6ec05997f 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1699,6 +1699,10 @@ pub fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: ?*const rlimit, ); } +pub fn mincore(address: [*]u8, len: usize, vec: [*]u8) usize { + return syscall3(.mincore, @ptrToInt(address), len, @ptrToInt(vec)); +} + pub fn madvise(address: [*]u8, len: usize, advice: u32) usize { return syscall3(.madvise, @ptrToInt(address), len, advice); }