@zigc/lib 0.16.0-test.1 → 0.17.0-dev.27

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.
Files changed (253) hide show
  1. package/LICENSE +19 -0
  2. package/c/math.zig +148 -35
  3. package/c/stropts.zig +17 -0
  4. package/c.zig +1 -0
  5. package/compiler/aro/aro/Attribute/names.zig +604 -589
  6. package/compiler/aro/aro/Attribute.zig +202 -116
  7. package/compiler/aro/aro/Builtins/common.zig +874 -863
  8. package/compiler/aro/aro/Builtins/eval.zig +15 -7
  9. package/compiler/aro/aro/Builtins.zig +0 -1
  10. package/compiler/aro/aro/CodeGen.zig +3 -1
  11. package/compiler/aro/aro/Compilation.zig +120 -97
  12. package/compiler/aro/aro/Diagnostics.zig +21 -17
  13. package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
  14. package/compiler/aro/aro/Driver.zig +124 -50
  15. package/compiler/aro/aro/LangOpts.zig +12 -2
  16. package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
  17. package/compiler/aro/aro/Parser.zig +336 -142
  18. package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
  19. package/compiler/aro/aro/Preprocessor.zig +127 -56
  20. package/compiler/aro/aro/Target.zig +17 -12
  21. package/compiler/aro/aro/Tokenizer.zig +31 -14
  22. package/compiler/aro/aro/Toolchain.zig +4 -7
  23. package/compiler/aro/aro/Tree.zig +178 -148
  24. package/compiler/aro/aro/TypeStore.zig +82 -24
  25. package/compiler/aro/aro/Value.zig +13 -17
  26. package/compiler/aro/aro/features.zig +1 -0
  27. package/compiler/aro/aro/pragmas/once.zig +0 -1
  28. package/compiler/aro/aro/record_layout.zig +3 -3
  29. package/compiler/aro/assembly_backend/x86_64.zig +3 -4
  30. package/compiler/aro/backend/Assembly.zig +1 -2
  31. package/compiler/aro/backend/Interner.zig +2 -2
  32. package/compiler/aro/backend/Ir.zig +100 -92
  33. package/compiler/aro/include/ptrcheck.h +49 -0
  34. package/compiler/aro/main.zig +26 -10
  35. package/compiler/build_runner.zig +1 -0
  36. package/compiler/objdump.zig +93 -0
  37. package/compiler/reduce.zig +5 -1
  38. package/compiler/resinator/compile.zig +2 -2
  39. package/compiler/resinator/main.zig +7 -1
  40. package/compiler/resinator/preprocess.zig +1 -3
  41. package/compiler/std-docs.zig +8 -1
  42. package/compiler/test_runner.zig +194 -62
  43. package/compiler/translate-c/MacroTranslator.zig +80 -11
  44. package/compiler/translate-c/PatternList.zig +1 -9
  45. package/compiler/translate-c/Scope.zig +43 -6
  46. package/compiler/translate-c/Translator.zig +364 -126
  47. package/compiler/translate-c/ast.zig +19 -11
  48. package/compiler/translate-c/main.zig +75 -16
  49. package/compiler_rt/cos.zig +141 -52
  50. package/compiler_rt/divmodei4.zig +40 -17
  51. package/compiler_rt/exp.zig +1 -4
  52. package/compiler_rt/exp2.zig +1 -4
  53. package/compiler_rt/exp_f128.zig +377 -0
  54. package/compiler_rt/limb64.zig +1126 -0
  55. package/compiler_rt/long_double.zig +37 -0
  56. package/compiler_rt/mulXi3.zig +1 -1
  57. package/compiler_rt/mulo.zig +6 -1
  58. package/compiler_rt/rem_pio2l.zig +173 -0
  59. package/compiler_rt/sin.zig +140 -55
  60. package/compiler_rt/sincos.zig +279 -72
  61. package/compiler_rt/ssp.zig +1 -1
  62. package/compiler_rt/tan.zig +118 -47
  63. package/compiler_rt/trig.zig +256 -6
  64. package/compiler_rt/udivmodei4.zig +28 -0
  65. package/compiler_rt.zig +2 -0
  66. package/fuzzer.zig +855 -307
  67. package/libc/musl/src/math/pow.c +343 -0
  68. package/package.json +1 -1
  69. package/std/Build/Fuzz.zig +6 -19
  70. package/std/Build/Module.zig +1 -1
  71. package/std/Build/Step/CheckObject.zig +3 -3
  72. package/std/Build/Step/Compile.zig +18 -0
  73. package/std/Build/Step/ConfigHeader.zig +49 -33
  74. package/std/Build/Step/InstallArtifact.zig +18 -0
  75. package/std/Build/Step/Run.zig +536 -87
  76. package/std/Build/Step/TranslateC.zig +0 -6
  77. package/std/Build/Step.zig +8 -15
  78. package/std/Build/WebServer.zig +29 -17
  79. package/std/Build/abi.zig +47 -11
  80. package/std/Build.zig +17 -14
  81. package/std/Io/Dispatch.zig +2 -0
  82. package/std/Io/File/Reader.zig +3 -1
  83. package/std/Io/File.zig +1 -0
  84. package/std/Io/Kqueue.zig +2 -2
  85. package/std/Io/Threaded.zig +181 -143
  86. package/std/Io/Uring.zig +2 -1
  87. package/std/Io/Writer.zig +41 -41
  88. package/std/Io.zig +970 -2
  89. package/std/Target.zig +3 -2
  90. package/std/Thread.zig +8 -3
  91. package/std/array_hash_map.zig +96 -555
  92. package/std/array_list.zig +22 -31
  93. package/std/bit_set.zig +22 -6
  94. package/std/builtin/assembly.zig +68 -0
  95. package/std/c.zig +17 -17
  96. package/std/compress/flate/Compress.zig +3 -3
  97. package/std/crypto/Certificate/Bundle.zig +15 -1
  98. package/std/crypto/codecs/asn1.zig +33 -18
  99. package/std/crypto/codecs/base64_hex_ct.zig +14 -4
  100. package/std/debug/Dwarf.zig +29 -9
  101. package/std/debug/Info.zig +4 -0
  102. package/std/debug/MachOFile.zig +46 -8
  103. package/std/debug/Pdb.zig +539 -36
  104. package/std/debug/SelfInfo/Elf.zig +19 -18
  105. package/std/debug/SelfInfo/MachO.zig +18 -7
  106. package/std/debug/SelfInfo/Windows.zig +138 -36
  107. package/std/debug.zig +179 -65
  108. package/std/enums.zig +25 -19
  109. package/std/heap/ArenaAllocator.zig +145 -154
  110. package/std/heap/debug_allocator.zig +7 -7
  111. package/std/http/Client.zig +10 -6
  112. package/std/http.zig +11 -9
  113. package/std/json/Stringify.zig +3 -3
  114. package/std/json/dynamic.zig +4 -4
  115. package/std/math/big/int.zig +16 -17
  116. package/std/mem/Allocator.zig +4 -5
  117. package/std/mem.zig +48 -0
  118. package/std/os/emscripten.zig +2 -18
  119. package/std/os/linux/arc.zig +144 -0
  120. package/std/os/linux.zig +21 -4
  121. package/std/os/windows.zig +2 -2
  122. package/std/pdb.zig +143 -4
  123. package/std/posix.zig +6 -12
  124. package/std/priority_dequeue.zig +13 -12
  125. package/std/priority_queue.zig +5 -4
  126. package/std/process/Child.zig +1 -1
  127. package/std/process/Environ.zig +1 -1
  128. package/std/start.zig +17 -4
  129. package/std/std.zig +19 -6
  130. package/std/testing/FailingAllocator.zig +4 -4
  131. package/std/testing/Smith.zig +37 -2
  132. package/std/zig/Ast/Render.zig +186 -458
  133. package/std/zig/Ast.zig +0 -4
  134. package/std/zig/AstGen.zig +44 -7
  135. package/std/zig/AstSmith.zig +2602 -0
  136. package/std/zig/Client.zig +8 -3
  137. package/std/zig/Parse.zig +83 -74
  138. package/std/zig/Server.zig +26 -0
  139. package/std/zig/Zir.zig +17 -0
  140. package/std/zig/c_translation/helpers.zig +14 -9
  141. package/std/zig/llvm/Builder.zig +107 -48
  142. package/std/zig/system.zig +20 -4
  143. package/std/zig/tokenizer.zig +2 -1
  144. package/std/zig.zig +6 -0
  145. package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
  146. package/libc/mingw/complex/cabs.c +0 -48
  147. package/libc/mingw/complex/cabsf.c +0 -48
  148. package/libc/mingw/complex/cacos.c +0 -50
  149. package/libc/mingw/complex/cacosf.c +0 -50
  150. package/libc/mingw/complex/carg.c +0 -48
  151. package/libc/mingw/complex/cargf.c +0 -48
  152. package/libc/mingw/complex/casin.c +0 -50
  153. package/libc/mingw/complex/casinf.c +0 -50
  154. package/libc/mingw/complex/catan.c +0 -50
  155. package/libc/mingw/complex/catanf.c +0 -50
  156. package/libc/mingw/complex/ccos.c +0 -50
  157. package/libc/mingw/complex/ccosf.c +0 -50
  158. package/libc/mingw/complex/cexp.c +0 -48
  159. package/libc/mingw/complex/cexpf.c +0 -48
  160. package/libc/mingw/complex/cimag.c +0 -48
  161. package/libc/mingw/complex/cimagf.c +0 -48
  162. package/libc/mingw/complex/clog.c +0 -48
  163. package/libc/mingw/complex/clog10.c +0 -49
  164. package/libc/mingw/complex/clog10f.c +0 -49
  165. package/libc/mingw/complex/clogf.c +0 -48
  166. package/libc/mingw/complex/conj.c +0 -48
  167. package/libc/mingw/complex/conjf.c +0 -48
  168. package/libc/mingw/complex/cpow.c +0 -48
  169. package/libc/mingw/complex/cpowf.c +0 -48
  170. package/libc/mingw/complex/cproj.c +0 -48
  171. package/libc/mingw/complex/cprojf.c +0 -48
  172. package/libc/mingw/complex/creal.c +0 -48
  173. package/libc/mingw/complex/crealf.c +0 -48
  174. package/libc/mingw/complex/csin.c +0 -50
  175. package/libc/mingw/complex/csinf.c +0 -50
  176. package/libc/mingw/complex/csqrt.c +0 -48
  177. package/libc/mingw/complex/csqrtf.c +0 -48
  178. package/libc/mingw/complex/ctan.c +0 -50
  179. package/libc/mingw/complex/ctanf.c +0 -50
  180. package/libc/mingw/math/arm/s_rint.c +0 -86
  181. package/libc/mingw/math/arm/s_rintf.c +0 -51
  182. package/libc/mingw/math/arm/sincos.S +0 -30
  183. package/libc/mingw/math/arm-common/sincosl.c +0 -13
  184. package/libc/mingw/math/arm64/rint.c +0 -12
  185. package/libc/mingw/math/arm64/rintf.c +0 -12
  186. package/libc/mingw/math/arm64/sincos.S +0 -32
  187. package/libc/mingw/math/bsd_private_base.h +0 -148
  188. package/libc/mingw/math/fdiml.c +0 -24
  189. package/libc/mingw/math/frexpf.c +0 -13
  190. package/libc/mingw/math/frexpl.c +0 -71
  191. package/libc/mingw/math/x86/acosf.c +0 -29
  192. package/libc/mingw/math/x86/atanf.c +0 -23
  193. package/libc/mingw/math/x86/atanl.c +0 -18
  194. package/libc/mingw/math/x86/cos.def.h +0 -65
  195. package/libc/mingw/math/x86/cosl.c +0 -46
  196. package/libc/mingw/math/x86/cosl_internal.S +0 -55
  197. package/libc/mingw/math/x86/ldexp.c +0 -23
  198. package/libc/mingw/math/x86/scalbn.S +0 -41
  199. package/libc/mingw/math/x86/scalbnf.S +0 -40
  200. package/libc/mingw/math/x86/sin.def.h +0 -65
  201. package/libc/mingw/math/x86/sinl.c +0 -46
  202. package/libc/mingw/math/x86/sinl_internal.S +0 -58
  203. package/libc/mingw/math/x86/tanl.S +0 -62
  204. package/libc/mingw/misc/btowc.c +0 -28
  205. package/libc/mingw/misc/wcstof.c +0 -66
  206. package/libc/mingw/misc/wcstoimax.c +0 -132
  207. package/libc/mingw/misc/wcstoumax.c +0 -126
  208. package/libc/mingw/misc/wctob.c +0 -29
  209. package/libc/mingw/misc/winbs_uint64.c +0 -6
  210. package/libc/mingw/misc/winbs_ulong.c +0 -6
  211. package/libc/mingw/misc/winbs_ushort.c +0 -6
  212. package/libc/mingw/stdio/_Exit.c +0 -10
  213. package/libc/mingw/stdio/_findfirst64i32.c +0 -21
  214. package/libc/mingw/stdio/_findnext64i32.c +0 -21
  215. package/libc/mingw/stdio/_fstat64i32.c +0 -37
  216. package/libc/mingw/stdio/_stat64i32.c +0 -37
  217. package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
  218. package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
  219. package/libc/mingw/stdio/_wstat64i32.c +0 -37
  220. package/libc/musl/src/legacy/isastream.c +0 -7
  221. package/libc/musl/src/legacy/valloc.c +0 -8
  222. package/libc/musl/src/math/__cosl.c +0 -96
  223. package/libc/musl/src/math/__sinl.c +0 -78
  224. package/libc/musl/src/math/__tanl.c +0 -143
  225. package/libc/musl/src/math/aarch64/lrint.c +0 -10
  226. package/libc/musl/src/math/aarch64/lrintf.c +0 -10
  227. package/libc/musl/src/math/aarch64/rintf.c +0 -7
  228. package/libc/musl/src/math/cosl.c +0 -39
  229. package/libc/musl/src/math/fdim.c +0 -10
  230. package/libc/musl/src/math/fdimf.c +0 -10
  231. package/libc/musl/src/math/fdiml.c +0 -18
  232. package/libc/musl/src/math/finite.c +0 -7
  233. package/libc/musl/src/math/finitef.c +0 -7
  234. package/libc/musl/src/math/frexp.c +0 -23
  235. package/libc/musl/src/math/frexpf.c +0 -23
  236. package/libc/musl/src/math/frexpl.c +0 -29
  237. package/libc/musl/src/math/i386/lrint.c +0 -8
  238. package/libc/musl/src/math/i386/lrintf.c +0 -8
  239. package/libc/musl/src/math/i386/rintf.c +0 -7
  240. package/libc/musl/src/math/lrint.c +0 -72
  241. package/libc/musl/src/math/lrintf.c +0 -8
  242. package/libc/musl/src/math/powerpc64/lrint.c +0 -16
  243. package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
  244. package/libc/musl/src/math/rintf.c +0 -30
  245. package/libc/musl/src/math/s390x/rintf.c +0 -15
  246. package/libc/musl/src/math/sincosl.c +0 -60
  247. package/libc/musl/src/math/sinl.c +0 -41
  248. package/libc/musl/src/math/tanl.c +0 -29
  249. package/libc/musl/src/math/x32/lrint.s +0 -5
  250. package/libc/musl/src/math/x32/lrintf.s +0 -5
  251. package/libc/musl/src/math/x86_64/lrint.c +0 -8
  252. package/libc/musl/src/math/x86_64/lrintf.c +0 -8
  253. package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
