@zigc/lib 0.16.0-test.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/c/math.zig +135 -35
- package/c/stropts.zig +17 -0
- package/c.zig +1 -0
- package/compiler/aro/aro/Attribute/names.zig +604 -589
- package/compiler/aro/aro/Attribute.zig +202 -116
- package/compiler/aro/aro/Builtins/common.zig +874 -863
- package/compiler/aro/aro/Builtins/eval.zig +15 -7
- package/compiler/aro/aro/Builtins.zig +0 -1
- package/compiler/aro/aro/CodeGen.zig +3 -1
- package/compiler/aro/aro/Compilation.zig +120 -97
- package/compiler/aro/aro/Diagnostics.zig +21 -17
- package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
- package/compiler/aro/aro/Driver.zig +124 -50
- package/compiler/aro/aro/LangOpts.zig +12 -2
- package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
- package/compiler/aro/aro/Parser.zig +336 -142
- package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
- package/compiler/aro/aro/Preprocessor.zig +127 -56
- package/compiler/aro/aro/Target.zig +17 -12
- package/compiler/aro/aro/Tokenizer.zig +31 -14
- package/compiler/aro/aro/Toolchain.zig +4 -7
- package/compiler/aro/aro/Tree.zig +178 -148
- package/compiler/aro/aro/TypeStore.zig +82 -24
- package/compiler/aro/aro/Value.zig +13 -17
- package/compiler/aro/aro/features.zig +1 -0
- package/compiler/aro/aro/pragmas/once.zig +0 -1
- package/compiler/aro/aro/record_layout.zig +3 -3
- package/compiler/aro/assembly_backend/x86_64.zig +3 -4
- package/compiler/aro/backend/Assembly.zig +1 -2
- package/compiler/aro/backend/Interner.zig +2 -2
- package/compiler/aro/backend/Ir.zig +100 -92
- package/compiler/aro/include/ptrcheck.h +49 -0
- package/compiler/aro/main.zig +26 -10
- package/compiler/build_runner.zig +1 -0
- package/compiler/objdump.zig +93 -0
- package/compiler/reduce.zig +5 -1
- package/compiler/resinator/compile.zig +2 -2
- package/compiler/resinator/main.zig +7 -1
- package/compiler/resinator/preprocess.zig +1 -3
- package/compiler/std-docs.zig +8 -1
- package/compiler/test_runner.zig +193 -61
- package/compiler/translate-c/MacroTranslator.zig +80 -11
- package/compiler/translate-c/PatternList.zig +1 -9
- package/compiler/translate-c/Scope.zig +43 -6
- package/compiler/translate-c/Translator.zig +364 -126
- package/compiler/translate-c/ast.zig +19 -11
- package/compiler/translate-c/main.zig +75 -16
- package/compiler_rt/cos.zig +141 -52
- package/compiler_rt/limb64.zig +266 -0
- package/compiler_rt/long_double.zig +37 -0
- package/compiler_rt/mulo.zig +6 -1
- package/compiler_rt/rem_pio2l.zig +173 -0
- package/compiler_rt/sin.zig +140 -55
- package/compiler_rt/sincos.zig +279 -72
- package/compiler_rt/tan.zig +118 -47
- package/compiler_rt/trig.zig +256 -6
- package/compiler_rt.zig +2 -0
- package/fuzzer.zig +855 -307
- package/libc/musl/src/math/pow.c +343 -0
- package/package.json +1 -1
- package/std/Build/Fuzz.zig +6 -19
- package/std/Build/Module.zig +1 -1
- package/std/Build/Step/CheckObject.zig +3 -3
- package/std/Build/Step/Compile.zig +18 -0
- package/std/Build/Step/ConfigHeader.zig +49 -33
- package/std/Build/Step/InstallArtifact.zig +18 -0
- package/std/Build/Step/Run.zig +536 -87
- package/std/Build/Step/TranslateC.zig +0 -6
- package/std/Build/Step.zig +8 -15
- package/std/Build/WebServer.zig +29 -17
- package/std/Build/abi.zig +47 -11
- package/std/Build.zig +17 -14
- package/std/Io/Dispatch.zig +2 -0
- package/std/Io/File/Reader.zig +3 -1
- package/std/Io/File.zig +1 -0
- package/std/Io/Kqueue.zig +2 -2
- package/std/Io/Threaded.zig +181 -143
- package/std/Io/Uring.zig +2 -1
- package/std/Io.zig +970 -2
- package/std/Target.zig +3 -2
- package/std/Thread.zig +8 -3
- package/std/array_hash_map.zig +96 -555
- package/std/array_list.zig +22 -31
- package/std/bit_set.zig +22 -6
- package/std/builtin/assembly.zig +68 -0
- package/std/c.zig +17 -17
- package/std/compress/flate/Compress.zig +3 -3
- package/std/crypto/Certificate/Bundle.zig +15 -1
- package/std/crypto/codecs/asn1.zig +33 -18
- package/std/crypto/codecs/base64_hex_ct.zig +14 -4
- package/std/debug/Dwarf.zig +29 -9
- package/std/debug/Info.zig +4 -0
- package/std/debug/MachOFile.zig +46 -8
- package/std/debug/Pdb.zig +539 -36
- package/std/debug/SelfInfo/Elf.zig +19 -18
- package/std/debug/SelfInfo/MachO.zig +18 -7
- package/std/debug/SelfInfo/Windows.zig +138 -36
- package/std/debug.zig +179 -65
- package/std/enums.zig +25 -19
- package/std/heap/ArenaAllocator.zig +145 -154
- package/std/heap/debug_allocator.zig +7 -7
- package/std/http/Client.zig +10 -6
- package/std/http.zig +11 -9
- package/std/json/Stringify.zig +3 -3
- package/std/json/dynamic.zig +4 -4
- package/std/math/big/int.zig +16 -17
- package/std/mem/Allocator.zig +4 -5
- package/std/mem.zig +48 -0
- package/std/os/emscripten.zig +1 -17
- package/std/os/linux.zig +7 -2
- package/std/os/windows.zig +2 -2
- package/std/pdb.zig +143 -4
- package/std/posix.zig +6 -12
- package/std/priority_dequeue.zig +13 -12
- package/std/priority_queue.zig +5 -4
- package/std/process/Child.zig +1 -1
- package/std/process/Environ.zig +1 -1
- package/std/start.zig +17 -4
- package/std/std.zig +19 -6
- package/std/testing/FailingAllocator.zig +4 -4
- package/std/testing/Smith.zig +37 -2
- package/std/zig/Ast/Render.zig +186 -458
- package/std/zig/Ast.zig +0 -4
- package/std/zig/AstGen.zig +44 -7
- package/std/zig/AstSmith.zig +2602 -0
- package/std/zig/Client.zig +8 -3
- package/std/zig/Parse.zig +83 -74
- package/std/zig/Server.zig +26 -0
- package/std/zig/Zir.zig +17 -0
- package/std/zig/c_translation/helpers.zig +14 -9
- package/std/zig/llvm/Builder.zig +107 -48
- package/std/zig/system.zig +20 -4
- package/std/zig/tokenizer.zig +2 -1
- package/std/zig.zig +6 -0
- package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
- package/libc/mingw/complex/cabs.c +0 -48
- package/libc/mingw/complex/cabsf.c +0 -48
- package/libc/mingw/complex/cacos.c +0 -50
- package/libc/mingw/complex/cacosf.c +0 -50
- package/libc/mingw/complex/carg.c +0 -48
- package/libc/mingw/complex/cargf.c +0 -48
- package/libc/mingw/complex/casin.c +0 -50
- package/libc/mingw/complex/casinf.c +0 -50
- package/libc/mingw/complex/catan.c +0 -50
- package/libc/mingw/complex/catanf.c +0 -50
- package/libc/mingw/complex/ccos.c +0 -50
- package/libc/mingw/complex/ccosf.c +0 -50
- package/libc/mingw/complex/cexp.c +0 -48
- package/libc/mingw/complex/cexpf.c +0 -48
- package/libc/mingw/complex/cimag.c +0 -48
- package/libc/mingw/complex/cimagf.c +0 -48
- package/libc/mingw/complex/clog.c +0 -48
- package/libc/mingw/complex/clog10.c +0 -49
- package/libc/mingw/complex/clog10f.c +0 -49
- package/libc/mingw/complex/clogf.c +0 -48
- package/libc/mingw/complex/conj.c +0 -48
- package/libc/mingw/complex/conjf.c +0 -48
- package/libc/mingw/complex/cpow.c +0 -48
- package/libc/mingw/complex/cpowf.c +0 -48
- package/libc/mingw/complex/cproj.c +0 -48
- package/libc/mingw/complex/cprojf.c +0 -48
- package/libc/mingw/complex/creal.c +0 -48
- package/libc/mingw/complex/crealf.c +0 -48
- package/libc/mingw/complex/csin.c +0 -50
- package/libc/mingw/complex/csinf.c +0 -50
- package/libc/mingw/complex/csqrt.c +0 -48
- package/libc/mingw/complex/csqrtf.c +0 -48
- package/libc/mingw/complex/ctan.c +0 -50
- package/libc/mingw/complex/ctanf.c +0 -50
- package/libc/mingw/math/arm/s_rint.c +0 -86
- package/libc/mingw/math/arm/s_rintf.c +0 -51
- package/libc/mingw/math/arm/sincos.S +0 -30
- package/libc/mingw/math/arm-common/sincosl.c +0 -13
- package/libc/mingw/math/arm64/rint.c +0 -12
- package/libc/mingw/math/arm64/rintf.c +0 -12
- package/libc/mingw/math/arm64/sincos.S +0 -32
- package/libc/mingw/math/bsd_private_base.h +0 -148
- package/libc/mingw/math/frexpf.c +0 -13
- package/libc/mingw/math/frexpl.c +0 -71
- package/libc/mingw/math/x86/acosf.c +0 -29
- package/libc/mingw/math/x86/atanf.c +0 -23
- package/libc/mingw/math/x86/atanl.c +0 -18
- package/libc/mingw/math/x86/cos.def.h +0 -65
- package/libc/mingw/math/x86/cosl.c +0 -46
- package/libc/mingw/math/x86/cosl_internal.S +0 -55
- package/libc/mingw/math/x86/ldexp.c +0 -23
- package/libc/mingw/math/x86/scalbn.S +0 -41
- package/libc/mingw/math/x86/scalbnf.S +0 -40
- package/libc/mingw/math/x86/sin.def.h +0 -65
- package/libc/mingw/math/x86/sinl.c +0 -46
- package/libc/mingw/math/x86/sinl_internal.S +0 -58
- package/libc/mingw/math/x86/tanl.S +0 -62
- package/libc/mingw/misc/btowc.c +0 -28
- package/libc/mingw/misc/wcstof.c +0 -66
- package/libc/mingw/misc/wcstoimax.c +0 -132
- package/libc/mingw/misc/wcstoumax.c +0 -126
- package/libc/mingw/misc/wctob.c +0 -29
- package/libc/mingw/misc/winbs_uint64.c +0 -6
- package/libc/mingw/misc/winbs_ulong.c +0 -6
- package/libc/mingw/misc/winbs_ushort.c +0 -6
- package/libc/mingw/stdio/_Exit.c +0 -10
- package/libc/mingw/stdio/_findfirst64i32.c +0 -21
- package/libc/mingw/stdio/_findnext64i32.c +0 -21
- package/libc/mingw/stdio/_fstat64i32.c +0 -37
- package/libc/mingw/stdio/_stat64i32.c +0 -37
- package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
- package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
- package/libc/mingw/stdio/_wstat64i32.c +0 -37
- package/libc/musl/src/legacy/isastream.c +0 -7
- package/libc/musl/src/legacy/valloc.c +0 -8
- package/libc/musl/src/math/__cosl.c +0 -96
- package/libc/musl/src/math/__sinl.c +0 -78
- package/libc/musl/src/math/__tanl.c +0 -143
- package/libc/musl/src/math/aarch64/lrint.c +0 -10
- package/libc/musl/src/math/aarch64/lrintf.c +0 -10
- package/libc/musl/src/math/aarch64/rintf.c +0 -7
- package/libc/musl/src/math/cosl.c +0 -39
- package/libc/musl/src/math/fdim.c +0 -10
- package/libc/musl/src/math/finite.c +0 -7
- package/libc/musl/src/math/finitef.c +0 -7
- package/libc/musl/src/math/frexp.c +0 -23
- package/libc/musl/src/math/frexpf.c +0 -23
- package/libc/musl/src/math/frexpl.c +0 -29
- package/libc/musl/src/math/i386/lrint.c +0 -8
- package/libc/musl/src/math/i386/lrintf.c +0 -8
- package/libc/musl/src/math/i386/rintf.c +0 -7
- package/libc/musl/src/math/lrint.c +0 -72
- package/libc/musl/src/math/lrintf.c +0 -8
- package/libc/musl/src/math/powerpc64/lrint.c +0 -16
- package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
- package/libc/musl/src/math/rintf.c +0 -30
- package/libc/musl/src/math/s390x/rintf.c +0 -15
- package/libc/musl/src/math/sincosl.c +0 -60
- package/libc/musl/src/math/sinl.c +0 -41
- package/libc/musl/src/math/tanl.c +0 -29
- package/libc/musl/src/math/x32/lrint.s +0 -5
- package/libc/musl/src/math/x32/lrintf.s +0 -5
- package/libc/musl/src/math/x86_64/lrint.c +0 -8
- package/libc/musl/src/math/x86_64/lrintf.c +0 -8
- package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const testing = std.testing;
|
|
3
|
+
const assert = std.debug.assert;
|
|
4
|
+
const maxInt = std.math.maxInt;
|
|
5
|
+
const minInt = std.math.minInt;
|
|
6
|
+
const divCeil = std.math.divCeil;
|
|
7
|
+
|
|
8
|
+
const builtin = @import("builtin");
|
|
9
|
+
const compiler_rt = @import("../compiler_rt.zig");
|
|
10
|
+
|
|
11
|
+
const endian = builtin.cpu.arch.endian();
|
|
12
|
+
|
|
13
|
+
inline fn limbGet(limbs: []const u64, i: usize) u64 {
|
|
14
|
+
return switch (endian) {
|
|
15
|
+
.little => limbs[i],
|
|
16
|
+
.big => limbs[limbs.len - 1 - i],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
inline fn limbSet(limbs: []u64, i: usize, value: u64) void {
|
|
21
|
+
switch (endian) {
|
|
22
|
+
.little => limbs[i] = value,
|
|
23
|
+
.big => limbs[limbs.len - 1 - i] = value,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fn limbCount(bits: u16) u16 {
|
|
28
|
+
return divCeil(u16, bits, 64) catch unreachable;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn Limbs(T: type) type {
|
|
32
|
+
const int_info = @typeInfo(T).int;
|
|
33
|
+
const limb_cnt = comptime limbCount(int_info.bits);
|
|
34
|
+
return [limb_cnt]u64;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fn asLimbs(v: anytype) Limbs(@TypeOf(v)) {
|
|
38
|
+
const T = @TypeOf(v);
|
|
39
|
+
const int_info = @typeInfo(T).int;
|
|
40
|
+
const limb_cnt = comptime limbCount(int_info.bits);
|
|
41
|
+
const ET = @Int(int_info.signedness, limb_cnt * 64);
|
|
42
|
+
return @bitCast(@as(ET, v));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn limbWrap(limb: u64, is_signed: bool, bits: u16) u64 {
|
|
46
|
+
assert(bits % 64 != 0);
|
|
47
|
+
const pad_bits: u6 = @intCast(64 - bits % 64);
|
|
48
|
+
if (!is_signed) {
|
|
49
|
+
const s = limb << pad_bits;
|
|
50
|
+
return s >> pad_bits;
|
|
51
|
+
} else {
|
|
52
|
+
const s = @as(i64, @bitCast(limb)) << pad_bits;
|
|
53
|
+
return @bitCast(s >> pad_bits);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
comptime {
|
|
58
|
+
@export(&__addo_limb64, .{ .name = "__addo_limb64", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fn __addo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, b_ptr: [*]const u64, is_signed: bool, bits: u16) callconv(.c) bool {
|
|
62
|
+
const limb_cnt = limbCount(bits);
|
|
63
|
+
const out = out_ptr[0..limb_cnt];
|
|
64
|
+
const a = a_ptr[0..limb_cnt];
|
|
65
|
+
const b = b_ptr[0..limb_cnt];
|
|
66
|
+
|
|
67
|
+
var carry: u1 = 0;
|
|
68
|
+
var i: usize = 0;
|
|
69
|
+
while (i < limb_cnt - 1) : (i += 1) {
|
|
70
|
+
const s1 = @addWithOverflow(limbGet(a, i), limbGet(b, i));
|
|
71
|
+
const s2 = @addWithOverflow(s1[0], carry);
|
|
72
|
+
carry = s1[1] | s2[1];
|
|
73
|
+
limbSet(out, i, s2[0]);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const limb: u64 = b: {
|
|
77
|
+
if (!is_signed) {
|
|
78
|
+
const s1 = @addWithOverflow(limbGet(a, i), limbGet(b, i));
|
|
79
|
+
const s2 = @addWithOverflow(s1[0], carry);
|
|
80
|
+
carry = s1[1] | s2[1];
|
|
81
|
+
break :b s2[0];
|
|
82
|
+
} else {
|
|
83
|
+
const as: i64 = @bitCast(limbGet(a, i));
|
|
84
|
+
const bs: i64 = @bitCast(limbGet(b, i));
|
|
85
|
+
const s1 = @addWithOverflow(as, bs);
|
|
86
|
+
const s2 = @addWithOverflow(s1[0], carry);
|
|
87
|
+
carry = s1[1] | s2[1];
|
|
88
|
+
break :b @bitCast(s2[0]);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (bits % 64 == 0) {
|
|
93
|
+
limbSet(out, i, limb);
|
|
94
|
+
return carry != 0;
|
|
95
|
+
} else {
|
|
96
|
+
assert(carry == 0);
|
|
97
|
+
const wrapped_limb = limbWrap(limb, is_signed, bits);
|
|
98
|
+
limbSet(out, i, wrapped_limb);
|
|
99
|
+
return wrapped_limb != limb;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fn test__addo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool }) !void {
|
|
104
|
+
const int_info = @typeInfo(T).int;
|
|
105
|
+
const is_signed = int_info.signedness == .signed;
|
|
106
|
+
|
|
107
|
+
var a_limbs = asLimbs(a);
|
|
108
|
+
var b_limbs = asLimbs(b);
|
|
109
|
+
var out: Limbs(T) = undefined;
|
|
110
|
+
const overflow = __addo_limb64(&out, &a_limbs, &b_limbs, is_signed, int_info.bits);
|
|
111
|
+
|
|
112
|
+
const expected_limbs = asLimbs(expected[0]);
|
|
113
|
+
try testing.expectEqual(expected_limbs, out);
|
|
114
|
+
try testing.expectEqual(expected[1], overflow);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
test __addo_limb64 {
|
|
118
|
+
try test__addo_limb64(u64, 1, 2, .{ 3, false });
|
|
119
|
+
try test__addo_limb64(u64, maxInt(u64), 2, .{ 1, true });
|
|
120
|
+
try test__addo_limb64(u65, maxInt(u65), 2, .{ 1, true });
|
|
121
|
+
try test__addo_limb64(u255, 1, 2, .{ 3, false });
|
|
122
|
+
|
|
123
|
+
try test__addo_limb64(i64, 1, 2, .{ 3, false });
|
|
124
|
+
try test__addo_limb64(i64, maxInt(i64), 1, .{ minInt(i64), true });
|
|
125
|
+
try test__addo_limb64(i65, maxInt(i65), 1, .{ minInt(i65), true });
|
|
126
|
+
try test__addo_limb64(i255, -3, 2, .{ -1, false });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
comptime {
|
|
130
|
+
@export(&__subo_limb64, .{ .name = "__subo_limb64", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
fn __subo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, b_ptr: [*]const u64, is_signed: bool, bits: u16) callconv(.c) bool {
|
|
134
|
+
const limb_cnt = limbCount(bits);
|
|
135
|
+
const out = out_ptr[0..limb_cnt];
|
|
136
|
+
const a = a_ptr[0..limb_cnt];
|
|
137
|
+
const b = b_ptr[0..limb_cnt];
|
|
138
|
+
|
|
139
|
+
var borrow: u1 = 0;
|
|
140
|
+
var i: usize = 0;
|
|
141
|
+
while (i < limb_cnt - 1) : (i += 1) {
|
|
142
|
+
const s1 = @subWithOverflow(limbGet(a, i), limbGet(b, i));
|
|
143
|
+
const s2 = @subWithOverflow(s1[0], borrow);
|
|
144
|
+
borrow = s1[1] | s2[1];
|
|
145
|
+
limbSet(out, i, s2[0]);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const limb: u64 = b: {
|
|
149
|
+
if (!is_signed) {
|
|
150
|
+
const s1 = @subWithOverflow(limbGet(a, i), limbGet(b, i));
|
|
151
|
+
const s2 = @subWithOverflow(s1[0], borrow);
|
|
152
|
+
borrow = s1[1] | s2[1];
|
|
153
|
+
break :b s2[0];
|
|
154
|
+
} else {
|
|
155
|
+
const as: i64 = @bitCast(limbGet(a, i));
|
|
156
|
+
const bs: i64 = @bitCast(limbGet(b, i));
|
|
157
|
+
const s1 = @subWithOverflow(as, bs);
|
|
158
|
+
const s2 = @subWithOverflow(s1[0], borrow);
|
|
159
|
+
borrow = s1[1] | s2[1];
|
|
160
|
+
break :b @bitCast(s2[0]);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
if (bits % 64 == 0) {
|
|
165
|
+
limbSet(out, i, limb);
|
|
166
|
+
return borrow != 0;
|
|
167
|
+
} else {
|
|
168
|
+
const wrapped_limb = limbWrap(limb, is_signed, bits);
|
|
169
|
+
limbSet(out, i, wrapped_limb);
|
|
170
|
+
return borrow != 0 or wrapped_limb != limb;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
fn test__subo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool }) !void {
|
|
175
|
+
const int_info = @typeInfo(T).int;
|
|
176
|
+
const is_signed = int_info.signedness == .signed;
|
|
177
|
+
|
|
178
|
+
var a_limbs = asLimbs(a);
|
|
179
|
+
var b_limbs = asLimbs(b);
|
|
180
|
+
var out: Limbs(T) = undefined;
|
|
181
|
+
const overflow = __subo_limb64(&out, &a_limbs, &b_limbs, is_signed, int_info.bits);
|
|
182
|
+
|
|
183
|
+
const expected_limbs = asLimbs(expected[0]);
|
|
184
|
+
try testing.expectEqual(expected_limbs, out);
|
|
185
|
+
try testing.expectEqual(expected[1], overflow);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
test __subo_limb64 {
|
|
189
|
+
try test__subo_limb64(u64, 3, 2, .{ 1, false });
|
|
190
|
+
try test__subo_limb64(u64, 0, 1, .{ maxInt(u64), true });
|
|
191
|
+
try test__subo_limb64(u65, 0, 1, .{ maxInt(u65), true });
|
|
192
|
+
try test__subo_limb64(u255, 3, 2, .{ 1, false });
|
|
193
|
+
|
|
194
|
+
try test__subo_limb64(i64, 1, 2, .{ -1, false });
|
|
195
|
+
try test__subo_limb64(i64, minInt(i64), 1, .{ maxInt(i64), true });
|
|
196
|
+
try test__subo_limb64(i65, minInt(i65), 1, .{ maxInt(i65), true });
|
|
197
|
+
try test__subo_limb64(i255, -1, 2, .{ -3, false });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
comptime {
|
|
201
|
+
@export(&__cmp_limb64, .{ .name = "__cmp_limb64", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// a < b -> -1
|
|
205
|
+
// a == b -> 0
|
|
206
|
+
// a > b -> 1
|
|
207
|
+
fn __cmp_limb64(a_ptr: [*]const u64, b_ptr: [*]const u64, is_signed: bool, bits: u16) callconv(.c) i8 {
|
|
208
|
+
const limb_cnt = limbCount(bits);
|
|
209
|
+
const a = a_ptr[0..limb_cnt];
|
|
210
|
+
const b = b_ptr[0..limb_cnt];
|
|
211
|
+
|
|
212
|
+
var i: usize = 0;
|
|
213
|
+
if (is_signed) {
|
|
214
|
+
const sa: i64 = @bitCast(limbGet(a, limb_cnt - 1));
|
|
215
|
+
const sb: i64 = @bitCast(limbGet(b, limb_cnt - 1));
|
|
216
|
+
if (sa < sb) return -1;
|
|
217
|
+
if (sa > sb) return 1;
|
|
218
|
+
i += 1;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
while (i < limb_cnt) : (i += 1) {
|
|
222
|
+
const ai = limbGet(a, limb_cnt - 1 - i);
|
|
223
|
+
const bi = limbGet(b, limb_cnt - 1 - i);
|
|
224
|
+
if (ai < bi) return -1;
|
|
225
|
+
if (ai > bi) return 1;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return 0;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
fn test__cmp_limb64(comptime T: type, a: T, b: T, expected: i8) !void {
|
|
232
|
+
const int_info = @typeInfo(T).int;
|
|
233
|
+
const is_signed = int_info.signedness == .signed;
|
|
234
|
+
|
|
235
|
+
var a_limbs = asLimbs(a);
|
|
236
|
+
var b_limbs = asLimbs(b);
|
|
237
|
+
const actual = __cmp_limb64(&a_limbs, &b_limbs, is_signed, int_info.bits);
|
|
238
|
+
|
|
239
|
+
try testing.expectEqual(expected, actual);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
test __cmp_limb64 {
|
|
243
|
+
try test__cmp_limb64(u64, 1, 2, -1);
|
|
244
|
+
try test__cmp_limb64(u64, 2, 2, 0);
|
|
245
|
+
try test__cmp_limb64(u64, 3, 2, 1);
|
|
246
|
+
|
|
247
|
+
try test__cmp_limb64(u65, 1, 2, -1);
|
|
248
|
+
try test__cmp_limb64(u65, maxInt(u65), maxInt(u65), 0);
|
|
249
|
+
try test__cmp_limb64(u65, maxInt(u65), maxInt(u65) - 1, 1);
|
|
250
|
+
|
|
251
|
+
try test__cmp_limb64(u255, 1, 2, -1);
|
|
252
|
+
try test__cmp_limb64(u255, 7, 7, 0);
|
|
253
|
+
try test__cmp_limb64(u255, maxInt(u255), maxInt(u255) - 1, 1);
|
|
254
|
+
|
|
255
|
+
try test__cmp_limb64(i64, -1, 0, -1);
|
|
256
|
+
try test__cmp_limb64(i64, 0, 0, 0);
|
|
257
|
+
try test__cmp_limb64(i64, 1, 0, 1);
|
|
258
|
+
|
|
259
|
+
try test__cmp_limb64(i65, minInt(i65), maxInt(i65), -1);
|
|
260
|
+
try test__cmp_limb64(i65, -1, -1, 0);
|
|
261
|
+
try test__cmp_limb64(i65, maxInt(i65), minInt(i65), 1);
|
|
262
|
+
|
|
263
|
+
try test__cmp_limb64(i255, -3, 2, -1);
|
|
264
|
+
try test__cmp_limb64(i255, -5, -5, 0);
|
|
265
|
+
try test__cmp_limb64(i255, 2, -3, 1);
|
|
266
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//! Utilities for dealing with the `long double` type (`f80` or `f128`)
|
|
2
|
+
|
|
3
|
+
const std = @import("std");
|
|
4
|
+
|
|
5
|
+
pub const U80 = std.meta.Int(.unsigned, 80);
|
|
6
|
+
|
|
7
|
+
/// Returns the sign + exponent bits of a `long double`
|
|
8
|
+
pub fn signExponent(x: anytype) u16 {
|
|
9
|
+
const T = @TypeOf(x);
|
|
10
|
+
switch (T) {
|
|
11
|
+
f80 => {
|
|
12
|
+
const bits: U80 = @bitCast(x);
|
|
13
|
+
return @intCast(bits >> 64);
|
|
14
|
+
},
|
|
15
|
+
f128 => {
|
|
16
|
+
const bits: u128 = @bitCast(x);
|
|
17
|
+
return @intCast(bits >> 112);
|
|
18
|
+
},
|
|
19
|
+
else => @compileError("`signExponent` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Takes the top 16 bits of a `long double`'s mantissa
|
|
24
|
+
pub fn mantissaTop(x: anytype) u16 {
|
|
25
|
+
const T = @TypeOf(x);
|
|
26
|
+
switch (T) {
|
|
27
|
+
f80 => {
|
|
28
|
+
const bits: U80 = @bitCast(x);
|
|
29
|
+
return @intCast((bits >> 48) & 0xFFFF);
|
|
30
|
+
},
|
|
31
|
+
f128 => {
|
|
32
|
+
const bits: u128 = @bitCast(x);
|
|
33
|
+
return @intCast((bits >> 96) & 0xFFFF);
|
|
34
|
+
},
|
|
35
|
+
else => @compileError("`mantissaTop` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
|
36
|
+
}
|
|
37
|
+
}
|
package/compiler_rt/mulo.zig
CHANGED
|
@@ -19,7 +19,12 @@ comptime {
|
|
|
19
19
|
inline fn muloXi4_genericSmall(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST {
|
|
20
20
|
overflow.* = 0;
|
|
21
21
|
const min = math.minInt(ST);
|
|
22
|
-
const res: ST =
|
|
22
|
+
const res: ST = if (ST == i128 and builtin.target.cpu.arch.isWasm()) res: {
|
|
23
|
+
// Despite compiler-rt being built with `-fno-builtin`, LLVM still converts this function to
|
|
24
|
+
// a call to `__muloti4` on WASM. This is an upstream bug: circumvent it by directly calling
|
|
25
|
+
// the "lower-level" compiler-rt routine for this wrapping multiplication.
|
|
26
|
+
break :res @import("mulXi3.zig").__multi3(a, b);
|
|
27
|
+
} else a *% b;
|
|
23
28
|
// Hacker's Delight section Overflow subsection Multiplication
|
|
24
29
|
// case a=-2^{31}, b=-1 problem, because
|
|
25
30
|
// on some machines a*b = -2^{31} with overflow
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Ported from musl, which is licensed under the MIT license:
|
|
2
|
+
// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
|
|
3
|
+
//
|
|
4
|
+
// https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2l.c
|
|
5
|
+
|
|
6
|
+
const std = @import("std");
|
|
7
|
+
const math = std.math;
|
|
8
|
+
|
|
9
|
+
const ld = @import("long_double.zig");
|
|
10
|
+
const rem_pio2_large = @import("rem_pio2_large.zig").rem_pio2_large;
|
|
11
|
+
|
|
12
|
+
pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
|
13
|
+
const impl = switch (T) {
|
|
14
|
+
f80 => struct {
|
|
15
|
+
const round1: i8 = 22;
|
|
16
|
+
const round2: i8 = 61;
|
|
17
|
+
const nx: i8 = 3;
|
|
18
|
+
const ny: i8 = 2;
|
|
19
|
+
|
|
20
|
+
const pio4: T = 0x1.921fb54442d1846ap-1;
|
|
21
|
+
// 64 bits of 2/pi
|
|
22
|
+
const invpio2: T = 6.36619772367581343076e-01; // 0xa2f9836e4e44152a.0p-64
|
|
23
|
+
// first 39 bits of pi/2
|
|
24
|
+
const pio2_1: f64 = 1.57079632679597125389e+00; // 0x3FF921FB, 0x54444000
|
|
25
|
+
// pi/2 - pio2_1
|
|
26
|
+
const pio2_1t: T = -1.07463465549719416346e-12; // -0x973dcb3b399d747f.0p-103
|
|
27
|
+
// second 39 bits of pi/2
|
|
28
|
+
const pio2_2: f64 = -1.07463465549783099519e-12; // -0x12e7b967674000.0p-92
|
|
29
|
+
// pi/2 - (pio2_1+pio2_2)
|
|
30
|
+
const pio2_2t: T = 6.36831716351095013979e-25; // 0xc51701b839a25205.0p-144
|
|
31
|
+
// pi/2 - (pio2_1+pio2_2+pio2_3)
|
|
32
|
+
const pio2_3t: T = -2.75299651904407171810e-37; // -0xbb5bf6c7ddd660ce.0p-185
|
|
33
|
+
// third 39 bits of pi/2
|
|
34
|
+
const pio2_3: f64 = 6.36831716351370313614e-25; // 0x18a2e037074000.0p-133
|
|
35
|
+
|
|
36
|
+
fn small(x_val: T) bool {
|
|
37
|
+
const se = ld.signExponent(x_val);
|
|
38
|
+
const top = ld.mantissaTop(x_val);
|
|
39
|
+
const lhs = (@as(u32, se & 0x7fff) << 16) | top;
|
|
40
|
+
const rhs: u32 = ((0x3fff + 25) << 16) | 0x921f >> 1 | 0x8000;
|
|
41
|
+
return lhs < rhs;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn quobits(v: T) i32 {
|
|
45
|
+
const q: i32 = @intFromFloat(v);
|
|
46
|
+
return @intCast(@as(u32, @bitCast(q)) & 0x7fffffff);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
f128 => struct {
|
|
50
|
+
const round1: i8 = 51;
|
|
51
|
+
const round2: i8 = 119;
|
|
52
|
+
const nx: i8 = 5;
|
|
53
|
+
const ny: i8 = 3;
|
|
54
|
+
|
|
55
|
+
const pio4: T = 0x1.921fb54442d18469898cc51701b8p-1;
|
|
56
|
+
const invpio2: T = 6.3661977236758134307553505349005747e-01;
|
|
57
|
+
const pio2_1: T = 1.5707963267948966192292994253909555e+00;
|
|
58
|
+
const pio2_1t: T = 2.0222662487959507323996846200947577e-21;
|
|
59
|
+
const pio2_2: T = 2.0222662487959507323994779168837751e-21;
|
|
60
|
+
const pio2_2t: T = 2.0670321098263988236496903051604844e-43;
|
|
61
|
+
const pio2_3: T = 2.0670321098263988236499468110329591e-43;
|
|
62
|
+
const pio2_3t: T = -2.5650587247459238361625433492959285e-65;
|
|
63
|
+
|
|
64
|
+
fn small(x_val: T) bool {
|
|
65
|
+
const se = ld.signExponent(x_val);
|
|
66
|
+
const top = ld.mantissaTop(x_val);
|
|
67
|
+
const lhs = (@as(u32, se & 0x7fff) << 16) | top;
|
|
68
|
+
const rhs: u32 = ((0x3fff + 45) << 16) | 0x921f;
|
|
69
|
+
return lhs < rhs;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fn quobits(fn_val: T) i32 {
|
|
73
|
+
const q: i64 = @intFromFloat(fn_val);
|
|
74
|
+
return @intCast(@as(u64, @bitCast(q)) & 0x7fffffff);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
else => @compileError("rem_pio2l supports only f80 and f128, got: " ++ @typeName(T)),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const x_se = ld.signExponent(x);
|
|
81
|
+
const ex: i32 = @intCast(x_se & 0x7fff);
|
|
82
|
+
|
|
83
|
+
if (impl.small(x)) {
|
|
84
|
+
// rint(x/(pi/2))
|
|
85
|
+
const toint: T = 1.5 / math.floatEps(T);
|
|
86
|
+
var fn_ = x * impl.invpio2 + toint - toint;
|
|
87
|
+
var n = impl.quobits(fn_);
|
|
88
|
+
var r = x - fn_ * @as(T, impl.pio2_1);
|
|
89
|
+
var w = fn_ * impl.pio2_1t; // 1st round good to 102/180 bits
|
|
90
|
+
|
|
91
|
+
// Matters with directed rounding.
|
|
92
|
+
if (r - w < -impl.pio4) {
|
|
93
|
+
@branchHint(.unlikely);
|
|
94
|
+
n -= 1;
|
|
95
|
+
fn_ -= 1;
|
|
96
|
+
r = x - fn_ * @as(T, impl.pio2_1);
|
|
97
|
+
w = fn_ * impl.pio2_1t;
|
|
98
|
+
} else if (r - w > impl.pio4) {
|
|
99
|
+
@branchHint(.unlikely);
|
|
100
|
+
n += 1;
|
|
101
|
+
fn_ += 1;
|
|
102
|
+
r = x - fn_ * @as(T, impl.pio2_1);
|
|
103
|
+
w = fn_ * impl.pio2_1t;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
y[0] = r - w;
|
|
107
|
+
|
|
108
|
+
const ey: i32 = @intCast(ld.signExponent(y[0]) & 0x7fff);
|
|
109
|
+
if (ex - ey > impl.round1) {
|
|
110
|
+
var t = r;
|
|
111
|
+
w = fn_ * impl.pio2_2;
|
|
112
|
+
r = t - w;
|
|
113
|
+
w = fn_ * impl.pio2_2t - ((t - r) - w);
|
|
114
|
+
y[0] = r - w;
|
|
115
|
+
const ey2: i32 = @intCast(ld.signExponent(y[0]) & 0x7fff);
|
|
116
|
+
if (ex - ey2 > impl.round2) {
|
|
117
|
+
t = r;
|
|
118
|
+
w = fn_ * impl.pio2_3;
|
|
119
|
+
r = t - w;
|
|
120
|
+
w = fn_ * impl.pio2_3t - ((t - r) - w);
|
|
121
|
+
y[0] = r - w;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
y[1] = (r - y[0]) - w;
|
|
125
|
+
return n;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// all other (large) arguments
|
|
129
|
+
if (ex == 0x7fff) { // x is inf or NaN
|
|
130
|
+
y[0] = x - x;
|
|
131
|
+
y[1] = y[0];
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var z: T = math.scalbn(@abs(x), -math.ilogb(x) + 23);
|
|
136
|
+
var tx: [impl.nx]f64 = undefined;
|
|
137
|
+
var ty: [impl.ny]f64 = undefined;
|
|
138
|
+
var i: usize = 0;
|
|
139
|
+
|
|
140
|
+
while (i < impl.nx - 1) : (i += 1) {
|
|
141
|
+
tx[i] = @floatFromInt(@as(i32, @intFromFloat(z)));
|
|
142
|
+
z = (z - @as(T, tx[i])) * 0x1p24;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
tx[i] = @floatCast(z);
|
|
146
|
+
while (tx[i] == 0.0) {
|
|
147
|
+
i -= 1;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const n = rem_pio2_large(
|
|
151
|
+
tx[0..(i + 1)],
|
|
152
|
+
ty[0..impl.ny],
|
|
153
|
+
ex - 0x3fff - 23,
|
|
154
|
+
@intCast(i + 1),
|
|
155
|
+
impl.ny,
|
|
156
|
+
);
|
|
157
|
+
var w: f64 = ty[1];
|
|
158
|
+
if (impl.ny == 3) {
|
|
159
|
+
w += ty[2];
|
|
160
|
+
}
|
|
161
|
+
const r = ty[0] + w;
|
|
162
|
+
w -= r - ty[0];
|
|
163
|
+
|
|
164
|
+
if (x_se >> 15 != 0) {
|
|
165
|
+
y[0] = -@as(T, r);
|
|
166
|
+
y[1] = -@as(T, w);
|
|
167
|
+
return -n;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
y[0] = @as(T, r);
|
|
171
|
+
y[1] = @as(T, w);
|
|
172
|
+
return n;
|
|
173
|
+
}
|