aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-01-22 12:12:36 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-01-22 12:12:36 -0500
commit97b2ac598b91194c09a96c9ed86e4f9b266d019c (patch)
treef8ddd18aaf3a52981f3a97faeac8ef7bd20e6908 /lib/std
parent7e674d6761c057985003694f98861f589b6cf313 (diff)
parentc522699f28c1df806865c527a7a68a875e606527 (diff)
downloadzig-97b2ac598b91194c09a96c9ed86e4f9b266d019c.tar.gz
zig-97b2ac598b91194c09a96c9ed86e4f9b266d019c.zip
Merge remote-tracking branch 'origin/master' into llvm10
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/build.zig4
-rw-r--r--lib/std/builtin.zig2
-rw-r--r--lib/std/c.zig6
-rw-r--r--lib/std/c/darwin.zig61
-rw-r--r--lib/std/c/freebsd.zig60
-rw-r--r--lib/std/c/linux.zig40
-rw-r--r--lib/std/dynamic_library.zig2
-rw-r--r--lib/std/fmt.zig17
-rw-r--r--lib/std/hash/benchmark.zig4
-rw-r--r--lib/std/hash/crc.zig27
-rw-r--r--lib/std/net.zig24
-rw-r--r--lib/std/os/bits/linux.zig2
-rw-r--r--lib/std/special/compiler_rt.zig126
-rw-r--r--lib/std/special/compiler_rt/arm.zig19
-rw-r--r--lib/std/special/compiler_rt/arm/aeabi_dcmp.zig95
-rw-r--r--lib/std/special/compiler_rt/arm/aeabi_fcmp.zig95
-rw-r--r--lib/std/special/compiler_rt/clzsi2.zig116
-rw-r--r--lib/std/special/compiler_rt/clzsi2_test.zig292
-rw-r--r--lib/std/special/compiler_rt/compareXf2.zig253
-rw-r--r--lib/std/special/compiler_rt/comparedf2.zig127
-rw-r--r--lib/std/special/compiler_rt/comparedf2_test.zig2
-rw-r--r--lib/std/special/compiler_rt/comparesf2.zig127
-rw-r--r--lib/std/special/compiler_rt/comparesf2_test.zig2
-rw-r--r--lib/std/special/compiler_rt/comparetf2.zig99
-rw-r--r--lib/std/start.zig13
-rw-r--r--lib/std/target.zig38
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,