@@ -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
+ }
@@ -63,7 +63,7 @@ fn DoubleInt(comptime T: type) type {
63
63
  };
64
64
  }
65
65
 
66
- fn muldXi(comptime T: type, a: T, b: T) DoubleInt(T) {
66
+ pub fn muldXi(comptime T: type, a: T, b: T) DoubleInt(T) {
67
67
  const DT = DoubleInt(T);
68
68
  const word_t = compiler_rt.HalveInt(DT, false);
69
69
  const bits_in_word_2 = @sizeOf(T) * 8 / 2;
@@ -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 = a *% b;
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
+ }
@@ -3,23 +3,28 @@
3
3
  //!
4
4
  //! https://git.musl-libc.org/cgit/musl/tree/src/math/sinf.c
5
5
  //! https://git.musl-libc.org/cgit/musl/tree/src/math/sin.c
6
+ //! https://git.musl-libc.org/cgit/musl/tree/src/math/sinl.c
6
7
 
7
8
  const std = @import("std");
8
9
  const math = std.math;
9
10
  const mem = std.mem;
10
11
  const expect = std.testing.expect;
12
+ const expectApproxEqAbs = std.testing.expectApproxEqAbs;
11
13
 
12
14
  const compiler_rt = @import("../compiler_rt.zig");
13
15
  const symbol = @import("../compiler_rt.zig").symbol;
14
16
  const trig = @import("trig.zig");
15
17
  const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
16
18
  const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
19
+ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
20
+ const ld = @import("long_double.zig");
17
21
 
18
22
  comptime {
19
- symbol(&__sinh, "__sinh");
23
+ symbol(&sinh, "__sinh");
24
+ symbol(&sinl, "__sinl");
20
25
  symbol(&sinf, "sinf");
21
26
  symbol(&sin, "sin");
22
- symbol(&__sinx, "__sinx");
27
+ symbol(&sinx, "__sinx");
23
28
  if (compiler_rt.want_ppc_abi) {
24
29
  symbol(&sinq, "sinf128");
25
30
  }
@@ -27,7 +32,7 @@ comptime {
27
32
  symbol(&sinl, "sinl");
28
33
  }
29
34
 
30
- pub fn __sinh(x: f16) callconv(.c) f16 {
35
+ pub fn sinh(x: f16) callconv(.c) f16 {
31
36
  // TODO: more efficient implementation
32
37
  return @floatCast(sinf(x));
33
38
  }
@@ -55,27 +60,27 @@ pub fn sinf(x: f32) callconv(.c) f32 {
55
60
  }
56
61
  return x;
57
62
  }
58
- return trig.__sindf(x);
63
+ return trig.sindf(x);
59
64
  }
60
65
  if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4
61
66
  if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4
62
67
  if (sign) {
63
- return -trig.__cosdf(x + s1pio2);
68
+ return -trig.cosdf(x + s1pio2);
64
69
  } else {
65
- return trig.__cosdf(x - s1pio2);
70
+ return trig.cosdf(x - s1pio2);
66
71
  }
67
72
  }
