diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-22 12:12:36 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-22 12:12:36 -0500 |
| commit | 97b2ac598b91194c09a96c9ed86e4f9b266d019c (patch) | |
| tree | f8ddd18aaf3a52981f3a97faeac8ef7bd20e6908 /lib/std | |
| parent | 7e674d6761c057985003694f98861f589b6cf313 (diff) | |
| parent | c522699f28c1df806865c527a7a68a875e606527 (diff) | |
| download | zig-97b2ac598b91194c09a96c9ed86e4f9b266d019c.tar.gz zig-97b2ac598b91194c09a96c9ed86e4f9b266d019c.zip | |
Merge remote-tracking branch 'origin/master' into llvm10
Diffstat (limited to 'lib/std')
26 files changed, 902 insertions, 751 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index ad4be9e4ca..53f8f19df5 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1687,7 +1687,9 @@ pub const LibExeObjStep = struct { } pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void { - self.link_objects.append(LinkObject{ .AssemblyFile = self.builder.dupe(path) }) catch unreachable; + self.link_objects.append(LinkObject{ + .AssemblyFile = .{ .path = self.builder.dupe(path) }, + }) catch unreachable; } pub fn addAssemblyFileFromWriteFileStep(self: *LibExeObjStep, wfs: *WriteFileStep, basename: []const u8) void { diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index dbd19fbadf..55f044094e 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -205,6 +205,7 @@ pub const TypeInfo = union(enum) { name: []const u8, offset: ?comptime_int, field_type: type, + default_value: var, }; /// This data structure is used by the Zig language code generation and @@ -253,6 +254,7 @@ pub const TypeInfo = union(enum) { tag_type: type, fields: []EnumField, decls: []Declaration, + is_exhaustive: bool, }; /// This data structure is used by the Zig language code generation and diff --git a/lib/std/c.zig b/lib/std/c.zig index 45d0b4db03..c912c72418 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -185,7 +185,7 @@ pub extern "c" fn getaddrinfo( noalias service: [*:0]const u8, noalias hints: *const addrinfo, noalias res: **addrinfo, -) c_int; +) EAI; pub extern "c" fn freeaddrinfo(res: *addrinfo) void; @@ -197,9 +197,9 @@ pub extern "c" fn getnameinfo( noalias serv: [*]u8, servlen: socklen_t, flags: u32, -) c_int; +) EAI; -pub extern "c" fn gai_strerror(errcode: c_int) [*:0]const u8; +pub extern "c" fn gai_strerror(errcode: EAI) [*:0]const u8; pub extern "c" fn poll(fds: [*]pollfd, nfds: nfds_t, timeout: c_int) c_int; diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index bcb5a38ba3..bc58b1fba1 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -70,47 +70,52 @@ pub const AI_NUMERICHOST = 0x00000004; /// prevent service name resolution pub const AI_NUMERICSERV = 0x00001000; -/// address family for hostname not supported -pub const EAI_ADDRFAMILY = 1; +pub const EAI = extern enum(c_int) { + /// address family for hostname not supported + ADDRFAMILY = 1, -/// temporary failure in name resolution -pub const EAI_AGAIN = 2; + /// temporary failure in name resolution + AGAIN = 2, -/// invalid value for ai_flags -pub const EAI_BADFLAGS = 3; + /// invalid value for ai_flags + BADFLAGS = 3, -/// non-recoverable failure in name resolution -pub const EAI_FAIL = 4; + /// non-recoverable failure in name resolution + FAIL = 4, -/// ai_family not supported -pub const EAI_FAMILY = 5; + /// ai_family not supported + FAMILY = 5, -/// memory allocation failure -pub const EAI_MEMORY = 6; + /// memory allocation failure + MEMORY = 6, -/// no address associated with hostname -pub const EAI_NODATA = 7; + /// no address associated with hostname + NODATA = 7, -/// hostname nor servname provided, or not known -pub const EAI_NONAME = 8; + /// hostname nor servname provided, or not known + NONAME = 8, -/// servname not supported for ai_socktype -pub const EAI_SERVICE = 9; + /// servname not supported for ai_socktype + SERVICE = 9, -/// ai_socktype not supported -pub const EAI_SOCKTYPE = 10; + /// ai_socktype not supported + SOCKTYPE = 10, -/// system error returned in errno -pub const EAI_SYSTEM = 11; + /// system error returned in errno + SYSTEM = 11, -/// invalid value for hints -pub const EAI_BADHINTS = 12; + /// invalid value for hints + BADHINTS = 12, -/// resolved protocol is unknown -pub const EAI_PROTOCOL = 13; + /// resolved protocol is unknown + PROTOCOL = 13, + + /// argument buffer overflow + OVERFLOW = 14, + + _, +}; -/// argument buffer overflow -pub const EAI_OVERFLOW = 14; pub const EAI_MAX = 15; pub const pthread_mutex_t = extern struct { diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index 95e27a7d92..4c6614c978 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -23,47 +23,51 @@ pub const pthread_attr_t = extern struct { __align: c_long, }; -/// address family for hostname not supported -pub const EAI_ADDRFAMILY = 1; +pub const EAI = extern enum(c_int) { + /// address family for hostname not supported + ADDRFAMILY = 1, -/// name could not be resolved at this time -pub const EAI_AGAIN = 2; + /// name could not be resolved at this time + AGAIN = 2, -/// flags parameter had an invalid value -pub const EAI_BADFLAGS = 3; + /// flags parameter had an invalid value + BADFLAGS = 3, -/// non-recoverable failure in name resolution -pub const EAI_FAIL = 4; + /// non-recoverable failure in name resolution + FAIL = 4, -/// address family not recognized -pub const EAI_FAMILY = 5; + /// address family not recognized + FAMILY = 5, -/// memory allocation failure -pub const EAI_MEMORY = 6; + /// memory allocation failure + MEMORY = 6, -/// no address associated with hostname -pub const EAI_NODATA = 7; + /// no address associated with hostname + NODATA = 7, -/// name does not resolve -pub const EAI_NONAME = 8; + /// name does not resolve + NONAME = 8, -/// service not recognized for socket type -pub const EAI_SERVICE = 9; + /// service not recognized for socket type + SERVICE = 9, -/// intended socket type was not recognized -pub const EAI_SOCKTYPE = 10; + /// intended socket type was not recognized + SOCKTYPE = 10, -/// system error returned in errno -pub const EAI_SYSTEM = 11; + /// system error returned in errno + SYSTEM = 11, -/// invalid value for hints -pub const EAI_BADHINTS = 12; + /// invalid value for hints + BADHINTS = 12, -/// resolved protocol is unknown -pub const EAI_PROTOCOL = 13; + /// resolved protocol is unknown + PROTOCOL = 13, -/// argument buffer overflow -pub const EAI_OVERFLOW = 14; + /// argument buffer overflow + OVERFLOW = 14, + + _, +}; pub const EAI_MAX = 15; diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index 9969474097..0f7abaaaa0 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -32,25 +32,29 @@ pub const NI_NAMEREQD = 0x08; pub const NI_DGRAM = 0x10; pub const NI_NUMERICSCOPE = 0x100; -pub const EAI_BADFLAGS = -1; -pub const EAI_NONAME = -2; -pub const EAI_AGAIN = -3; -pub const EAI_FAIL = -4; -pub const EAI_FAMILY = -6; -pub const EAI_SOCKTYPE = -7; -pub const EAI_SERVICE = -8; -pub const EAI_MEMORY = -10; -pub const EAI_SYSTEM = -11; -pub const EAI_OVERFLOW = -12; +pub const EAI = extern enum(c_int) { + BADFLAGS = -1, + NONAME = -2, + AGAIN = -3, + FAIL = -4, + FAMILY = -6, + SOCKTYPE = -7, + SERVICE = -8, + MEMORY = -10, + SYSTEM = -11, + OVERFLOW = -12, -pub const EAI_NODATA = -5; -pub const EAI_ADDRFAMILY = -9; -pub const EAI_INPROGRESS = -100; -pub const EAI_CANCELED = -101; -pub const EAI_NOTCANCELED = -102; -pub const EAI_ALLDONE = -103; -pub const EAI_INTR = -104; -pub const EAI_IDN_ENCODE = -105; + NODATA = -5, + ADDRFAMILY = -9, + INPROGRESS = -100, + CANCELED = -101, + NOTCANCELED = -102, + ALLDONE = -103, + INTR = -104, + IDN_ENCODE = -105, + + _, +}; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int; diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index db912ec922..ef64870b8d 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -277,7 +277,7 @@ pub const WindowsDynLib = struct { } pub fn openC(path_c: [*:0]const u8) !WindowsDynLib { - const path_w = try windows.cStrToPrefixedFileW(path); + const path_w = try windows.cStrToPrefixedFileW(path_c); return openW(&path_w); } diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 548ef8ccce..5a650c3b10 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -431,7 +431,7 @@ pub fn formatType( }, else => return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }), }, - .Many => { + .Many, .C => { if (ptr_info.child == u8) { if (fmt.len > 0 and fmt[0] == 's') { const len = mem.len(u8, value); @@ -449,9 +449,6 @@ pub fn formatType( } return format(context, Errors, output, "{}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value.ptr) }); }, - .C => { - return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }); - }, }, .Array => |info| { const Slice = @Type(builtin.TypeInfo{ @@ -1285,8 +1282,16 @@ test "pointer" { } test "cstr" { - try testFmt("cstr: Test C\n", "cstr: {s}\n", .{"Test C"}); - try testFmt("cstr: Test C \n", "cstr: {s:10}\n", .{"Test C"}); + try testFmt( + "cstr: Test C\n", + "cstr: {s}\n", + .{@ptrCast([*c]const u8, "Test C")}, + ); + try testFmt( + "cstr: Test C \n", + "cstr: {s:10}\n", + .{@ptrCast([*c]const u8, "Test C")}, + ); } test "filesize" { diff --git a/lib/std/hash/benchmark.zig b/lib/std/hash/benchmark.zig index ce9ed75b58..c792013e06 100644 --- a/lib/std/hash/benchmark.zig +++ b/lib/std/hash/benchmark.zig @@ -47,11 +47,11 @@ const hashes = [_]Hash{ .name = "adler32", }, Hash{ - .ty = hash.crc.Crc32WithPoly(hash.crc.Polynomial.IEEE), + .ty = hash.crc.Crc32WithPoly(.IEEE), .name = "crc32-slicing-by-8", }, Hash{ - .ty = hash.crc.Crc32SmallWithPoly(hash.crc.Polynomial.IEEE), + .ty = hash.crc.Crc32SmallWithPoly(.IEEE), .name = "crc32-half-byte-lookup", }, Hash{ diff --git a/lib/std/hash/crc.zig b/lib/std/hash/crc.zig index 6176ded81d..506d8c8aed 100644 --- a/lib/std/hash/crc.zig +++ b/lib/std/hash/crc.zig @@ -9,17 +9,18 @@ const std = @import("../std.zig"); const debug = std.debug; const testing = std.testing; -pub const Polynomial = struct { - pub const IEEE = 0xedb88320; - pub const Castagnoli = 0x82f63b78; - pub const Koopman = 0xeb31d82e; +pub const Polynomial = enum(u32) { + IEEE = 0xedb88320, + Castagnoli = 0x82f63b78, + Koopman = 0xeb31d82e, + _, }; // IEEE is by far the most common CRC and so is aliased by default. -pub const Crc32 = Crc32WithPoly(Polynomial.IEEE); +pub const Crc32 = Crc32WithPoly(.IEEE); // slicing-by-8 crc32 implementation. -pub fn Crc32WithPoly(comptime poly: u32) type { +pub fn Crc32WithPoly(comptime poly: Polynomial) type { return struct { const Self = @This(); const lookup_tables = comptime block: { @@ -31,7 +32,7 @@ pub fn Crc32WithPoly(comptime poly: u32) type { var j: usize = 0; while (j < 8) : (j += 1) { if (crc & 1 == 1) { - crc = (crc >> 1) ^ poly; + crc = (crc >> 1) ^ @enumToInt(poly); } else { crc = (crc >> 1); } @@ -100,7 +101,7 @@ pub fn Crc32WithPoly(comptime poly: u32) type { } test "crc32 ieee" { - const Crc32Ieee = Crc32WithPoly(Polynomial.IEEE); + const Crc32Ieee = Crc32WithPoly(.IEEE); testing.expect(Crc32Ieee.hash("") == 0x00000000); testing.expect(Crc32Ieee.hash("a") == 0xe8b7be43); @@ -108,7 +109,7 @@ test "crc32 ieee" { } test "crc32 castagnoli" { - const Crc32Castagnoli = Crc32WithPoly(Polynomial.Castagnoli); + const Crc32Castagnoli = Crc32WithPoly(.Castagnoli); testing.expect(Crc32Castagnoli.hash("") == 0x00000000); testing.expect(Crc32Castagnoli.hash("a") == 0xc1d04330); @@ -116,7 +117,7 @@ test "crc32 castagnoli" { } // half-byte lookup table implementation. -pub fn Crc32SmallWithPoly(comptime poly: u32) type { +pub fn Crc32SmallWithPoly(comptime poly: Polynomial) type { return struct { const Self = @This(); const lookup_table = comptime block: { @@ -127,7 +128,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type { var j: usize = 0; while (j < 8) : (j += 1) { if (crc & 1 == 1) { - crc = (crc >> 1) ^ poly; + crc = (crc >> 1) ^ @enumToInt(poly); } else { crc = (crc >> 1); } @@ -164,7 +165,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type { } test "small crc32 ieee" { - const Crc32Ieee = Crc32SmallWithPoly(Polynomial.IEEE); + const Crc32Ieee = Crc32SmallWithPoly(.IEEE); testing.expect(Crc32Ieee.hash("") == 0x00000000); testing.expect(Crc32Ieee.hash("a") == 0xe8b7be43); @@ -172,7 +173,7 @@ test "small crc32 ieee" { } test "small crc32 castagnoli" { - const Crc32Castagnoli = Crc32SmallWithPoly(Polynomial.Castagnoli); + const Crc32Castagnoli = Crc32SmallWithPoly(.Castagnoli); testing.expect(Crc32Castagnoli.hash("") == 0x00000000); testing.expect(Crc32Castagnoli.hash("a") == 0xc1d04330); diff --git a/lib/std/net.zig b/lib/std/net.zig index 47ce95c99f..c113462855 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -452,18 +452,18 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* }; var res: *os.addrinfo = undefined; switch (os.system.getaddrinfo(name_c.ptr, @ptrCast([*:0]const u8, port_c.ptr), &hints, &res)) { - 0 => {}, - c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses, - c.EAI_AGAIN => return error.TemporaryNameServerFailure, - c.EAI_BADFLAGS => unreachable, // Invalid hints - c.EAI_FAIL => return error.NameServerFailure, - c.EAI_FAMILY => return error.AddressFamilyNotSupported, - c.EAI_MEMORY => return error.OutOfMemory, - c.EAI_NODATA => return error.HostLacksNetworkAddresses, - c.EAI_NONAME => return error.UnknownHostName, - c.EAI_SERVICE => return error.ServiceUnavailable, - c.EAI_SOCKTYPE => unreachable, // Invalid socket type requested in hints - c.EAI_SYSTEM => switch (os.errno(-1)) { + @intToEnum(os.system.EAI, 0) => {}, + .ADDRFAMILY => return error.HostLacksNetworkAddresses, + .AGAIN => return error.TemporaryNameServerFailure, + .BADFLAGS => unreachable, // Invalid hints + .FAIL => return error.NameServerFailure, + .FAMILY => return error.AddressFamilyNotSupported, + .MEMORY => return error.OutOfMemory, + .NODATA => return error.HostLacksNetworkAddresses, + .NONAME => return error.UnknownHostName, + .SERVICE => return error.ServiceUnavailable, + .SOCKTYPE => unreachable, // Invalid socket type requested in hints + .SYSTEM => switch (os.errno(-1)) { else => |e| return os.unexpectedErrno(e), }, else => unreachable, diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 51ea49005e..f4024e1f1d 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -18,7 +18,7 @@ pub usingnamespace switch (builtin.arch) { else => struct {}, }; -const is_mips = builtin.arch == .mipsel; +const is_mips = builtin.arch.isMIPS(); pub const pid_t = i32; pub const fd_t = i32; diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index 2128883545..90dbf0cdf4 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -16,42 +16,42 @@ comptime { else => {}, } - @export(@import("compiler_rt/comparesf2.zig").__lesf2, .{ .name = "__lesf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__ledf2, .{ .name = "__ledf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__letf2, .{ .name = "__letf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__lesf2, .{ .name = "__lesf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__ledf2, .{ .name = "__ledf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__letf2, .{ .name = "__letf2", .linkage = linkage }); - @export(@import("compiler_rt/comparesf2.zig").__gesf2, .{ .name = "__gesf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__gedf2, .{ .name = "__gedf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__getf2, .{ .name = "__getf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__gesf2, .{ .name = "__gesf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__gedf2, .{ .name = "__gedf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__getf2, .{ .name = "__getf2", .linkage = linkage }); if (!is_test) { - @export(@import("compiler_rt/comparesf2.zig").__lesf2, .{ .name = "__cmpsf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__ledf2, .{ .name = "__cmpdf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__letf2, .{ .name = "__cmptf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__lesf2, .{ .name = "__cmpsf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__ledf2, .{ .name = "__cmpdf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__letf2, .{ .name = "__cmptf2", .linkage = linkage }); - @export(@import("compiler_rt/comparesf2.zig").__eqsf2, .{ .name = "__eqsf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__eqdf2, .{ .name = "__eqdf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__letf2, .{ .name = "__eqtf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__eqsf2, .{ .name = "__eqsf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__eqdf2, .{ .name = "__eqdf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__letf2, .{ .name = "__eqtf2", .linkage = linkage }); - @export(@import("compiler_rt/comparesf2.zig").__ltsf2, .{ .name = "__ltsf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__ltdf2, .{ .name = "__ltdf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__letf2, .{ .name = "__lttf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__ltsf2, .{ .name = "__ltsf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__ltdf2, .{ .name = "__ltdf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__letf2, .{ .name = "__lttf2", .linkage = linkage }); - @export(@import("compiler_rt/comparesf2.zig").__nesf2, .{ .name = "__nesf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__nedf2, .{ .name = "__nedf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__letf2, .{ .name = "__netf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__nesf2, .{ .name = "__nesf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__nedf2, .{ .name = "__nedf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__letf2, .{ .name = "__netf2", .linkage = linkage }); - @export(@import("compiler_rt/comparesf2.zig").__gtsf2, .{ .name = "__gtsf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__gtdf2, .{ .name = "__gtdf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__getf2, .{ .name = "__gttf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__gtsf2, .{ .name = "__gtsf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__gtdf2, .{ .name = "__gtdf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__getf2, .{ .name = "__gttf2", .linkage = linkage }); @export(@import("compiler_rt/extendXfYf2.zig").__extendhfsf2, .{ .name = "__gnu_h2f_ieee", .linkage = linkage }); @export(@import("compiler_rt/truncXfYf2.zig").__truncsfhf2, .{ .name = "__gnu_f2h_ieee", .linkage = linkage }); } - @export(@import("compiler_rt/comparesf2.zig").__unordsf2, .{ .name = "__unordsf2", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__unorddf2, .{ .name = "__unorddf2", .linkage = linkage }); - @export(@import("compiler_rt/comparetf2.zig").__unordtf2, .{ .name = "__unordtf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__unordsf2, .{ .name = "__unordsf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__unorddf2, .{ .name = "__unorddf2", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__unordtf2, .{ .name = "__unordtf2", .linkage = linkage }); @export(@import("compiler_rt/addXf3.zig").__addsf3, .{ .name = "__addsf3", .linkage = linkage }); @export(@import("compiler_rt/addXf3.zig").__adddf3, .{ .name = "__adddf3", .linkage = linkage }); @@ -146,8 +146,10 @@ comptime { @export(@import("compiler_rt/negXf2.zig").__negsf2, .{ .name = "__negsf2", .linkage = linkage }); @export(@import("compiler_rt/negXf2.zig").__negdf2, .{ .name = "__negdf2", .linkage = linkage }); - if (is_arm_arch and !is_arm_64 and !is_test) { - @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = strong_linkage }); + @export(@import("compiler_rt/clzsi2.zig").__clzsi2, .{ .name = "__clzsi2", .linkage = linkage }); + + if (builtin.arch.isARM() and !is_test) { + @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = linkage }); @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage }); @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage }); @@ -177,7 +179,9 @@ comptime { @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage }); @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage }); - @export(@import("compiler_rt/arm.zig").__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage }); + if (builtin.os == .linux) { + @export(@import("compiler_rt/arm.zig").__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage }); + } @export(@import("compiler_rt/extendXfYf2.zig").__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage }); @export(@import("compiler_rt/floatsiXf.zig").__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage }); @@ -222,20 +226,29 @@ comptime { @export(@import("compiler_rt/divsf3.zig").__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage }); @export(@import("compiler_rt/divdf3.zig").__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = linkage }); - @export(@import("compiler_rt/comparesf2.zig").__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = linkage }); - - @export(@import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = linkage }); - @export(@import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = linkage }); - @export(@import("compiler_rt/comparedf2.zig").__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmpge, .{ .name = "__aeabi_fcmpge", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmpgt, .{ .name = "__aeabi_fcmpgt", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmpun, .{ .name = "__aeabi_fcmpun", .linkage = linkage }); + + @export(@import("compiler_rt/compareXf2.zig").__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_dcmpge, .{ .name = "__aeabi_dcmpge", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_dcmpgt, .{ .name = "__aeabi_dcmpgt", .linkage = linkage }); + @export(@import("compiler_rt/compareXf2.zig").__aeabi_dcmpun, .{ .name = "__aeabi_dcmpun", .linkage = linkage }); + } + + if (builtin.arch == .i386 and builtin.abi == .msvc) { + // Don't let LLVM apply the stdcall name mangling on those MSVC builtins + @export(@import("compiler_rt/aulldiv.zig")._alldiv, .{ .name = "\x01__alldiv", .linkage = strong_linkage }); + @export(@import("compiler_rt/aulldiv.zig")._aulldiv, .{ .name = "\x01__aulldiv", .linkage = strong_linkage }); + @export(@import("compiler_rt/aullrem.zig")._allrem, .{ .name = "\x01__allrem", .linkage = strong_linkage }); + @export(@import("compiler_rt/aullrem.zig")._aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); } + if (builtin.os == .windows) { // Default stack-probe functions emitted by LLVM if (is_mingw) { @@ -254,13 +267,6 @@ comptime { switch (builtin.arch) { .i386 => { - // Don't let LLVM apply the stdcall name mangling on those MSVC - // builtin functions - @export(@import("compiler_rt/aulldiv.zig")._alldiv, .{ .name = "\x01__alldiv", .linkage = strong_linkage }); - @export(@import("compiler_rt/aulldiv.zig")._aulldiv, .{ .name = "\x01__aulldiv", .linkage = strong_linkage }); - @export(@import("compiler_rt/aullrem.zig")._allrem, .{ .name = "\x01__allrem", .linkage = strong_linkage }); - @export(@import("compiler_rt/aullrem.zig")._aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); - @export(@import("compiler_rt/divti3.zig").__divti3, .{ .name = "__divti3", .linkage = linkage }); @export(@import("compiler_rt/modti3.zig").__modti3, .{ .name = "__modti3", .linkage = linkage }); @export(@import("compiler_rt/multi3.zig").__multi3, .{ .name = "__multi3", .linkage = linkage }); @@ -295,16 +301,12 @@ comptime { @export(@import("compiler_rt/mulodi4.zig").__mulodi4, .{ .name = "__mulodi4", .linkage = linkage }); } -const std = @import("std"); -const assert = std.debug.assert; -const testing = std.testing; - // Avoid dragging in the runtime safety mechanisms into this .o file, // unless we're trying to test this file. pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { @setCold(true); if (is_test) { - std.debug.panic("{}", .{msg}); + @import("std").debug.panic("{}", .{msg}); } else { unreachable; } @@ -320,23 +322,3 @@ extern var __stack_chk_guard: usize = blk: { buf[@sizeOf(usize) - 2] = '\n'; break :blk @bitCast(usize, buf); }; - -const is_arm_64 = switch (builtin.arch) { - builtin.Arch.aarch64, - builtin.Arch.aarch64_be, - => true, - else => false, -}; - -const is_arm_arch = switch (builtin.arch) { - builtin.Arch.arm, - builtin.Arch.armeb, - builtin.Arch.aarch64, - builtin.Arch.aarch64_be, - builtin.Arch.thumb, - builtin.Arch.thumbeb, - => true, - else => false, -}; - -const is_arm_32 = is_arm_arch and !is_arm_64; diff --git a/lib/std/special/compiler_rt/arm.zig b/lib/std/special/compiler_rt/arm.zig index 9ba423931b..5e718ed4c4 100644 --- a/lib/std/special/compiler_rt/arm.zig +++ b/lib/std/special/compiler_rt/arm.zig @@ -1,6 +1,5 @@ // ARM specific builtins const builtin = @import("builtin"); -const is_test = builtin.is_test; const __divmodsi4 = @import("int.zig").__divmodsi4; const __udivmodsi4 = @import("int.zig").__udivmodsi4; @@ -33,18 +32,14 @@ pub fn __aeabi_memclr(dest: [*]u8, n: usize) callconv(.AAPCS) void { _ = memset(dest, 0, n); } -pub fn __aeabi_unwind_cpp_pr0() callconv(.C) void { - unreachable; -} -pub fn __aeabi_unwind_cpp_pr1() callconv(.C) void { - unreachable; -} -pub fn __aeabi_unwind_cpp_pr2() callconv(.C) void { - unreachable; -} +// Dummy functions to avoid errors during the linking phase +pub fn __aeabi_unwind_cpp_pr0() callconv(.C) void {} +pub fn __aeabi_unwind_cpp_pr1() callconv(.C) void {} +pub fn __aeabi_unwind_cpp_pr2() callconv(.C) void {} // This function can only clobber r0 according to the ABI pub fn __aeabi_read_tp() callconv(.Naked) void { + @setRuntimeSafety(false); asm volatile ( \\ mrc p15, 0, r0, c13, c0, 3 \\ bx lr @@ -56,6 +51,7 @@ pub fn __aeabi_read_tp() callconv(.Naked) void { // calling convention is always respected pub fn __aeabi_uidivmod() callconv(.Naked) void { + @setRuntimeSafety(false); // Divide r0 by r1; the quotient goes in r0, the remainder in r1 asm volatile ( \\ push {lr} @@ -73,6 +69,7 @@ pub fn __aeabi_uidivmod() callconv(.Naked) void { } pub fn __aeabi_uldivmod() callconv(.Naked) void { + @setRuntimeSafety(false); // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2 asm volatile ( \\ push {r4, lr} @@ -92,6 +89,7 @@ pub fn __aeabi_uldivmod() callconv(.Naked) void { } pub fn __aeabi_idivmod() callconv(.Naked) void { + @setRuntimeSafety(false); // Divide r0 by r1; the quotient goes in r0, the remainder in r1 asm volatile ( \\ push {lr} @@ -109,6 +107,7 @@ pub fn __aeabi_idivmod() callconv(.Naked) void { } pub fn __aeabi_ldivmod() callconv(.Naked) void { + @setRuntimeSafety(false); // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2 asm volatile ( \\ push {r4, lr} diff --git a/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig b/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig deleted file mode 100644 index a8ed182901..0000000000 --- a/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig +++ /dev/null @@ -1,95 +0,0 @@ -// Ported from: -// -// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/arm/aeabi_dcmp.S - -const ConditionalOperator = enum { - Eq, - Lt, - Le, - Ge, - Gt, -}; - -pub fn __aeabi_dcmpeq() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq}); - unreachable; -} - -pub fn __aeabi_dcmplt() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt}); - unreachable; -} - -pub fn __aeabi_dcmple() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le}); - unreachable; -} - -pub fn __aeabi_dcmpge() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge}); - unreachable; -} - -pub fn __aeabi_dcmpgt() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt}); - unreachable; -} - -fn aeabi_dcmp(comptime cond: ConditionalOperator) void { - @setRuntimeSafety(false); - asm volatile ( - \\ push { r4, lr } - ); - - switch (cond) { - .Eq => asm volatile ( - \\ bl __eqdf2 - \\ cmp r0, #0 - \\ beq 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Lt => asm volatile ( - \\ bl __ltdf2 - \\ cmp r0, #0 - \\ blt 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Le => asm volatile ( - \\ bl __ledf2 - \\ cmp r0, #0 - \\ ble 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Ge => asm volatile ( - \\ bl __ltdf2 - \\ cmp r0, #0 - \\ bge 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Gt => asm volatile ( - \\ bl __gtdf2 - \\ cmp r0, #0 - \\ bgt 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - } - asm volatile ( - \\ movs r0, #1 - \\ pop { r4, pc } - ); -} diff --git a/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig b/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig deleted file mode 100644 index 0b4c0f0d41..0000000000 --- a/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig +++ /dev/null @@ -1,95 +0,0 @@ -// Ported from: -// -// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/arm/aeabi_fcmp.S - -const ConditionalOperator = enum { - Eq, - Lt, - Le, - Ge, - Gt, -}; - -pub fn __aeabi_fcmpeq() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq}); - unreachable; -} - -pub fn __aeabi_fcmplt() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt}); - unreachable; -} - -pub fn __aeabi_fcmple() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le}); - unreachable; -} - -pub fn __aeabi_fcmpge() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge}); - unreachable; -} - -pub fn __aeabi_fcmpgt() callconv(.Naked) noreturn { - @setRuntimeSafety(false); - @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt}); - unreachable; -} - -fn aeabi_fcmp(comptime cond: ConditionalOperator) void { - @setRuntimeSafety(false); - asm volatile ( - \\ push { r4, lr } - ); - - switch (cond) { - .Eq => asm volatile ( - \\ bl __eqsf2 - \\ cmp r0, #0 - \\ beq 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Lt => asm volatile ( - \\ bl __ltsf2 - \\ cmp r0, #0 - \\ blt 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Le => asm volatile ( - \\ bl __lesf2 - \\ cmp r0, #0 - \\ ble 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Ge => asm volatile ( - \\ bl __ltsf2 - \\ cmp r0, #0 - \\ bge 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - .Gt => asm volatile ( - \\ bl __gtsf2 - \\ cmp r0, #0 - \\ bgt 1f - \\ movs r0, #0 - \\ pop { r4, pc } - \\ 1: - ), - } - asm volatile ( - \\ movs r0, #1 - \\ pop { r4, pc } - ); -} diff --git a/lib/std/special/compiler_rt/clzsi2.zig b/lib/std/special/compiler_rt/clzsi2.zig new file mode 100644 index 0000000000..6a69ae75f1 --- /dev/null +++ b/lib/std/special/compiler_rt/clzsi2.zig @@ -0,0 +1,116 @@ +const builtin = @import("builtin"); + +fn __clzsi2_generic(a: i32) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + + var x = @bitCast(u32, a); + var n: i32 = 32; + + // Count first bit set using binary search, from Hacker's Delight + var y: u32 = 0; + inline for ([_]i32{ 16, 8, 4, 2, 1 }) |shift| { + y = x >> shift; + if (y != 0) { + n = n - shift; + x = y; + } + } + + return n - @bitCast(i32, x); +} + +fn __clzsi2_thumb1() callconv(.Naked) void { + @setRuntimeSafety(builtin.is_test); + + // Similar to the generic version with the last two rounds replaced by a LUT + asm volatile ( + \\ movs r1, #32 + \\ lsrs r2, r0, #16 + \\ beq 1f + \\ subs r1, #16 + \\ movs r0, r2 + \\ 1: + \\ lsrs r2, r0, #8 + \\ beq 1f + \\ subs r1, #8 + \\ movs r0, r2 + \\ 1: + \\ lsrs r2, r0, #4 + \\ beq 1f + \\ subs r1, #4 + \\ movs r0, r2 + \\ 1: + \\ ldr r3, =LUT + \\ ldrb r0, [r3, r0] + \\ subs r0, r1, r0 + \\ bx lr + \\ .p2align 2 + \\ LUT: + \\ .byte 4,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 + ); + + unreachable; +} + +fn __clzsi2_arm32() callconv(.Naked) void { + @setRuntimeSafety(builtin.is_test); + + asm volatile ( + \\ // Assumption: n != 0 + \\ // r0: n + \\ // r1: count of leading zeros in n + 1 + \\ // r2: scratch register for shifted r0 + \\ mov r1, #1 + \\ + \\ // Basic block: + \\ // if ((r0 >> SHIFT) == 0) + \\ // r1 += SHIFT; + \\ // else + \\ // r0 >>= SHIFT; + \\ // for descending powers of two as SHIFT. + \\ lsrs r2, r0, #16 + \\ movne r0, r2 + \\ addeq r1, #16 + \\ + \\ lsrs r2, r0, #8 + \\ movne r0, r2 + \\ addeq r1, #8 + \\ + \\ lsrs r2, r0, #4 + \\ movne r0, r2 + \\ addeq r1, #4 + \\ + \\ lsrs r2, r0, #2 + \\ movne r0, r2 + \\ addeq r1, #2 + \\ + \\ // The basic block invariants at this point are (r0 >> 2) == 0 and + \\ // r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1. + \\ // + \\ // r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)f + \\ // ---+----------------+----------------+------------+-------------- + \\ // 1 | 1 | 0 | 0 | 1 + \\ // 2 | 0 | 1 | -1 | 0 + \\ // 3 | 0 | 1 | -1 | 0 + \\ // + \\ // The r1's initial value of 1 compensates for the 1 here. + \\ sub r0, r1, r0, lsr #1 + \\ bx lr + ); + + unreachable; +} + +pub const __clzsi2 = blk: { + if (builtin.arch.isARM()) { + break :blk __clzsi2_arm32; + } else if (builtin.arch.isThumb()) { + break :blk __clzsi2_thumb1; + } else { + break :blk __clzsi2_generic; + } +}; + +test "test clzsi2" { + _ = @import("clzsi2_test.zig"); +} diff --git a/lib/std/special/compiler_rt/clzsi2_test.zig b/lib/std/special/compiler_rt/clzsi2_test.zig new file mode 100644 index 0000000000..ff94455846 --- /dev/null +++ b/lib/std/special/compiler_rt/clzsi2_test.zig @@ -0,0 +1,292 @@ +const clzsi2 = @import("clzsi2.zig"); +const testing = @import("std").testing; + +fn test__clzsi2(a: u32, expected: i32) void { + var nakedClzsi2 = clzsi2.__clzsi2; + var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2); + var x = @intCast(i32, a); + var result = actualClzsi2(x); + testing.expectEqual(expected, result); +} + +test "clzsi2" { + test__clzsi2(0x00800000, 8); + test__clzsi2(0x01000000, 7); + test__clzsi2(0x02000000, 6); + test__clzsi2(0x03000000, 6); + test__clzsi2(0x04000000, 5); + test__clzsi2(0x05000000, 5); + test__clzsi2(0x06000000, 5); + test__clzsi2(0x07000000, 5); + test__clzsi2(0x08000000, 4); + test__clzsi2(0x09000000, 4); + test__clzsi2(0x0A000000, 4); + test__clzsi2(0x0B000000, 4); + test__clzsi2(0x0C000000, 4); + test__clzsi2(0x0D000000, 4); + test__clzsi2(0x0E000000, 4); + test__clzsi2(0x0F000000, 4); + test__clzsi2(0x10000000, 3); + test__clzsi2(0x11000000, 3); + test__clzsi2(0x12000000, 3); + test__clzsi2(0x13000000, 3); + test__clzsi2(0x14000000, 3); + test__clzsi2(0x15000000, 3); + test__clzsi2(0x16000000, 3); + test__clzsi2(0x17000000, 3); + test__clzsi2(0x18000000, 3); + test__clzsi2(0x19000000, 3); + test__clzsi2(0x1A000000, 3); + test__clzsi2(0x1B000000, 3); + test__clzsi2(0x1C000000, 3); + test__clzsi2(0x1D000000, 3); + test__clzsi2(0x1E000000, 3); + test__clzsi2(0x1F000000, 3); + test__clzsi2(0x20000000, 2); + test__clzsi2(0x21000000, 2); + test__clzsi2(0x22000000, 2); + test__clzsi2(0x23000000, 2); + test__clzsi2(0x24000000, 2); + test__clzsi2(0x25000000, 2); + test__clzsi2(0x26000000, 2); + test__clzsi2(0x27000000, 2); + test__clzsi2(0x28000000, 2); + test__clzsi2(0x29000000, 2); + test__clzsi2(0x2A000000, 2); + test__clzsi2(0x2B000000, 2); + test__clzsi2(0x2C000000, 2); + test__clzsi2(0x2D000000, 2); + test__clzsi2(0x2E000000, 2); + test__clzsi2(0x2F000000, 2); + test__clzsi2(0x30000000, 2); + test__clzsi2(0x31000000, 2); + test__clzsi2(0x32000000, 2); + test__clzsi2(0x33000000, 2); + test__clzsi2(0x34000000, 2); + test__clzsi2(0x35000000, 2); + test__clzsi2(0x36000000, 2); + test__clzsi2(0x37000000, 2); + test__clzsi2(0x38000000, 2); + test__clzsi2(0x39000000, 2); + test__clzsi2(0x3A000000, 2); + test__clzsi2(0x3B000000, 2); + test__clzsi2(0x3C000000, 2); + test__clzsi2(0x3D000000, 2); + test__clzsi2(0x3E000000, 2); + test__clzsi2(0x3F000000, 2); + test__clzsi2(0x40000000, 1); + test__clzsi2(0x41000000, 1); + test__clzsi2(0x42000000, 1); + test__clzsi2(0x43000000, 1); + test__clzsi2(0x44000000, 1); + test__clzsi2(0x45000000, 1); + test__clzsi2(0x46000000, 1); + test__clzsi2(0x47000000, 1); + test__clzsi2(0x48000000, 1); + test__clzsi2(0x49000000, 1); + test__clzsi2(0x4A000000, 1); + test__clzsi2(0x4B000000, 1); + test__clzsi2(0x4C000000, 1); + test__clzsi2(0x4D000000, 1); + test__clzsi2(0x4E000000, 1); + test__clzsi2(0x4F000000, 1); + test__clzsi2(0x50000000, 1); + test__clzsi2(0x51000000, 1); + test__clzsi2(0x52000000, 1); + test__clzsi2(0x53000000, 1); + test__clzsi2(0x54000000, 1); + test__clzsi2(0x55000000, 1); + test__clzsi2(0x56000000, 1); + test__clzsi2(0x57000000, 1); + test__clzsi2(0x58000000, 1); + test__clzsi2(0x59000000, 1); + test__clzsi2(0x5A000000, 1); + test__clzsi2(0x5B000000, 1); + test__clzsi2(0x5C000000, 1); + test__clzsi2(0x5D000000, 1); + test__clzsi2(0x5E000000, 1); + test__clzsi2(0x5F000000, 1); + test__clzsi2(0x60000000, 1); + test__clzsi2(0x61000000, 1); + test__clzsi2(0x62000000, 1); + test__clzsi2(0x63000000, 1); + test__clzsi2(0x64000000, 1); + test__clzsi2(0x65000000, 1); + test__clzsi2(0x66000000, 1); + test__clzsi2(0x67000000, 1); + test__clzsi2(0x68000000, 1); + test__clzsi2(0x69000000, 1); + test__clzsi2(0x6A000000, 1); + test__clzsi2(0x6B000000, 1); + test__clzsi2(0x6C000000, 1); + test__clzsi2(0x6D000000, 1); + test__clzsi2(0x6E000000, 1); + test__clzsi2(0x6F000000, 1); + test__clzsi2(0x70000000, 1); + test__clzsi2(0x71000000, 1); + test__clzsi2(0x72000000, 1); + test__clzsi2(0x73000000, 1); + test__clzsi2(0x74000000, 1); + test__clzsi2(0x75000000, 1); + test__clzsi2(0x76000000, 1); + test__clzsi2(0x77000000, 1); + test__clzsi2(0x78000000, 1); + test__clzsi2(0x79000000, 1); + test__clzsi2(0x7A000000, 1); + test__clzsi2(0x7B000000, 1); + test__clzsi2(0x7C000000, 1); + test__clzsi2(0x7D000000, 1); + test__clzsi2(0x7E000000, 1); + test__clzsi2(0x7F000000, 1); + test__clzsi2(0x80000000, 0); + test__clzsi2(0x81000000, 0); + test__clzsi2(0x82000000, 0); + test__clzsi2(0x83000000, 0); + test__clzsi2(0x84000000, 0); + test__clzsi2(0x85000000, 0); + test__clzsi2(0x86000000, 0); + test__clzsi2(0x87000000, 0); + test__clzsi2(0x88000000, 0); + test__clzsi2(0x89000000, 0); + test__clzsi2(0x8A000000, 0); + test__clzsi2(0x8B000000, 0); + test__clzsi2(0x8C000000, 0); + test__clzsi2(0x8D000000, 0); + test__clzsi2(0x8E000000, 0); + test__clzsi2(0x8F000000, 0); + test__clzsi2(0x90000000, 0); + test__clzsi2(0x91000000, 0); + test__clzsi2(0x92000000, 0); + test__clzsi2(0x93000000, 0); + test__clzsi2(0x94000000, 0); + test__clzsi2(0x95000000, 0); + test__clzsi2(0x96000000, 0); + test__clzsi2(0x97000000, 0); + test__clzsi2(0x98000000, 0); + test__clzsi2(0x99000000, 0); + test__clzsi2(0x9A000000, 0); + test__clzsi2(0x9B000000, 0); + test__clzsi2(0x9C000000, 0); + test__clzsi2(0x9D000000, 0); + test__clzsi2(0x9E000000, 0); + test__clzsi2(0x9F000000, 0); + test__clzsi2(0xA0000000, 0); + test__clzsi2(0xA1000000, 0); + test__clzsi2(0xA2000000, 0); + test__clzsi2(0xA3000000, 0); + test__clzsi2(0xA4000000, 0); + test__clzsi2(0xA5000000, 0); + test__clzsi2(0xA6000000, 0); + test__clzsi2(0xA7000000, 0); + test__clzsi2(0xA8000000, 0); + test__clzsi2(0xA9000000, 0); + test__clzsi2(0xAA000000, 0); + test__clzsi2(0xAB000000, 0); + test__clzsi2(0xAC000000, 0); + test__clzsi2(0xAD000000, 0); + test__clzsi2(0xAE000000, 0); + test__clzsi2(0xAF000000, 0); + test__clzsi2(0xB0000000, 0); + test__clzsi2(0xB1000000, 0); + test__clzsi2(0xB2000000, 0); + test__clzsi2(0xB3000000, 0); + test__clzsi2(0xB4000000, 0); + test__clzsi2(0xB5000000, 0); + test__clzsi2(0xB6000000, 0); + test__clzsi2(0xB7000000, 0); + test__clzsi2(0xB8000000, 0); + test__clzsi2(0xB9000000, 0); + test__clzsi2(0xBA000000, 0); + test__clzsi2(0xBB000000, 0); + test__clzsi2(0xBC000000, 0); + test__clzsi2(0xBD000000, 0); + test__clzsi2(0xBE000000, 0); + test__clzsi2(0xBF000000, 0); + test__clzsi2(0xC0000000, 0); + test__clzsi2(0xC1000000, 0); + test__clzsi2(0xC2000000, 0); + test__clzsi2(0xC3000000, 0); + test__clzsi2(0xC4000000, 0); + test__clzsi2(0xC5000000, 0); + test__clzsi2(0xC6000000, 0); + test__clzsi2(0xC7000000, 0); + test__clzsi2(0xC8000000, 0); + test__clzsi2(0xC9000000, 0); + test__clzsi2(0xCA000000, 0); + test__clzsi2(0xCB000000, 0); + test__clzsi2(0xCC000000, 0); + test__clzsi2(0xCD000000, 0); + test__clzsi2(0xCE000000, 0); + test__clzsi2(0xCF000000, 0); + test__clzsi2(0xD0000000, 0); + test__clzsi2(0xD1000000, 0); + test__clzsi2(0xD2000000, 0); + test__clzsi2(0xD3000000, 0); + test__clzsi2(0xD4000000, 0); + test__clzsi2(0xD5000000, 0); + test__clzsi2(0xD6000000, 0); + test__clzsi2(0xD7000000, 0); + test__clzsi2(0xD8000000, 0); + test__clzsi2(0xD9000000, 0); + test__clzsi2(0xDA000000, 0); + test__clzsi2(0xDB000000, 0); + test__clzsi2(0xDC000000, 0); + test__clzsi2(0xDD000000, 0); + test__clzsi2(0xDE000000, 0); + test__clzsi2(0xDF000000, 0); + test__clzsi2(0xE0000000, 0); + test__clzsi2(0xE1000000, 0); + test__clzsi2(0xE2000000, 0); + test__clzsi2(0xE3000000, 0); + test__clzsi2(0xE4000000, 0); + test__clzsi2(0xE5000000, 0); + test__clzsi2(0xE6000000, 0); + test__clzsi2(0xE7000000, 0); + test__clzsi2(0xE8000000, 0); + test__clzsi2(0xE9000000, 0); + test__clzsi2(0xEA000000, 0); + test__clzsi2(0xEB000000, 0); + test__clzsi2(0xEC000000, 0); + test__clzsi2(0xED000000, 0); + test__clzsi2(0xEE000000, 0); + test__clzsi2(0xEF000000, 0); + test__clzsi2(0xF0000000, 0); + test__clzsi2(0xF1000000, 0); + test__clzsi2(0xF2000000, 0); + test__clzsi2(0xF3000000, 0); + test__clzsi2(0xF4000000, 0); + test__clzsi2(0xF5000000, 0); + test__clzsi2(0xF6000000, 0); + test__clzsi2(0xF7000000, 0); + test__clzsi2(0xF8000000, 0); + test__clzsi2(0xF9000000, 0); + test__clzsi2(0xFA000000, 0); + test__clzsi2(0xFB000000, 0); + test__clzsi2(0xFC000000, 0); + test__clzsi2(0xFD000000, 0); + test__clzsi2(0xFE000000, 0); + test__clzsi2(0xFF000000, 0); + test__clzsi2(0x00000001, 31); + test__clzsi2(0x00000002, 30); + test__clzsi2(0x00000004, 29); + test__clzsi2(0x00000008, 28); + test__clzsi2(0x00000010, 27); + test__clzsi2(0x00000020, 26); + test__clzsi2(0x00000040, 25); + test__clzsi2(0x00000080, 24); + test__clzsi2(0x00000100, 23); + test__clzsi2(0x00000200, 22); + test__clzsi2(0x00000400, 21); + test__clzsi2(0x00000800, 20); + test__clzsi2(0x00001000, 19); + test__clzsi2(0x00002000, 18); + test__clzsi2(0x00004000, 17); + test__clzsi2(0x00008000, 16); + test__clzsi2(0x00010000, 15); + test__clzsi2(0x00020000, 14); + test__clzsi2(0x00040000, 13); + test__clzsi2(0x00080000, 12); + test__clzsi2(0x00100000, 11); + test__clzsi2(0x00200000, 10); + test__clzsi2(0x00400000, 9); +} diff --git a/lib/std/special/compiler_rt/compareXf2.zig b/lib/std/special/compiler_rt/compareXf2.zig new file mode 100644 index 0000000000..15e49e3cc1 --- /dev/null +++ b/lib/std/special/compiler_rt/compareXf2.zig @@ -0,0 +1,253 @@ +// Ported from: +// +// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/comparesf2.c + +const std = @import("std"); +const builtin = @import("builtin"); + +const LE = extern enum(i32) { + Less = -1, + Equal = 0, + Greater = 1, + Unordered = 1, +}; + +const GE = extern enum(i32) { + Less = -1, + Equal = 0, + Greater = 1, + Unordered = -1, +}; + +pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT { + @setRuntimeSafety(builtin.is_test); + + const srep_t = @IntType(true, T.bit_count); + const rep_t = @IntType(false, T.bit_count); + + const significandBits = std.math.floatMantissaBits(T); + const exponentBits = std.math.floatExponentBits(T); + const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); + const absMask = signBit - 1; + const infRep = @bitCast(rep_t, std.math.inf(T)); + + const aInt = @bitCast(srep_t, a); + const bInt = @bitCast(srep_t, b); + const aAbs = @bitCast(rep_t, aInt) & absMask; + const bAbs = @bitCast(rep_t, bInt) & absMask; + + // If either a or b is NaN, they are unordered. + if (aAbs > infRep or bAbs > infRep) return .Unordered; + + // If a and b are both zeros, they are equal. + if ((aAbs | bAbs) == 0) return .Equal; + + // If at least one of a and b is positive, we get the same result comparing + // a and b as signed integers as we would with a fp_ting-point compare. + if ((aInt & bInt) >= 0) { + if (aInt < bInt) { + return .Less; + } else if (aInt == bInt) { + return .Equal; + } else return .Greater; + } + + // Otherwise, both are negative, so we need to flip the sense of the + // comparison to get the correct result. (This assumes a twos- or ones- + // complement integer representation; if integers are represented in a + // sign-magnitude representation, then this flip is incorrect). + else { + if (aInt > bInt) { + return .Less; + } else if (aInt == bInt) { + return .Equal; + } else return .Greater; + } +} + +pub fn unordcmp(comptime T: type, a: T, b: T) i32 { + @setRuntimeSafety(builtin.is_test); + + const rep_t = @IntType(false, T.bit_count); + + const significandBits = std.math.floatMantissaBits(T); + const exponentBits = std.math.floatExponentBits(T); + const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); + const absMask = signBit - 1; + const infRep = @bitCast(rep_t, std.math.inf(T)); + + const aAbs: rep_t = @bitCast(rep_t, a) & absMask; + const bAbs: rep_t = @bitCast(rep_t, b) & absMask; + + return @boolToInt(aAbs > infRep or bAbs > infRep); +} + +// Comparison between f32 + +pub fn __lesf2(a: f32, b: f32) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @bitCast(i32, @call(.{ .modifier = .always_inline }, cmp, .{ f32, LE, a, b })); +} + +pub fn __gesf2(a: f32, b: f32) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @bitCast(i32, @call(.{ .modifier = .always_inline }, cmp, .{ f32, GE, a, b })); +} + +pub fn __eqsf2(a: f32, b: f32) callconv(.C) i32 { + return __lesf2(a, b); +} + +pub fn __ltsf2(a: f32, b: f32) callconv(.C) i32 { + return __lesf2(a, b); +} + +pub fn __nesf2(a: f32, b: f32) callconv(.C) i32 { + return __lesf2(a, b); +} + +pub fn __gtsf2(a: f32, b: f32) callconv(.C) i32 { + return __gesf2(a, b); +} + +// Comparison between f64 + +pub fn __ledf2(a: f64, b: f64) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @bitCast(i32, @call(.{ .modifier = .always_inline }, cmp, .{ f64, LE, a, b })); +} + +pub fn __gedf2(a: f64, b: f64) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @bitCast(i32, @call(.{ .modifier = .always_inline }, cmp, .{ f64, GE, a, b })); +} + +pub fn __eqdf2(a: f64, b: f64) callconv(.C) i32 { + return __ledf2(a, b); +} + +pub fn __ltdf2(a: f64, b: f64) callconv(.C) i32 { + return __ledf2(a, b); +} + +pub fn __nedf2(a: f64, b: f64) callconv(.C) i32 { + return __ledf2(a, b); +} + +pub fn __gtdf2(a: f64, b: f64) callconv(.C) i32 { + return __gedf2(a, b); +} + +// Comparison between f128 + +pub fn __letf2(a: f128, b: f128) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @bitCast(i32, @call(.{ .modifier = .always_inline }, cmp, .{ f128, LE, a, b })); +} + +pub fn __getf2(a: f128, b: f128) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @bitCast(i32, @call(.{ .modifier = .always_inline }, cmp, .{ f128, GE, a, b })); +} + +pub fn __eqtf2(a: f128, b: f128) callconv(.C) i32 { + return __letf2(a, b); +} + +pub fn __lttf2(a: f128, b: f128) callconv(.C) i32 { + return __letf2(a, b); +} + +pub fn __netf2(a: f128, b: f128) callconv(.C) i32 { + return __letf2(a, b); +} + +pub fn __gttf2(a: f128, b: f128) callconv(.C) i32 { + return __getf2(a, b); +} + +// Unordered comparison between f32/f64/f128 + +pub fn __unordsf2(a: f32, b: f32) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @call(.{ .modifier = .always_inline }, unordcmp, .{ f32, a, b }); +} + +pub fn __unorddf2(a: f64, b: f64) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @call(.{ .modifier = .always_inline }, unordcmp, .{ f64, a, b }); +} + +pub fn __unordtf2(a: f128, b: f128) callconv(.C) i32 { + @setRuntimeSafety(builtin.is_test); + return @call(.{ .modifier = .always_inline }, unordcmp, .{ f128, a, b }); +} + +// ARM EABI intrinsics + +pub fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __eqsf2, .{ a, b }) == 0); +} + +pub fn __aeabi_fcmplt(a: f32, b: f32) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __ltsf2, .{ a, b }) < 0); +} + +pub fn __aeabi_fcmple(a: f32, b: f32) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __lesf2, .{ a, b }) <= 0); +} + +pub fn __aeabi_fcmpge(a: f32, b: f32) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __gesf2, .{ a, b }) >= 0); +} + +pub fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __gtsf2, .{ a, b }) > 0); +} + +pub fn __aeabi_fcmpun(a: f32, b: f32) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @call(.{ .modifier = .always_inline }, __unordsf2, .{ a, b }); +} + +pub fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __eqdf2, .{ a, b }) == 0); +} + +pub fn __aeabi_dcmplt(a: f64, b: f64) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __ltdf2, .{ a, b }) < 0); +} + +pub fn __aeabi_dcmple(a: f64, b: f64) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __ledf2, .{ a, b }) <= 0); +} + +pub fn __aeabi_dcmpge(a: f64, b: f64) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __gedf2, .{ a, b }) >= 0); +} + +pub fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @boolToInt(@call(.{ .modifier = .always_inline }, __gtdf2, .{ a, b }) > 0); +} + +pub fn __aeabi_dcmpun(a: f64, b: f64) callconv(.AAPCS) i32 { + @setRuntimeSafety(false); + return @call(.{ .modifier = .always_inline }, __unorddf2, .{ a, b }); +} + +test "comparesf2" { + _ = @import("comparesf2_test.zig"); +} +test "comparedf2" { + _ = @import("comparedf2_test.zig"); +} diff --git a/lib/std/special/compiler_rt/comparedf2.zig b/lib/std/special/compiler_rt/comparedf2.zig deleted file mode 100644 index 98cca106f7..0000000000 --- a/lib/std/special/compiler_rt/comparedf2.zig +++ /dev/null @@ -1,127 +0,0 @@ -// Ported from: -// -// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/comparedf2.c - -const std = @import("std"); -const builtin = @import("builtin"); -const is_test = builtin.is_test; - -const fp_t = f64; -const rep_t = u64; -const srep_t = i64; - -const typeWidth = rep_t.bit_count; -const significandBits = std.math.floatMantissaBits(fp_t); -const exponentBits = std.math.floatExponentBits(fp_t); -const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); -const absMask = signBit - 1; -const implicitBit = @as(rep_t, 1) << significandBits; -const significandMask = implicitBit - 1; -const exponentMask = absMask ^ significandMask; -const infRep = @bitCast(rep_t, std.math.inf(fp_t)); - -// TODO https://github.com/ziglang/zig/issues/641 -// and then make the return types of some of these functions the enum instead of c_int -const LE_LESS = @as(c_int, -1); -const LE_EQUAL = @as(c_int, 0); -const LE_GREATER = @as(c_int, 1); -const LE_UNORDERED = @as(c_int, 1); - -pub fn __ledf2(a: fp_t, b: fp_t) callconv(.C) c_int { - @setRuntimeSafety(is_test); - const aInt: srep_t = @bitCast(srep_t, a); - const bInt: srep_t = @bitCast(srep_t, b); - const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask; - const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask; - - // If either a or b is NaN, they are unordered. - if (aAbs > infRep or bAbs > infRep) return LE_UNORDERED; - - // If a and b are both zeros, they are equal. - if ((aAbs | bAbs) == 0) return LE_EQUAL; - - // If at least one of a and b is positive, we get the same result comparing - // a and b as signed integers as we would with a fp_ting-point compare. - if ((aInt & bInt) >= 0) { - if (aInt < bInt) { - return LE_LESS; - } else if (aInt == bInt) { - return LE_EQUAL; - } else return LE_GREATER; - } - - // Otherwise, both are negative, so we need to flip the sense of the - // comparison to get the correct result. (This assumes a twos- or ones- - // complement integer representation; if integers are represented in a - // sign-magnitude representation, then this flip is incorrect). - else { - if (aInt > bInt) { - return LE_LESS; - } else if (aInt == bInt) { - return LE_EQUAL; - } else return LE_GREATER; - } -} - -// TODO https://github.com/ziglang/zig/issues/641 -// and then make the return types of some of these functions the enum instead of c_int -const GE_LESS = @as(c_int, -1); -const GE_EQUAL = @as(c_int, 0); -const GE_GREATER = @as(c_int, 1); -const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED - -pub fn __gedf2(a: fp_t, b: fp_t) callconv(.C) c_int { - @setRuntimeSafety(is_test); - const aInt: srep_t = @bitCast(srep_t, a); - const bInt: srep_t = @bitCast(srep_t, b); - const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask; - const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask; - - if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED; - if ((aAbs | bAbs) == 0) return GE_EQUAL; - if ((aInt & bInt) >= 0) { - if (aInt < bInt) { - return GE_LESS; - } else if (aInt == bInt) { - return GE_EQUAL; - } else return GE_GREATER; - } else { - if (aInt > bInt) { - return GE_LESS; - } else if (aInt == bInt) { - return GE_EQUAL; - } else return GE_GREATER; - } -} - -pub fn __unorddf2(a: fp_t, b: fp_t) callconv(.C) c_int { - @setRuntimeSafety(is_test); - const aAbs: rep_t = @bitCast(rep_t, a) & absMask; - const bAbs: rep_t = @bitCast(rep_t, b) & absMask; - return @boolToInt(aAbs > infRep or bAbs > infRep); -} - -pub fn __eqdf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __ledf2(a, b); -} - -pub fn __ltdf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __ledf2(a, b); -} - -pub fn __nedf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __ledf2(a, b); -} - -pub fn __gtdf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __gedf2(a, b); -} - -pub fn __aeabi_dcmpun(a: fp_t, b: fp_t) callconv(.AAPCS) c_int { - @setRuntimeSafety(false); - return @call(.{ .modifier = .always_inline }, __unorddf2, .{ a, b }); -} - -test "import comparedf2" { - _ = @import("comparedf2_test.zig"); -} diff --git a/lib/std/special/compiler_rt/comparedf2_test.zig b/lib/std/special/compiler_rt/comparedf2_test.zig index b0e5757ec0..16a2a258ce 100644 --- a/lib/std/special/compiler_rt/comparedf2_test.zig +++ b/lib/std/special/compiler_rt/comparedf2_test.zig @@ -6,7 +6,7 @@ const std = @import("std"); const builtin = @import("builtin"); const is_test = builtin.is_test; -const comparedf2 = @import("comparedf2.zig"); +const comparedf2 = @import("compareXf2.zig"); const TestVector = struct { a: f64, diff --git a/lib/std/special/compiler_rt/comparesf2.zig b/lib/std/special/compiler_rt/comparesf2.zig deleted file mode 100644 index bd881af2a1..0000000000 --- a/lib/std/special/compiler_rt/comparesf2.zig +++ /dev/null @@ -1,127 +0,0 @@ -// Ported from: -// -// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/comparesf2.c - -const std = @import("std"); -const builtin = @import("builtin"); -const is_test = builtin.is_test; - -const fp_t = f32; -const rep_t = u32; -const srep_t = i32; - -const typeWidth = rep_t.bit_count; -const significandBits = std.math.floatMantissaBits(fp_t); -const exponentBits = std.math.floatExponentBits(fp_t); -const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); -const absMask = signBit - 1; -const implicitBit = @as(rep_t, 1) << significandBits; -const significandMask = implicitBit - 1; -const exponentMask = absMask ^ significandMask; -const infRep = @bitCast(rep_t, std.math.inf(fp_t)); - -// TODO https://github.com/ziglang/zig/issues/641 -// and then make the return types of some of these functions the enum instead of c_int -const LE_LESS = @as(c_int, -1); -const LE_EQUAL = @as(c_int, 0); -const LE_GREATER = @as(c_int, 1); -const LE_UNORDERED = @as(c_int, 1); - -pub fn __lesf2(a: fp_t, b: fp_t) callconv(.C) c_int { - @setRuntimeSafety(is_test); - const aInt: srep_t = @bitCast(srep_t, a); - const bInt: srep_t = @bitCast(srep_t, b); - const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask; - const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask; - - // If either a or b is NaN, they are unordered. - if (aAbs > infRep or bAbs > infRep) return LE_UNORDERED; - - // If a and b are both zeros, they are equal. - if ((aAbs | bAbs) == 0) return LE_EQUAL; - - // If at least one of a and b is positive, we get the same result comparing - // a and b as signed integers as we would with a fp_ting-point compare. - if ((aInt & bInt) >= 0) { - if (aInt < bInt) { - return LE_LESS; - } else if (aInt == bInt) { - return LE_EQUAL; - } else return LE_GREATER; - } - - // Otherwise, both are negative, so we need to flip the sense of the - // comparison to get the correct result. (This assumes a twos- or ones- - // complement integer representation; if integers are represented in a - // sign-magnitude representation, then this flip is incorrect). - else { - if (aInt > bInt) { - return LE_LESS; - } else if (aInt == bInt) { - return LE_EQUAL; - } else return LE_GREATER; - } -} - -// TODO https://github.com/ziglang/zig/issues/641 -// and then make the return types of some of these functions the enum instead of c_int -const GE_LESS = @as(c_int, -1); -const GE_EQUAL = @as(c_int, 0); -const GE_GREATER = @as(c_int, 1); -const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED - -pub fn __gesf2(a: fp_t, b: fp_t) callconv(.C) c_int { - @setRuntimeSafety(is_test); - const aInt: srep_t = @bitCast(srep_t, a); - const bInt: srep_t = @bitCast(srep_t, b); - const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask; - const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask; - - if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED; - if ((aAbs | bAbs) == 0) return GE_EQUAL; - if ((aInt & bInt) >= 0) { - if (aInt < bInt) { - return GE_LESS; - } else if (aInt == bInt) { - return GE_EQUAL; - } else return GE_GREATER; - } else { - if (aInt > bInt) { - return GE_LESS; - } else if (aInt == bInt) { - return GE_EQUAL; - } else return GE_GREATER; - } -} - -pub fn __unordsf2(a: fp_t, b: fp_t) callconv(.C) c_int { - @setRuntimeSafety(is_test); - const aAbs: rep_t = @bitCast(rep_t, a) & absMask; - const bAbs: rep_t = @bitCast(rep_t, b) & absMask; - return @boolToInt(aAbs > infRep or bAbs > infRep); -} - -pub fn __eqsf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __lesf2(a, b); -} - -pub fn __ltsf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __lesf2(a, b); -} - -pub fn __nesf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __lesf2(a, b); -} - -pub fn __gtsf2(a: fp_t, b: fp_t) callconv(.C) c_int { - return __gesf2(a, b); -} - -pub fn __aeabi_fcmpun(a: fp_t, b: fp_t) callconv(.AAPCS) c_int { - @setRuntimeSafety(false); - return @call(.{ .modifier = .always_inline }, __unordsf2, .{ a, b }); -} - -test "import comparesf2" { - _ = @import("comparesf2_test.zig"); -} diff --git a/lib/std/special/compiler_rt/comparesf2_test.zig b/lib/std/special/compiler_rt/comparesf2_test.zig index d736988bfb..e3966c021b 100644 --- a/lib/std/special/compiler_rt/comparesf2_test.zig +++ b/lib/std/special/compiler_rt/comparesf2_test.zig @@ -6,7 +6,7 @@ const std = @import("std"); const builtin = @import("builtin"); const is_test = builtin.is_test; -const comparesf2 = @import("comparesf2.zig"); +const comparesf2 = @import("compareXf2.zig"); const TestVector = struct { a: f32, diff --git a/lib/std/special/compiler_rt/comparetf2.zig b/lib/std/special/compiler_rt/comparetf2.zig deleted file mode 100644 index f2969f2112..0000000000 --- a/lib/std/special/compiler_rt/comparetf2.zig +++ /dev/null @@ -1,99 +0,0 @@ -// TODO https://github.com/ziglang/zig/issues/641 -// and then make the return types of some of these functions the enum instead of c_int -const LE_LESS = @as(c_int, -1); -const LE_EQUAL = @as(c_int, 0); -const LE_GREATER = @as(c_int, 1); -const LE_UNORDERED = @as(c_int, 1); - -const rep_t = u128; -const srep_t = i128; - -const typeWidth = rep_t.bit_count; -const significandBits = 112; -const exponentBits = (typeWidth - significandBits - 1); -const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); -const absMask = signBit - 1; -const implicitBit = @as(rep_t, 1) << significandBits; -const significandMask = implicitBit - 1; -const exponentMask = absMask ^ significandMask; -const infRep = exponentMask; - -const builtin = @import("builtin"); -const is_test = builtin.is_test; - -pub fn __letf2(a: f128, b: f128) callconv(.C) c_int { - @setRuntimeSafety(is_test); - - const aInt = @bitCast(rep_t, a); - const bInt = @bitCast(rep_t, b); - - const aAbs: rep_t = aInt & absMask; - const bAbs: rep_t = bInt & absMask; - - // If either a or b is NaN, they are unordered. - if (aAbs > infRep or bAbs > infRep) return LE_UNORDERED; - - // If a and b are both zeros, they are equal. - if ((aAbs | bAbs) == 0) return LE_EQUAL; - - // If at least one of a and b is positive, we get the same result comparing - // a and b as signed integers as we would with a floating-point compare. - return if ((aInt & bInt) >= 0) - if (aInt < bInt) - LE_LESS - else if (aInt == bInt) - LE_EQUAL - else - LE_GREATER - else - // Otherwise, both are negative, so we need to flip the sense of the - // comparison to get the correct result. (This assumes a twos- or ones- - // complement integer representation; if integers are represented in a - // sign-magnitude representation, then this flip is incorrect). - if (aInt > bInt) - LE_LESS - else if (aInt == bInt) - LE_EQUAL - else - LE_GREATER; -} - -// TODO https://github.com/ziglang/zig/issues/641 -// and then make the return types of some of these functions the enum instead of c_int -const GE_LESS = @as(c_int, -1); -const GE_EQUAL = @as(c_int, 0); -const GE_GREATER = @as(c_int, 1); -const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED - -pub fn __getf2(a: f128, b: f128) callconv(.C) c_int { - @setRuntimeSafety(is_test); - - const aInt = @bitCast(srep_t, a); - const bInt = @bitCast(srep_t, b); - const aAbs = @bitCast(rep_t, aInt) & absMask; - const bAbs = @bitCast(rep_t, bInt) & absMask; - - if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED; - if ((aAbs | bAbs) == 0) return GE_EQUAL; - return if ((aInt & bInt) >= 0) - if (aInt < bInt) - GE_LESS - else if (aInt == bInt) - GE_EQUAL - else - GE_GREATER - else if (aInt > bInt) - GE_LESS - else if (aInt == bInt) - GE_EQUAL - else - GE_GREATER; -} - -pub fn __unordtf2(a: f128, b: f128) callconv(.C) c_int { - @setRuntimeSafety(is_test); - - const aAbs = @bitCast(rep_t, a) & absMask; - const bAbs = @bitCast(rep_t, b) & absMask; - return @boolToInt(aAbs > infRep or bAbs > infRep); -} diff --git a/lib/std/start.zig b/lib/std/start.zig index c3844e4d1e..bf6f61f25f 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -8,16 +8,7 @@ const uefi = std.os.uefi; var starting_stack_ptr: [*]usize = undefined; -const is_wasm = switch (builtin.arch) { - .wasm32, .wasm64 => true, - else => false, -}; - -const is_mips = switch (builtin.arch) { - .mips, .mipsel, .mips64, .mips64el => true, - else => false, -}; -const start_sym_name = if (is_mips) "__start" else "_start"; +const start_sym_name = if (builtin.arch.isMIPS()) "__start" else "_start"; comptime { if (builtin.output_mode == .Lib and builtin.link_mode == .Dynamic) { @@ -35,7 +26,7 @@ comptime { } } else if (builtin.os == .uefi) { if (!@hasDecl(root, "EfiMain")) @export(EfiMain, .{ .name = "EfiMain" }); - } else if (is_wasm and builtin.os == .freestanding) { + } else if (builtin.arch.isWasm() and builtin.os == .freestanding) { if (!@hasDecl(root, start_sym_name)) @export(wasm_freestanding_start, .{ .name = start_sym_name }); } else if (builtin.os != .other and builtin.os != .freestanding) { if (!@hasDecl(root, start_sym_name)) @export(_start, .{ .name = start_sym_name }); diff --git a/lib/std/target.zig b/lib/std/target.zig index 22fea691c4..d62786ff7f 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -125,6 +125,16 @@ pub const Target = union(enum) { v5, v5te, v4t, + + pub fn version(version: Arm32) comptime_int { + return switch (version) { + .v8_5a, .v8_4a, .v8_3a, .v8_2a, .v8_1a, .v8, .v8r, .v8m_baseline, .v8m_mainline, .v8_1m_mainline => 8, + .v7, .v7em, .v7m, .v7s, .v7k, .v7ve => 7, + .v6, .v6m, .v6k, .v6t2 => 6, + .v5, .v5te => 5, + .v4t => 4, + }; + } }; pub const Arm64 = enum { v8_5a, @@ -146,6 +156,34 @@ pub const Target = union(enum) { r6, }; + pub fn isARM(arch: Arch) bool { + return switch (arch) { + .arm, .armeb => true, + else => false, + }; + } + + pub fn isThumb(arch: Arch) bool { + return switch (arch) { + .thumb, .thumbeb => true, + else => false, + }; + } + + pub fn isWasm(arch: Arch) bool { + return switch (arch) { + .wasm32, .wasm64 => true, + else => false, + }; + } + + pub fn isMIPS(arch: Arch) bool { + return switch (arch) { + .mips, .mipsel, .mips64, .mips64el => true, + else => false, + }; + } + pub fn toElfMachine(arch: Arch) std.elf.EM { return switch (arch) { .avr => ._AVR, |