68
- return trig.__sindf(if (sign) -(x + s2pio2) else -(x - s2pio2));
73
+ return trig.sindf(if (sign) -(x + s2pio2) else -(x - s2pio2));
69
74
  }
70
75
  if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4
71
76
  if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4
72
77
  if (sign) {
73
- return trig.__cosdf(x + s3pio2);
78
+ return trig.cosdf(x + s3pio2);
74
79
  } else {
75
- return -trig.__cosdf(x - s3pio2);
80
+ return -trig.cosdf(x - s3pio2);
76
81
  }
77
82
  }
78
- return trig.__sindf(if (sign) x + s4pio2 else x - s4pio2);
83
+ return trig.sindf(if (sign) x + s4pio2 else x - s4pio2);
79
84
  }
80
85
 
81
86
  // sin(Inf or NaN) is NaN
@@ -86,10 +91,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {
86
91
  var y: f64 = undefined;
87
92
  const n = rem_pio2f(x, &y);
88
93
  return switch (n & 3) {
89
- 0 => trig.__sindf(y),
90
- 1 => trig.__cosdf(y),
91
- 2 => trig.__sindf(-y),
92
- else => -trig.__cosdf(y),
94
+ 0 => trig.sindf(y),
95
+ 1 => trig.cosdf(y),
96
+ 2 => trig.sindf(-y),
97
+ else => -trig.cosdf(y),
93
98
  };
94
99
  }
95
100
 
@@ -110,7 +115,7 @@ pub fn sin(x: f64) callconv(.c) f64 {
110
115
  }
111
116
  return x;
112
117
  }
113
- return trig.__sin(x, 0.0, 0);
118
+ return trig.sin(x, 0.0, 0);
114
119
  }
115
120
 
116
121
  // sin(Inf or NaN) is NaN
@@ -121,72 +126,152 @@ pub fn sin(x: f64) callconv(.c) f64 {
121
126
  var y: [2]f64 = undefined;
122
127
  const n = rem_pio2(x, &y);
123
128
  return switch (n & 3) {
124
- 0 => trig.__sin(y[0], y[1], 1),
125
- 1 => trig.__cos(y[0], y[1]),
126
- 2 => -trig.__sin(y[0], y[1], 1),
127
- else => -trig.__cos(y[0], y[1]),
129
+ 0 => trig.sin(y[0], y[1], 1),
130
+ 1 => trig.cos(y[0], y[1]),
131
+ 2 => -trig.sin(y[0], y[1], 1),
132
+ else => -trig.cos(y[0], y[1]),
128
133
  };
129
134
  }
130
135
 
131
- pub fn __sinx(x: f80) callconv(.c) f80 {
132
- // TODO: more efficient implementation
133
- return @floatCast(sinq(x));
136
+ fn sinx(x: f80) callconv(.c) f80 {
137
+ const se = ld.signExponent(x) & 0x7fff;
138
+ if (se == 0x7fff) {
139
+ return x - x;
140
+ }
141
+
142
+ if (@abs(x) < trig.pi_4) {
143
+ if (se < 0x3fff - (math.floatMantissaBits(f80) / 2)) {
144
+ // raise inexact if x!=0 and underflow if subnormal
145
+ if (compiler_rt.want_float_exceptions) {
146
+ mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
147
+ }
148
+ return x;
149
+ }
150
+ return trig.sinx(x, 0.0, 0);
151
+ }
152
+
153
+ var y: [2]f80 = undefined;
154
+ const n = rem_pio2l(f80, x, &y);
155
+ return switch (n & 3) {
156
+ 0 => trig.sinx(y[0], y[1], 1),
157
+ 1 => trig.cosx(y[0], y[1]),
158
+ 2 => -trig.sinx(y[0], y[1], 1),
159
+ else => -trig.cosx(y[0], y[1]),
160
+ };
134
161
  }
135
162
 
136
163
  pub fn sinq(x: f128) callconv(.c) f128 {
137
- // TODO: more correct implementation
138
- return sin(@floatCast(x));
164
+ const se = ld.signExponent(x) & 0x7fff;
165
+ if (se == 0x7fff) {
166
+ return x - x;
167
+ }
168
+
169
+ if (@abs(x) < trig.pi_4) {
170
+ if (se < 0x3fff - (math.floatMantissaBits(f128) / 2)) {
171
+ // raise inexact if x!=0 and underflow if subnormal
172
+ if (compiler_rt.want_float_exceptions) {
173
+ mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
174
+ }
175
+ return x;
176
+ }
177
+ return trig.sinq(x, 0.0, 0);
178
+ }
179
+
180
+ var y: [2]f128 = undefined;
181
+ const n = rem_pio2l(f128, x, &y);
182
+ return switch (n & 3) {
183
+ 0 => trig.sinq(y[0], y[1], 1),
184
+ 1 => trig.cosq(y[0], y[1]),
185
+ 2 => -trig.sinq(y[0], y[1], 1),
186
+ else => -trig.cosq(y[0], y[1]),
187
+ };
139
188
  }
140
189
 
141
190
  pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {
142
191
  switch (@typeInfo(c_longdouble).float.bits) {
143
- 16 => return __sinh(x),
192
+ 16 => return sinh(x),
144
193
  32 => return sinf(x),
145
194
  64 => return sin(x),
146
- 80 => return __sinx(x),
195
+ 80 => return sinx(x),
147
196
  128 => return sinq(x),
148
197
  else => @compileError("unreachable"),
149
198
  }
150
199
  }
151
200
 
152
- test "sin32" {
153
- const epsilon = 0.00001;
201
+ fn testSinSpecial(comptime T: type) !void {
202
+ const f = switch (T) {
203
+ f32 => sinf,
204
+ f64 => sin,
205
+ f80 => sinx,
206
+ f128 => sinq,
207
+ else => @compileError("unimplemented"),
208
+ };
154
209
 
155
- try expect(math.approxEqAbs(f32, sinf(0.0), 0.0, epsilon));
156
- try expect(math.approxEqAbs(f32, sinf(0.2), 0.198669, epsilon));
157
- try expect(math.approxEqAbs(f32, sinf(0.8923), 0.778517, epsilon));
158
- try expect(math.approxEqAbs(f32, sinf(1.5), 0.997495, epsilon));
159
- try expect(math.approxEqAbs(f32, sinf(-1.5), -0.997495, epsilon));
160
- try expect(math.approxEqAbs(f32, sinf(37.45), -0.246544, epsilon));
161
- try expect(math.approxEqAbs(f32, sinf(89.123), 0.916166, epsilon));
210
+ try expect(math.isPositiveZero(f(0.0)));
211
+ try expect(math.isNegativeZero(f(-0.0)));
212
+ try expect(math.isNan(f(math.inf(T))));
213
+ try expect(math.isNan(f(-math.inf(T))));
214
+ try expect(math.isNan(f(math.nan(T))));
162
215
  }
163
216
 
164
- test "sin64" {
165
- const epsilon = 0.000001;
166
-
167
- try expect(math.approxEqAbs(f64, sin(0.0), 0.0, epsilon));
168
- try expect(math.approxEqAbs(f64, sin(0.2), 0.198669, epsilon));
169
- try expect(math.approxEqAbs(f64, sin(0.8923), 0.778517, epsilon));
170
- try expect(math.approxEqAbs(f64, sin(1.5), 0.997495, epsilon));
171
- try expect(math.approxEqAbs(f64, sin(-1.5), -0.997495, epsilon));
172
- try expect(math.approxEqAbs(f64, sin(37.45), -0.246543, epsilon));
173
- try expect(math.approxEqAbs(f64, sin(89.123), 0.916166, epsilon));
217
+ test "sin32.normal" {
218
+ const epsilon = math.floatEps(f32);
219
+ try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon);
220
+ try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon);
221
+ try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon);
222
+ try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon);
223
+ try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon);
224
+ try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon);
225
+ try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon);
174
226
  }
175
227
 
176
228
  test "sin32.special" {
177
- try expect(sinf(0.0) == 0.0);
178
- try expect(sinf(-0.0) == -0.0);
179
- try expect(math.isNan(sinf(math.inf(f32))));
180
- try expect(math.isNan(sinf(-math.inf(f32))));
181
- try expect(math.isNan(sinf(math.nan(f32))));
229
+ try testSinSpecial(f32);
230
+ }
231
+
232
+ test "sin64.normal" {
233
+ const epsilon = math.floatEps(f64);
234
+ try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon);
235
+ try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon);
236
+ try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon);
237
+ try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon);
238
+ try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon);
239
+ try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon);
240
+ try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon);
182
241
  }
183
242
 
184
243
  test "sin64.special" {
185
- try expect(sin(0.0) == 0.0);
186
- try expect(sin(-0.0) == -0.0);
187
- try expect(math.isNan(sin(math.inf(f64))));
188
- try expect(math.isNan(sin(-math.inf(f64))));
189
- try expect(math.isNan(sin(math.nan(f64))));
244
+ try testSinSpecial(f64);
245
+ }
246
+
247
+ test "sin80.normal" {
248
+ const epsilon = math.floatEps(f80);
249
+ try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon);
250
+ try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon);
251
+ try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon);
252
+ try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon);
253
+ try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon);
254
+ try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon);
255
+ try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon);
256
+ }
257
+
258
+ test "sin80.special" {
259
+ try testSinSpecial(f80);
260
+ }
261
+
262
+ test "sin128.normal" {
263
+ const epsilon = math.floatEps(f128);
264
+ try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon);
265
+ try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon);
266
+ try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon);
267
+ try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon);
268
+ try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon);
269
+ try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon);
270
+ try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon);
271
+ }
272
+
273
+ test "sin128.special" {
274
+ try testSinSpecial(f128);
190
275
  }
191
276
 
192
277
  test "sin32 #9901" {