usearch 2.21.3 → 2.25.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.
Files changed (602) hide show
  1. package/README.md +24 -24
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +7 -7
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +83 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +235 -52
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/dist/cjs/usearch.d.ts +8 -3
  16. package/javascript/dist/cjs/usearch.js +12 -4
  17. package/javascript/dist/esm/usearch.d.ts +8 -3
  18. package/javascript/dist/esm/usearch.js +12 -4
  19. package/javascript/lib.cpp +17 -0
  20. package/javascript/usearch.ts +14 -6
  21. package/numkong/.clang-tidy +30 -0
  22. package/{simsimd → numkong}/.cmake-format.py +18 -0
  23. package/numkong/.editorconfig +12 -0
  24. package/numkong/.git-blame-ignore-revs +123 -0
  25. package/numkong/.mailmap +15 -0
  26. package/numkong/.spi.yml +11 -0
  27. package/numkong/.swift-format +14 -0
  28. package/numkong/CITATION.cff +81 -0
  29. package/numkong/CONTRIBUTING.md +500 -0
  30. package/numkong/Cargo.toml +54 -0
  31. package/numkong/MANIFEST.in +8 -0
  32. package/numkong/Package.swift +84 -0
  33. package/numkong/README.md +569 -0
  34. package/numkong/bench/README.md +217 -0
  35. package/numkong/bench/bench-browser.html +323 -0
  36. package/numkong/bench/bench.cpp +344 -0
  37. package/numkong/bench/bench.hpp +816 -0
  38. package/numkong/bench/bench.js +148 -0
  39. package/numkong/bench/bench.mjs +616 -0
  40. package/numkong/bench/bench_attention.cpp +113 -0
  41. package/numkong/bench/bench_cast.cpp +264 -0
  42. package/numkong/bench/bench_cross_amx.cpp +62 -0
  43. package/numkong/bench/bench_cross_arm.cpp +245 -0
  44. package/numkong/bench/bench_cross_blas.cpp +309 -0
  45. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  46. package/numkong/bench/bench_cross_power.cpp +84 -0
  47. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  48. package/numkong/bench/bench_cross_serial.cpp +151 -0
  49. package/numkong/bench/bench_cross_sme.cpp +163 -0
  50. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  51. package/numkong/bench/bench_cross_x86.cpp +455 -0
  52. package/numkong/bench/bench_curved.cpp +210 -0
  53. package/numkong/bench/bench_dot.cpp +315 -0
  54. package/numkong/bench/bench_each.cpp +503 -0
  55. package/numkong/bench/bench_geospatial.cpp +112 -0
  56. package/numkong/bench/bench_maxsim.cpp +154 -0
  57. package/numkong/bench/bench_mesh.cpp +148 -0
  58. package/numkong/bench/bench_probability.cpp +60 -0
  59. package/numkong/bench/bench_reduce.cpp +371 -0
  60. package/numkong/bench/bench_set.cpp +73 -0
  61. package/numkong/bench/bench_sparse.cpp +198 -0
  62. package/numkong/bench/bench_spatial.cpp +347 -0
  63. package/numkong/bench/bench_trigonometry.cpp +137 -0
  64. package/numkong/bench/swift/Bench.swift +506 -0
  65. package/numkong/binding.gyp +169 -0
  66. package/numkong/build.rs +484 -0
  67. package/numkong/c/dispatch.h +512 -0
  68. package/numkong/c/dispatch_bf16.c +447 -0
  69. package/numkong/c/dispatch_bf16c.c +52 -0
  70. package/numkong/c/dispatch_e2m3.c +296 -0
  71. package/numkong/c/dispatch_e3m2.c +284 -0
  72. package/numkong/c/dispatch_e4m3.c +318 -0
  73. package/numkong/c/dispatch_e5m2.c +316 -0
  74. package/numkong/c/dispatch_f16.c +452 -0
  75. package/numkong/c/dispatch_f16c.c +58 -0
  76. package/numkong/c/dispatch_f32.c +434 -0
  77. package/numkong/c/dispatch_f32c.c +99 -0
  78. package/numkong/c/dispatch_f64.c +348 -0
  79. package/numkong/c/dispatch_f64c.c +98 -0
  80. package/numkong/c/dispatch_i16.c +96 -0
  81. package/numkong/c/dispatch_i32.c +89 -0
  82. package/numkong/c/dispatch_i4.c +153 -0
  83. package/numkong/c/dispatch_i64.c +86 -0
  84. package/numkong/c/dispatch_i8.c +348 -0
  85. package/numkong/c/dispatch_other.c +348 -0
  86. package/numkong/c/dispatch_u1.c +193 -0
  87. package/numkong/c/dispatch_u16.c +124 -0
  88. package/numkong/c/dispatch_u32.c +118 -0
  89. package/numkong/c/dispatch_u4.c +153 -0
  90. package/numkong/c/dispatch_u64.c +102 -0
  91. package/numkong/c/dispatch_u8.c +364 -0
  92. package/numkong/c/numkong.c +940 -0
  93. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  94. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  95. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  96. package/numkong/cmake/nk_math_lib.cmake +46 -0
  97. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  99. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  100. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  101. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  102. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  103. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  104. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  105. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  106. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  107. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  108. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  109. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  110. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  111. package/numkong/include/README.md +643 -0
  112. package/numkong/include/module.modulemap +129 -0
  113. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  114. package/numkong/include/numkong/attention/sme.h +2075 -0
  115. package/numkong/include/numkong/attention.h +49 -0
  116. package/numkong/include/numkong/capabilities.h +930 -0
  117. package/numkong/include/numkong/cast/README.md +262 -0
  118. package/numkong/include/numkong/cast/diamond.h +64 -0
  119. package/numkong/include/numkong/cast/haswell.h +823 -0
  120. package/numkong/include/numkong/cast/icelake.h +475 -0
  121. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  122. package/numkong/include/numkong/cast/neon.h +1174 -0
  123. package/numkong/include/numkong/cast/powervsx.h +449 -0
  124. package/numkong/include/numkong/cast/rvv.h +970 -0
  125. package/numkong/include/numkong/cast/sapphire.h +262 -0
  126. package/numkong/include/numkong/cast/serial.h +2336 -0
  127. package/numkong/include/numkong/cast/skylake.h +915 -0
  128. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  129. package/numkong/include/numkong/cast.h +254 -0
  130. package/numkong/include/numkong/cast.hpp +44 -0
  131. package/numkong/include/numkong/curved/README.md +223 -0
  132. package/numkong/include/numkong/curved/genoa.h +182 -0
  133. package/numkong/include/numkong/curved/haswell.h +276 -0
  134. package/numkong/include/numkong/curved/neon.h +329 -0
  135. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  136. package/numkong/include/numkong/curved/rvv.h +305 -0
  137. package/numkong/include/numkong/curved/serial.h +207 -0
  138. package/numkong/include/numkong/curved/skylake.h +457 -0
  139. package/numkong/include/numkong/curved/smef64.h +530 -0
  140. package/numkong/include/numkong/curved.h +513 -0
  141. package/numkong/include/numkong/curved.hpp +144 -0
  142. package/numkong/include/numkong/dot/README.md +442 -0
  143. package/numkong/include/numkong/dot/alder.h +563 -0
  144. package/numkong/include/numkong/dot/diamond.h +158 -0
  145. package/numkong/include/numkong/dot/genoa.h +289 -0
  146. package/numkong/include/numkong/dot/haswell.h +1723 -0
  147. package/numkong/include/numkong/dot/icelake.h +997 -0
  148. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  149. package/numkong/include/numkong/dot/neon.h +869 -0
  150. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  151. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  152. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  153. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  154. package/numkong/include/numkong/dot/powervsx.h +752 -0
  155. package/numkong/include/numkong/dot/rvv.h +722 -0
  156. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  157. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  158. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  159. package/numkong/include/numkong/dot/sapphire.h +141 -0
  160. package/numkong/include/numkong/dot/serial.h +874 -0
  161. package/numkong/include/numkong/dot/sierra.h +405 -0
  162. package/numkong/include/numkong/dot/skylake.h +1116 -0
  163. package/numkong/include/numkong/dot/sve.h +420 -0
  164. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  165. package/numkong/include/numkong/dot/svehalf.h +168 -0
  166. package/numkong/include/numkong/dot/svesdot.h +90 -0
  167. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  168. package/numkong/include/numkong/dot.h +1136 -0
  169. package/numkong/include/numkong/dot.hpp +94 -0
  170. package/numkong/include/numkong/dots/README.md +496 -0
  171. package/numkong/include/numkong/dots/alder.h +117 -0
  172. package/numkong/include/numkong/dots/diamond.h +86 -0
  173. package/numkong/include/numkong/dots/genoa.h +100 -0
  174. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  175. package/numkong/include/numkong/dots/haswell.h +310 -0
  176. package/numkong/include/numkong/dots/icelake.h +180 -0
  177. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  178. package/numkong/include/numkong/dots/neon.h +123 -0
  179. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  180. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  181. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  182. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  183. package/numkong/include/numkong/dots/powervsx.h +194 -0
  184. package/numkong/include/numkong/dots/rvv.h +2593 -0
  185. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  186. package/numkong/include/numkong/dots/serial.h +2867 -0
  187. package/numkong/include/numkong/dots/sierra.h +100 -0
  188. package/numkong/include/numkong/dots/skylake.h +207 -0
  189. package/numkong/include/numkong/dots/sme.h +5041 -0
  190. package/numkong/include/numkong/dots/smebi32.h +477 -0
  191. package/numkong/include/numkong/dots/smef64.h +1328 -0
  192. package/numkong/include/numkong/dots/smehalf.h +47 -0
  193. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  194. package/numkong/include/numkong/dots.h +3110 -0
  195. package/numkong/include/numkong/dots.hpp +641 -0
  196. package/numkong/include/numkong/each/README.md +465 -0
  197. package/numkong/include/numkong/each/haswell.h +1658 -0
  198. package/numkong/include/numkong/each/icelake.h +272 -0
  199. package/numkong/include/numkong/each/neon.h +1138 -0
  200. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  201. package/numkong/include/numkong/each/neonhalf.h +318 -0
  202. package/numkong/include/numkong/each/rvv.h +1121 -0
  203. package/numkong/include/numkong/each/sapphire.h +343 -0
  204. package/numkong/include/numkong/each/serial.h +282 -0
  205. package/numkong/include/numkong/each/skylake.h +1562 -0
  206. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  207. package/numkong/include/numkong/each.h +2232 -0
  208. package/numkong/include/numkong/each.hpp +434 -0
  209. package/numkong/include/numkong/geospatial/README.md +147 -0
  210. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  211. package/numkong/include/numkong/geospatial/neon.h +615 -0
  212. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  213. package/numkong/include/numkong/geospatial/serial.h +309 -0
  214. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  215. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  216. package/numkong/include/numkong/geospatial.h +453 -0
  217. package/numkong/include/numkong/geospatial.hpp +235 -0
  218. package/numkong/include/numkong/matrix.hpp +336 -0
  219. package/numkong/include/numkong/maxsim/README.md +187 -0
  220. package/numkong/include/numkong/maxsim/alder.h +511 -0
  221. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  222. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  223. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  224. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  225. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  226. package/numkong/include/numkong/maxsim/serial.h +490 -0
  227. package/numkong/include/numkong/maxsim/sme.h +993 -0
  228. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  229. package/numkong/include/numkong/maxsim.h +571 -0
  230. package/numkong/include/numkong/maxsim.hpp +133 -0
  231. package/numkong/include/numkong/mesh/README.md +219 -0
  232. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  233. package/numkong/include/numkong/mesh/neon.h +1821 -0
  234. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  235. package/numkong/include/numkong/mesh/rvv.h +936 -0
  236. package/numkong/include/numkong/mesh/serial.h +721 -0
  237. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  238. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  239. package/numkong/include/numkong/mesh.h +666 -0
  240. package/numkong/include/numkong/mesh.hpp +701 -0
  241. package/numkong/include/numkong/numkong.h +78 -0
  242. package/numkong/include/numkong/numkong.hpp +58 -0
  243. package/numkong/include/numkong/probability/README.md +177 -0
  244. package/numkong/include/numkong/probability/haswell.h +267 -0
  245. package/numkong/include/numkong/probability/neon.h +255 -0
  246. package/numkong/include/numkong/probability/rvv.h +414 -0
  247. package/numkong/include/numkong/probability/serial.h +181 -0
  248. package/numkong/include/numkong/probability/skylake.h +324 -0
  249. package/numkong/include/numkong/probability.h +380 -0
  250. package/numkong/include/numkong/probability.hpp +120 -0
  251. package/numkong/include/numkong/random.h +50 -0
  252. package/numkong/include/numkong/random.hpp +285 -0
  253. package/numkong/include/numkong/reduce/README.md +552 -0
  254. package/numkong/include/numkong/reduce/alder.h +636 -0
  255. package/numkong/include/numkong/reduce/genoa.h +201 -0
  256. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  257. package/numkong/include/numkong/reduce/icelake.h +549 -0
  258. package/numkong/include/numkong/reduce/neon.h +3980 -0
  259. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  260. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  261. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  262. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  263. package/numkong/include/numkong/reduce/serial.h +753 -0
  264. package/numkong/include/numkong/reduce/sierra.h +338 -0
  265. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  266. package/numkong/include/numkong/reduce/sve.h +52 -0
  267. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  268. package/numkong/include/numkong/reduce.h +1582 -0
  269. package/numkong/include/numkong/reduce.hpp +778 -0
  270. package/numkong/include/numkong/scalar/README.md +89 -0
  271. package/numkong/include/numkong/scalar/haswell.h +122 -0
  272. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  273. package/numkong/include/numkong/scalar/neon.h +122 -0
  274. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  275. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  276. package/numkong/include/numkong/scalar/rvv.h +211 -0
  277. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  278. package/numkong/include/numkong/scalar/serial.h +332 -0
  279. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  280. package/numkong/include/numkong/scalar.h +696 -0
  281. package/numkong/include/numkong/set/README.md +179 -0
  282. package/numkong/include/numkong/set/haswell.h +334 -0
  283. package/numkong/include/numkong/set/icelake.h +485 -0
  284. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  285. package/numkong/include/numkong/set/neon.h +363 -0
  286. package/numkong/include/numkong/set/powervsx.h +326 -0
  287. package/numkong/include/numkong/set/rvv.h +226 -0
  288. package/numkong/include/numkong/set/rvvbb.h +117 -0
  289. package/numkong/include/numkong/set/serial.h +174 -0
  290. package/numkong/include/numkong/set/sve.h +187 -0
  291. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  292. package/numkong/include/numkong/set.h +471 -0
  293. package/numkong/include/numkong/set.hpp +114 -0
  294. package/numkong/include/numkong/sets/README.md +149 -0
  295. package/numkong/include/numkong/sets/haswell.h +63 -0
  296. package/numkong/include/numkong/sets/icelake.h +66 -0
  297. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  298. package/numkong/include/numkong/sets/neon.h +61 -0
  299. package/numkong/include/numkong/sets/powervsx.h +65 -0
  300. package/numkong/include/numkong/sets/serial.h +43 -0
  301. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  302. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  303. package/numkong/include/numkong/sets.h +382 -0
  304. package/numkong/include/numkong/sparse/README.md +156 -0
  305. package/numkong/include/numkong/sparse/icelake.h +463 -0
  306. package/numkong/include/numkong/sparse/neon.h +288 -0
  307. package/numkong/include/numkong/sparse/serial.h +117 -0
  308. package/numkong/include/numkong/sparse/sve2.h +504 -0
  309. package/numkong/include/numkong/sparse/turin.h +322 -0
  310. package/numkong/include/numkong/sparse.h +363 -0
  311. package/numkong/include/numkong/sparse.hpp +113 -0
  312. package/numkong/include/numkong/spatial/README.md +439 -0
  313. package/numkong/include/numkong/spatial/alder.h +604 -0
  314. package/numkong/include/numkong/spatial/diamond.h +240 -0
  315. package/numkong/include/numkong/spatial/genoa.h +222 -0
  316. package/numkong/include/numkong/spatial/haswell.h +979 -0
  317. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  318. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  319. package/numkong/include/numkong/spatial/neon.h +846 -0
  320. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  321. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  322. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  323. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  324. package/numkong/include/numkong/spatial/rvv.h +991 -0
  325. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  326. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  327. package/numkong/include/numkong/spatial/serial.h +347 -0
  328. package/numkong/include/numkong/spatial/sierra.h +516 -0
  329. package/numkong/include/numkong/spatial/skylake.h +605 -0
  330. package/numkong/include/numkong/spatial/sve.h +246 -0
  331. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  332. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  333. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  334. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  335. package/numkong/include/numkong/spatial.h +1681 -0
  336. package/numkong/include/numkong/spatial.hpp +183 -0
  337. package/numkong/include/numkong/spatials/README.md +580 -0
  338. package/numkong/include/numkong/spatials/alder.h +94 -0
  339. package/numkong/include/numkong/spatials/diamond.h +82 -0
  340. package/numkong/include/numkong/spatials/genoa.h +94 -0
  341. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  342. package/numkong/include/numkong/spatials/haswell.h +219 -0
  343. package/numkong/include/numkong/spatials/icelake.h +113 -0
  344. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  345. package/numkong/include/numkong/spatials/neon.h +109 -0
  346. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  347. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  348. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  349. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  350. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  351. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  352. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  353. package/numkong/include/numkong/spatials/serial.h +248 -0
  354. package/numkong/include/numkong/spatials/sierra.h +96 -0
  355. package/numkong/include/numkong/spatials/skylake.h +184 -0
  356. package/numkong/include/numkong/spatials/sme.h +1927 -0
  357. package/numkong/include/numkong/spatials/smef64.h +483 -0
  358. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  359. package/numkong/include/numkong/spatials.h +3374 -0
  360. package/numkong/include/numkong/spatials.hpp +509 -0
  361. package/numkong/include/numkong/tensor.hpp +1981 -0
  362. package/numkong/include/numkong/trigonometry/README.md +184 -0
  363. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  364. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  365. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  366. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  367. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  368. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  369. package/numkong/include/numkong/trigonometry.h +467 -0
  370. package/numkong/include/numkong/trigonometry.hpp +166 -0
  371. package/numkong/include/numkong/types.h +1695 -0
  372. package/numkong/include/numkong/types.hpp +6027 -0
  373. package/numkong/include/numkong/vector.hpp +766 -0
  374. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  375. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  376. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  377. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  378. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  380. package/numkong/javascript/README.md +254 -0
  381. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  382. package/numkong/javascript/numkong-browser.ts +40 -0
  383. package/numkong/javascript/numkong-wasm.ts +750 -0
  384. package/numkong/javascript/numkong.c +712 -0
  385. package/numkong/javascript/numkong.ts +613 -0
  386. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  387. package/numkong/javascript/tsconfig-cjs.json +13 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  389. package/numkong/javascript/types.ts +784 -0
  390. package/numkong/numkong.gypi +104 -0
  391. package/numkong/package.json +108 -0
  392. package/numkong/probes/arm_neon.c +8 -0
  393. package/numkong/probes/arm_neon_bfdot.c +9 -0
  394. package/numkong/probes/arm_neon_fhm.c +9 -0
  395. package/numkong/probes/arm_neon_half.c +8 -0
  396. package/numkong/probes/arm_neon_sdot.c +9 -0
  397. package/numkong/probes/arm_neonfp8.c +9 -0
  398. package/numkong/probes/arm_sme.c +16 -0
  399. package/numkong/probes/arm_sme2.c +16 -0
  400. package/numkong/probes/arm_sme2p1.c +16 -0
  401. package/numkong/probes/arm_sme_bf16.c +16 -0
  402. package/numkong/probes/arm_sme_bi32.c +16 -0
  403. package/numkong/probes/arm_sme_f64.c +16 -0
  404. package/numkong/probes/arm_sme_fa64.c +14 -0
  405. package/numkong/probes/arm_sme_half.c +16 -0
  406. package/numkong/probes/arm_sme_lut2.c +15 -0
  407. package/numkong/probes/arm_sve.c +18 -0
  408. package/numkong/probes/arm_sve2.c +20 -0
  409. package/numkong/probes/arm_sve2p1.c +18 -0
  410. package/numkong/probes/arm_sve_bfdot.c +20 -0
  411. package/numkong/probes/arm_sve_half.c +18 -0
  412. package/numkong/probes/arm_sve_sdot.c +21 -0
  413. package/numkong/probes/loongarch_lasx.c +12 -0
  414. package/numkong/probes/power_vsx.c +12 -0
  415. package/numkong/probes/probe.js +127 -0
  416. package/numkong/probes/riscv_rvv.c +14 -0
  417. package/numkong/probes/riscv_rvv_bb.c +15 -0
  418. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  419. package/numkong/probes/riscv_rvv_half.c +14 -0
  420. package/numkong/probes/wasm_v128relaxed.c +11 -0
  421. package/numkong/probes/x86_alder.c +17 -0
  422. package/numkong/probes/x86_diamond.c +17 -0
  423. package/numkong/probes/x86_genoa.c +17 -0
  424. package/numkong/probes/x86_graniteamx.c +19 -0
  425. package/numkong/probes/x86_haswell.c +11 -0
  426. package/numkong/probes/x86_icelake.c +17 -0
  427. package/numkong/probes/x86_sapphire.c +16 -0
  428. package/numkong/probes/x86_sapphireamx.c +18 -0
  429. package/numkong/probes/x86_sierra.c +17 -0
  430. package/numkong/probes/x86_skylake.c +15 -0
  431. package/numkong/probes/x86_turin.c +17 -0
  432. package/numkong/rust/README.md +698 -0
  433. package/numkong/rust/capabilities.rs +96 -0
  434. package/numkong/rust/cast.rs +314 -0
  435. package/numkong/rust/curved.rs +391 -0
  436. package/numkong/rust/each.rs +2721 -0
  437. package/numkong/rust/geospatial.rs +343 -0
  438. package/numkong/rust/matrix.rs +5424 -0
  439. package/numkong/rust/maxsim.rs +540 -0
  440. package/numkong/rust/mesh.rs +837 -0
  441. package/numkong/rust/numkong.rs +409 -0
  442. package/numkong/rust/probability.rs +272 -0
  443. package/numkong/rust/reduce.rs +1249 -0
  444. package/numkong/rust/set.rs +194 -0
  445. package/numkong/rust/sparse.rs +513 -0
  446. package/numkong/rust/spatial.rs +1815 -0
  447. package/numkong/rust/tensor.rs +7565 -0
  448. package/numkong/rust/types.rs +3666 -0
  449. package/numkong/rust/vector.rs +1899 -0
  450. package/numkong/rustfmt.toml +2 -0
  451. package/numkong/swift/Matrix.swift +1388 -0
  452. package/numkong/swift/MaxSim.swift +151 -0
  453. package/numkong/swift/NumKong.swift +283 -0
  454. package/numkong/swift/Numerics.swift +329 -0
  455. package/numkong/swift/README.md +433 -0
  456. package/numkong/swift/Scalar.swift +741 -0
  457. package/numkong/swift/Tensor.swift +209 -0
  458. package/numkong/test/README.md +315 -0
  459. package/numkong/test/playwright.config.ts +16 -0
  460. package/numkong/test/swift/Test.swift +534 -0
  461. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  462. package/numkong/test/test-browser-bundle.html +188 -0
  463. package/numkong/test/test-browser-runner.mjs +43 -0
  464. package/numkong/test/test-browser.html +305 -0
  465. package/numkong/test/test-dtypes.mjs +453 -0
  466. package/numkong/test/test-wasm.mjs +267 -0
  467. package/numkong/test/test.cpp +442 -0
  468. package/numkong/test/test.hpp +580 -0
  469. package/numkong/test/test.mjs +363 -0
  470. package/numkong/test/test_base.py +1041 -0
  471. package/numkong/test/test_cast.cpp +242 -0
  472. package/numkong/test/test_cross.hpp +551 -0
  473. package/numkong/test/test_cross.py +467 -0
  474. package/numkong/test/test_cross_amx.cpp +50 -0
  475. package/numkong/test/test_cross_arm.cpp +225 -0
  476. package/numkong/test/test_cross_blas.cpp +354 -0
  477. package/numkong/test/test_cross_loongarch.cpp +90 -0
  478. package/numkong/test/test_cross_power.cpp +73 -0
  479. package/numkong/test/test_cross_rvv.cpp +109 -0
  480. package/numkong/test/test_cross_serial.cpp +181 -0
  481. package/numkong/test/test_cross_sme.cpp +148 -0
  482. package/numkong/test/test_cross_wasm.cpp +141 -0
  483. package/numkong/test/test_cross_x86.cpp +442 -0
  484. package/numkong/test/test_curved.cpp +182 -0
  485. package/numkong/test/test_curved.py +207 -0
  486. package/numkong/test/test_dot.cpp +353 -0
  487. package/numkong/test/test_dot.py +296 -0
  488. package/numkong/test/test_each.cpp +437 -0
  489. package/numkong/test/test_each.py +756 -0
  490. package/numkong/test/test_geospatial.cpp +155 -0
  491. package/numkong/test/test_geospatial.py +241 -0
  492. package/numkong/test/test_maxsim.cpp +138 -0
  493. package/numkong/test/test_maxsim.py +209 -0
  494. package/numkong/test/test_mesh.cpp +203 -0
  495. package/numkong/test/test_mesh.py +394 -0
  496. package/numkong/test/test_probability.cpp +136 -0
  497. package/numkong/test/test_probability.py +166 -0
  498. package/numkong/test/test_reduce.cpp +563 -0
  499. package/numkong/test/test_reduce.py +781 -0
  500. package/numkong/test/test_set.cpp +151 -0
  501. package/numkong/test/test_set.py +120 -0
  502. package/numkong/test/test_similarities.py +579 -0
  503. package/numkong/test/test_sparse.cpp +121 -0
  504. package/numkong/test/test_sparse.py +118 -0
  505. package/numkong/test/test_spatial.cpp +518 -0
  506. package/numkong/test/test_spatial.py +269 -0
  507. package/numkong/test/test_tensor.cpp +884 -0
  508. package/numkong/test/test_tensor.py +1417 -0
  509. package/numkong/test/test_trigonometry.cpp +156 -0
  510. package/numkong/test/test_trigonometry.py +180 -0
  511. package/package.json +7 -8
  512. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  513. package/prebuilds/linux-arm64/usearch.node +0 -0
  514. package/prebuilds/linux-x64/usearch.node +0 -0
  515. package/fp16/CMakeLists.txt +0 -176
  516. package/fp16/LICENSE +0 -11
  517. package/fp16/README.md +0 -20
  518. package/fp16/bench/alt-element.cc +0 -89
  519. package/fp16/bench/from-alt-array.cc +0 -175
  520. package/fp16/bench/from-ieee-array.cc +0 -399
  521. package/fp16/bench/ieee-element.cc +0 -272
  522. package/fp16/bench/to-alt-array.cc +0 -91
  523. package/fp16/bench/to-ieee-array.cc +0 -303
  524. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  525. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  526. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  527. package/fp16/configure.py +0 -65
  528. package/fp16/confu.yaml +0 -8
  529. package/fp16/include/fp16/__init__.py +0 -0
  530. package/fp16/include/fp16/avx.py +0 -50
  531. package/fp16/include/fp16/avx2.py +0 -53
  532. package/fp16/include/fp16/bitcasts.h +0 -92
  533. package/fp16/include/fp16/fp16.h +0 -451
  534. package/fp16/include/fp16/psimd.h +0 -131
  535. package/fp16/include/fp16.h +0 -11
  536. package/fp16/jni/Android.mk +0 -6
  537. package/fp16/jni/Application.mk +0 -4
  538. package/fp16/test/alt-from-fp32-value.cc +0 -498
  539. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  540. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  541. package/fp16/test/alt-to-fp32-value.cc +0 -348
  542. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  543. package/fp16/test/bitcasts.cc +0 -56
  544. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  545. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  546. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  547. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  548. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  549. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  550. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  551. package/fp16/test/peachpy/stubs.py +0 -38
  552. package/fp16/test/tables.cc +0 -530
  553. package/fp16/test/tables.h +0 -13
  554. package/fp16/third-party/THHalf.h +0 -92
  555. package/fp16/third-party/eigen-half.h +0 -170
  556. package/fp16/third-party/float16-compressor.h +0 -80
  557. package/fp16/third-party/half.hpp +0 -2916
  558. package/fp16/third-party/npy-halffloat.h +0 -328
  559. package/simsimd/.git-blame-ignore-revs +0 -2
  560. package/simsimd/CONTRIBUTING.md +0 -321
  561. package/simsimd/Cargo.toml +0 -49
  562. package/simsimd/MANIFEST.in +0 -4
  563. package/simsimd/Package.swift +0 -28
  564. package/simsimd/README.md +0 -1493
  565. package/simsimd/binding.gyp +0 -35
  566. package/simsimd/build.rs +0 -70
  567. package/simsimd/c/lib.c +0 -374
  568. package/simsimd/include/module.modulemap +0 -4
  569. package/simsimd/include/simsimd/binary.h +0 -486
  570. package/simsimd/include/simsimd/curved.h +0 -1541
  571. package/simsimd/include/simsimd/dot.h +0 -1853
  572. package/simsimd/include/simsimd/elementwise.h +0 -2465
  573. package/simsimd/include/simsimd/geospatial.h +0 -43
  574. package/simsimd/include/simsimd/mesh.h +0 -69
  575. package/simsimd/include/simsimd/probability.h +0 -606
  576. package/simsimd/include/simsimd/simsimd.h +0 -2567
  577. package/simsimd/include/simsimd/sparse.h +0 -1384
  578. package/simsimd/include/simsimd/spatial.h +0 -2335
  579. package/simsimd/include/simsimd/types.h +0 -666
  580. package/simsimd/javascript/fallback.ts +0 -233
  581. package/simsimd/javascript/lib.c +0 -125
  582. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  583. package/simsimd/javascript/simsimd.ts +0 -179
  584. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  585. package/simsimd/package-lock.json +0 -1761
  586. package/simsimd/package.json +0 -61
  587. package/simsimd/rust/lib.rs +0 -1821
  588. package/simsimd/scripts/bench.cxx +0 -1170
  589. package/simsimd/scripts/bench.ipynb +0 -187
  590. package/simsimd/scripts/bench.js +0 -127
  591. package/simsimd/scripts/bench.rs +0 -876
  592. package/simsimd/scripts/bench_vectors.py +0 -734
  593. package/simsimd/scripts/bench_vectors_live.py +0 -213
  594. package/simsimd/scripts/test.c +0 -187
  595. package/simsimd/scripts/test.mjs +0 -220
  596. package/simsimd/scripts/test.py +0 -1505
  597. package/simsimd/swift/SimSIMD.swift +0 -149
  598. package/simsimd/swift/Test.swift +0 -128
  599. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  600. /package/{simsimd → numkong}/LICENSE +0 -0
  601. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  602. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,667 @@
1
+ /**
2
+ * @brief SIMD-accelerated Trigonometric Functions for WASM.
3
+ * @file include/numkong/trigonometry/v128relaxed.h
4
+ * @author Ash Vardanian
5
+ * @date February 6, 2026
6
+ *
7
+ * @sa include/numkong/trigonometry.h
8
+ * @see https://sleef.org
9
+ *
10
+ * Implements sin, cos, atan, atan2 for f32x4 and f64x2 using minimax polynomial approximations.
11
+ * F32 sin/cos use 3-term polynomials with Cody-Waite range reduction; f64 uses 8-term Estrin.
12
+ * F32 atan uses an 8-term Horner scheme; f64 atan uses 19 terms. Atan2 adds quadrant correction.
13
+ *
14
+ * Polynomial chains rely on relaxed FMA (`relaxed_madd`/`relaxed_nmadd`) for throughput.
15
+ * Range reduction uses `nearest` rounding (avoiding int-float roundtrips); `trunc_sat` only
16
+ * for integer parity checks. F32 atan uses division for reciprocal (no approximate reciprocal
17
+ * available in WASM). All type punning is free since `v128_t` is untyped.
18
+ *
19
+ * @section wasm_trig_instructions Key WASM SIMD Instructions
20
+ *
21
+ * Intrinsic Operation
22
+ * wasm_f32x4_relaxed_madd(a, b, c) a*b + c (relaxed FMA)
23
+ * wasm_f32x4_relaxed_nmadd(a, b, c) -(a*b) + c (relaxed FNMA)
24
+ * wasm_f64x2_relaxed_madd(a, b, c) a*b + c (relaxed FMA)
25
+ * wasm_f64x2_relaxed_nmadd(a, b, c) -(a*b) + c (relaxed FNMA)
26
+ * wasm_f32x4_nearest(a) Round to nearest integer
27
+ * wasm_f64x2_nearest(a) Round to nearest integer
28
+ * wasm_v128_bitselect(true, false, mask) Bitwise select
29
+ * wasm_i32x4_relaxed_laneselect(a, b, m) Lane select (1 instr vs 3 on x86)
30
+ * wasm_i64x2_relaxed_laneselect(a, b, m) Lane select for f64 masks
31
+ * wasm_i32x4_relaxed_trunc_f32x4(a) Truncate without sat fixup (1 vs 7 on x86)
32
+ * wasm_i32x4_relaxed_trunc_f64x2_zero(a) Truncate f64→i32 without sat fixup (1 vs 7 on x86)
33
+ */
34
+ #ifndef NK_TRIGONOMETRY_V128RELAXED_H
35
+ #define NK_TRIGONOMETRY_V128RELAXED_H
36
+
37
+ #if NK_TARGET_V128RELAXED
38
+
39
+ #include "numkong/types.h"
40
+
41
+ #if defined(__cplusplus)
42
+ extern "C" {
43
+ #endif
44
+
45
+ #if defined(__clang__)
46
+ #pragma clang attribute push(__attribute__((target("relaxed-simd"))), apply_to = function)
47
+ #endif
48
+
49
+ /* WASM Relaxed SIMD trigonometry kernels (4-way f32, 2-way f64)
50
+ * These implement polynomial approximations using 128-bit WASM SIMD vectors.
51
+ */
52
+
53
+ NK_INTERNAL v128_t nk_f32x4_sin_v128relaxed_(v128_t const angles_radians) {
54
+ // Constants for argument reduction
55
+ v128_t const pi_f32x4 = wasm_f32x4_splat(3.14159265358979323846f);
56
+ v128_t const pi_reciprocal_f32x4 = wasm_f32x4_splat(0.31830988618379067154f);
57
+ v128_t const coeff_5_f32x4 = wasm_f32x4_splat(-0.0001881748176f);
58
+ v128_t const coeff_3_f32x4 = wasm_f32x4_splat(+0.008323502727f);
59
+ v128_t const coeff_1_f32x4 = wasm_f32x4_splat(-0.1666651368f);
60
+
61
+ // Compute (multiples_of_pi_f32x4) = round(angle / pi_f32x4) using nearest rounding
62
+ v128_t quotients_f32x4 = wasm_f32x4_mul(angles_radians, pi_reciprocal_f32x4);
63
+ v128_t rounded_quotients_f32x4 = wasm_f32x4_nearest(quotients_f32x4);
64
+ // relaxed_trunc: 1 instruction (cvttps2dq) vs 7 (with NaN/overflow fixup) on x86.
65
+ // Safe because rounded_quotients_f32x4 are small integers from nearest(), never NaN or out of i32 range.
66
+ v128_t multiples_of_pi_f32x4 = wasm_i32x4_relaxed_trunc_f32x4(rounded_quotients_f32x4);
67
+
68
+ // Reduce the angle: angle - rounded_quotients_f32x4 * pi_f32x4
69
+ // vfmsq_f32(acc, a, b) = acc - a*b -> wasm_f32x4_relaxed_nmadd(a, b, acc)
70
+ v128_t const angles_f32x4 = wasm_f32x4_relaxed_nmadd(rounded_quotients_f32x4, pi_f32x4, angles_radians);
71
+ v128_t const angles_squared_f32x4 = wasm_f32x4_mul(angles_f32x4, angles_f32x4);
72
+ v128_t const angles_cubed_f32x4 = wasm_f32x4_mul(angles_f32x4, angles_squared_f32x4);
73
+
74
+ // Compute the polynomial approximation
75
+ // vfmaq_f32(acc, a, b) = acc + a*b -> wasm_f32x4_relaxed_madd(a, b, acc)
76
+ v128_t polynomials_f32x4 = coeff_5_f32x4;
77
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, angles_squared_f32x4, coeff_3_f32x4);
78
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, angles_squared_f32x4, coeff_1_f32x4);
79
+ v128_t results_f32x4 = wasm_f32x4_relaxed_madd(angles_cubed_f32x4, polynomials_f32x4, angles_f32x4);
80
+
81
+ // If multiples_of_pi_f32x4 is odd, flip the sign
82
+ v128_t parity_i32x4 = wasm_v128_and(multiples_of_pi_f32x4, wasm_i32x4_splat(1));
83
+ v128_t odd_mask_i32x4 = wasm_i32x4_eq(parity_i32x4, wasm_i32x4_splat(1));
84
+ v128_t negated_f32x4 = wasm_f32x4_neg(results_f32x4);
85
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
86
+ // Safe because mask is from comparison (all-ones or all-zeros per lane).
87
+ results_f32x4 = wasm_i32x4_relaxed_laneselect(negated_f32x4, results_f32x4, odd_mask_i32x4);
88
+ return results_f32x4;
89
+ }
90
+
91
+ NK_INTERNAL v128_t nk_f32x4_cos_v128relaxed_(v128_t const angles_radians) {
92
+ // Constants for argument reduction
93
+ v128_t const pi_f32x4 = wasm_f32x4_splat(3.14159265358979323846f);
94
+ v128_t const pi_half_f32x4 = wasm_f32x4_splat(1.57079632679489661923f);
95
+ v128_t const pi_reciprocal_f32x4 = wasm_f32x4_splat(0.31830988618379067154f);
96
+ v128_t const coeff_5_f32x4 = wasm_f32x4_splat(-0.0001881748176f);
97
+ v128_t const coeff_3_f32x4 = wasm_f32x4_splat(+0.008323502727f);
98
+ v128_t const coeff_1_f32x4 = wasm_f32x4_splat(-0.1666651368f);
99
+
100
+ // Compute round((angle / pi_f32x4) - 0.5)
101
+ v128_t const neg_half_f32x4 = wasm_f32x4_splat(-0.5f);
102
+ v128_t quotients_f32x4 = wasm_f32x4_relaxed_madd(angles_radians, pi_reciprocal_f32x4, neg_half_f32x4);
103
+ v128_t rounded_quotients_f32x4 = wasm_f32x4_nearest(quotients_f32x4);
104
+ // relaxed_trunc: 1 instruction (cvttps2dq) vs 7 (with NaN/overflow fixup) on x86.
105
+ // Safe because rounded_quotients_f32x4 are small integers from nearest(), never NaN or out of i32 range.
106
+ v128_t multiples_of_pi_f32x4 = wasm_i32x4_relaxed_trunc_f32x4(rounded_quotients_f32x4);
107
+
108
+ // Reduce the angle: (angle - pi_f32x4/2) - rounded_quotients_f32x4 * pi_f32x4
109
+ v128_t shifted_f32x4 = wasm_f32x4_sub(angles_radians, pi_half_f32x4);
110
+ v128_t const angles_f32x4 = wasm_f32x4_relaxed_nmadd(rounded_quotients_f32x4, pi_f32x4, shifted_f32x4);
111
+ v128_t const angles_squared_f32x4 = wasm_f32x4_mul(angles_f32x4, angles_f32x4);
112
+ v128_t const angles_cubed_f32x4 = wasm_f32x4_mul(angles_f32x4, angles_squared_f32x4);
113
+
114
+ // Compute the polynomial approximation
115
+ v128_t polynomials_f32x4 = coeff_5_f32x4;
116
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, angles_squared_f32x4, coeff_3_f32x4);
117
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, angles_squared_f32x4, coeff_1_f32x4);
118
+ v128_t results_f32x4 = wasm_f32x4_relaxed_madd(angles_cubed_f32x4, polynomials_f32x4, angles_f32x4);
119
+
120
+ // If multiples_of_pi_f32x4 is even, flip the sign
121
+ v128_t parity_i32x4 = wasm_v128_and(multiples_of_pi_f32x4, wasm_i32x4_splat(1));
122
+ v128_t even_mask_i32x4 = wasm_i32x4_eq(parity_i32x4, wasm_i32x4_splat(0));
123
+ v128_t negated_f32x4 = wasm_f32x4_neg(results_f32x4);
124
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
125
+ // Safe because mask is from comparison (all-ones or all-zeros per lane).
126
+ results_f32x4 = wasm_i32x4_relaxed_laneselect(negated_f32x4, results_f32x4, even_mask_i32x4);
127
+ return results_f32x4;
128
+ }
129
+
130
+ NK_INTERNAL v128_t nk_f32x4_atan_v128relaxed_(v128_t const inputs) {
131
+ // Polynomial coefficients for atan approximation (8 terms)
132
+ v128_t const coeff_8_f32x4 = wasm_f32x4_splat(-0.333331018686294555664062f);
133
+ v128_t const coeff_7_f32x4 = wasm_f32x4_splat(+0.199926957488059997558594f);
134
+ v128_t const coeff_6_f32x4 = wasm_f32x4_splat(-0.142027363181114196777344f);
135
+ v128_t const coeff_5_f32x4 = wasm_f32x4_splat(+0.106347933411598205566406f);
136
+ v128_t const coeff_4_f32x4 = wasm_f32x4_splat(-0.0748900920152664184570312f);
137
+ v128_t const coeff_3_f32x4 = wasm_f32x4_splat(+0.0425049886107444763183594f);
138
+ v128_t const coeff_2_f32x4 = wasm_f32x4_splat(-0.0159569028764963150024414f);
139
+ v128_t const coeff_1_f32x4 = wasm_f32x4_splat(+0.00282363896258175373077393f);
140
+ v128_t const half_pi_f32x4 = wasm_f32x4_splat(1.5707963267948966f);
141
+
142
+ // Detect negative values_f32x4 and take absolute value
143
+ v128_t const zeros_f32x4 = wasm_f32x4_splat(0);
144
+ v128_t negative_mask_f32x4 = wasm_f32x4_lt(inputs, zeros_f32x4);
145
+ v128_t values_f32x4 = wasm_f32x4_abs(inputs);
146
+
147
+ // Check if values_f32x4 > 1 (need reciprocal)
148
+ v128_t reciprocal_mask_f32x4 = wasm_f32x4_gt(values_f32x4, wasm_f32x4_splat(1.0f));
149
+
150
+ // No fast reciprocal in WASM — use division
151
+ v128_t recip_f32x4 = wasm_f32x4_div(wasm_f32x4_splat(1.0f), values_f32x4);
152
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
153
+ // Safe because mask is from comparison (all-ones or all-zeros_f32x4 per lane).
154
+ values_f32x4 = wasm_i32x4_relaxed_laneselect(recip_f32x4, values_f32x4, reciprocal_mask_f32x4);
155
+
156
+ // Compute powers
157
+ v128_t const values_squared_f32x4 = wasm_f32x4_mul(values_f32x4, values_f32x4);
158
+ v128_t const values_cubed_f32x4 = wasm_f32x4_mul(values_f32x4, values_squared_f32x4);
159
+
160
+ // Polynomial evaluation using Horner's method
161
+ v128_t polynomials_f32x4 = coeff_1_f32x4;
162
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_2_f32x4);
163
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_3_f32x4);
164
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_4_f32x4);
165
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_5_f32x4);
166
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_6_f32x4);
167
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_7_f32x4);
168
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, values_squared_f32x4, coeff_8_f32x4);
169
+
170
+ // Compute result_f32x4: atan(x) ~ x + x^3 * P(x^2)
171
+ v128_t result_f32x4 = wasm_f32x4_relaxed_madd(values_cubed_f32x4, polynomials_f32x4, values_f32x4);
172
+
173
+ // Adjust for reciprocal: result_f32x4 = pi/2 - result_f32x4
174
+ v128_t adjusted_f32x4 = wasm_f32x4_sub(half_pi_f32x4, result_f32x4);
175
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
176
+ // Safe because mask is from comparison (all-ones or all-zeros_f32x4 per lane).
177
+ result_f32x4 = wasm_i32x4_relaxed_laneselect(adjusted_f32x4, result_f32x4, reciprocal_mask_f32x4);
178
+
179
+ // Adjust for negative: result_f32x4 = -result_f32x4
180
+ v128_t negated_f32x4 = wasm_f32x4_neg(result_f32x4);
181
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
182
+ // Safe because mask is from comparison (all-ones or all-zeros_f32x4 per lane).
183
+ result_f32x4 = wasm_i32x4_relaxed_laneselect(negated_f32x4, result_f32x4, negative_mask_f32x4);
184
+ return result_f32x4;
185
+ }
186
+
187
+ NK_INTERNAL v128_t nk_f32x4_atan2_v128relaxed_(v128_t const ys_inputs, v128_t const xs_inputs) {
188
+ // Polynomial coefficients (same as atan)
189
+ v128_t const coeff_8_f32x4 = wasm_f32x4_splat(-0.333331018686294555664062f);
190
+ v128_t const coeff_7_f32x4 = wasm_f32x4_splat(+0.199926957488059997558594f);
191
+ v128_t const coeff_6_f32x4 = wasm_f32x4_splat(-0.142027363181114196777344f);
192
+ v128_t const coeff_5_f32x4 = wasm_f32x4_splat(+0.106347933411598205566406f);
193
+ v128_t const coeff_4_f32x4 = wasm_f32x4_splat(-0.0748900920152664184570312f);
194
+ v128_t const coeff_3_f32x4 = wasm_f32x4_splat(+0.0425049886107444763183594f);
195
+ v128_t const coeff_2_f32x4 = wasm_f32x4_splat(-0.0159569028764963150024414f);
196
+ v128_t const coeff_1_f32x4 = wasm_f32x4_splat(+0.00282363896258175373077393f);
197
+ v128_t const pi_f32x4 = wasm_f32x4_splat(3.14159265358979323846f);
198
+ v128_t const half_pi_f32x4 = wasm_f32x4_splat(1.5707963267948966f);
199
+ v128_t const zeros_f32x4 = wasm_f32x4_splat(0);
200
+
201
+ // Quadrant adjustments - take absolute values
202
+ v128_t xs_negative_mask_f32x4 = wasm_f32x4_lt(xs_inputs, zeros_f32x4);
203
+ v128_t xs_f32x4 = wasm_f32x4_abs(xs_inputs);
204
+ v128_t ys_f32x4 = wasm_f32x4_abs(ys_inputs);
205
+
206
+ // Ensure proper fraction where numerator < denominator
207
+ v128_t swap_mask_f32x4 = wasm_f32x4_gt(ys_f32x4, xs_f32x4);
208
+ v128_t temps_f32x4 = xs_f32x4;
209
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
210
+ // Safe because mask is from comparison (all-ones or all-zeros_f32x4 per lane).
211
+ xs_f32x4 = wasm_i32x4_relaxed_laneselect(ys_f32x4, xs_f32x4, swap_mask_f32x4);
212
+ ys_f32x4 = wasm_i32x4_relaxed_laneselect(wasm_f32x4_neg(temps_f32x4), ys_f32x4, swap_mask_f32x4);
213
+
214
+ // Division for ratio_f32x4: ratio_f32x4 = ys_f32x4 / xs_f32x4
215
+ v128_t const ratio_f32x4 = wasm_f32x4_div(ys_f32x4, xs_f32x4);
216
+ v128_t const ratio_squared_f32x4 = wasm_f32x4_mul(ratio_f32x4, ratio_f32x4);
217
+ v128_t const ratio_cubed_f32x4 = wasm_f32x4_mul(ratio_f32x4, ratio_squared_f32x4);
218
+
219
+ // Polynomial evaluation using Horner's method
220
+ v128_t polynomials_f32x4 = coeff_1_f32x4;
221
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_2_f32x4);
222
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_3_f32x4);
223
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_4_f32x4);
224
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_5_f32x4);
225
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_6_f32x4);
226
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_7_f32x4);
227
+ polynomials_f32x4 = wasm_f32x4_relaxed_madd(polynomials_f32x4, ratio_squared_f32x4, coeff_8_f32x4);
228
+
229
+ // Compute the result
230
+ v128_t results_f32x4 = wasm_f32x4_relaxed_madd(ratio_cubed_f32x4, polynomials_f32x4, ratio_f32x4);
231
+
232
+ // Compute quadrant_f32x4 value: 0 for x>=0 && !swap, 1 for x>=0 && swap,
233
+ // -2 for x<0 && !swap, -1 for x<0 && swap
234
+ v128_t quadrant_f32x4 = wasm_f32x4_splat(0.0f);
235
+ v128_t neg_two_f32x4 = wasm_f32x4_splat(-2.0f);
236
+ // relaxed_laneselect: 1 instruction (vblendvps) vs 3 (vpand+vpandn+vpor) on x86.
237
+ // Safe because mask is from comparison (all-ones or all-zeros_f32x4 per lane).
238
+ quadrant_f32x4 = wasm_i32x4_relaxed_laneselect(neg_two_f32x4, quadrant_f32x4, xs_negative_mask_f32x4);
239
+ v128_t quadrant_incremented_f32x4 = wasm_f32x4_add(quadrant_f32x4, wasm_f32x4_splat(1.0f));
240
+ quadrant_f32x4 = wasm_i32x4_relaxed_laneselect(quadrant_incremented_f32x4, quadrant_f32x4, swap_mask_f32x4);
241
+
242
+ // Adjust for quadrant_f32x4: result += quadrant_f32x4 * pi_f32x4/2
243
+ results_f32x4 = wasm_f32x4_relaxed_madd(quadrant_f32x4, half_pi_f32x4, results_f32x4);
244
+
245
+ // Transfer sign from x and y by XOR with sign bits
246
+ v128_t sign_mask_f32x4 = wasm_f32x4_splat(-0.0f);
247
+ v128_t xs_sign_f32x4 = wasm_v128_and(xs_inputs, sign_mask_f32x4);
248
+ v128_t ys_sign_f32x4 = wasm_v128_and(ys_inputs, sign_mask_f32x4);
249
+ results_f32x4 = wasm_v128_xor(results_f32x4, xs_sign_f32x4);
250
+ results_f32x4 = wasm_v128_xor(results_f32x4, ys_sign_f32x4);
251
+
252
+ return results_f32x4;
253
+ }
254
+
255
+ NK_INTERNAL v128_t nk_f64x2_sin_v128relaxed_(v128_t const angles_radians) {
256
+ // Constants for argument reduction
257
+ v128_t const pi_high_f64x2 = wasm_f64x2_splat(3.141592653589793116);
258
+ v128_t const pi_low_f64x2 = wasm_f64x2_splat(1.2246467991473532072e-16);
259
+ v128_t const pi_reciprocal_f64x2 = wasm_f64x2_splat(0.31830988618379067154);
260
+
261
+ // Polynomial coefficients for sine approximation
262
+ v128_t const coeff_0_f64x2 = wasm_f64x2_splat(+0.00833333333333332974823815);
263
+ v128_t const coeff_1_f64x2 = wasm_f64x2_splat(-0.000198412698412696162806809);
264
+ v128_t const coeff_2_f64x2 = wasm_f64x2_splat(+2.75573192239198747630416e-06);
265
+ v128_t const coeff_3_f64x2 = wasm_f64x2_splat(-2.50521083763502045810755e-08);
266
+ v128_t const coeff_4_f64x2 = wasm_f64x2_splat(+1.60590430605664501629054e-10);
267
+ v128_t const coeff_5_f64x2 = wasm_f64x2_splat(-7.64712219118158833288484e-13);
268
+ v128_t const coeff_6_f64x2 = wasm_f64x2_splat(+2.81009972710863200091251e-15);
269
+ v128_t const coeff_7_f64x2 = wasm_f64x2_splat(-7.97255955009037868891952e-18);
270
+ v128_t const coeff_8_f64x2 = wasm_f64x2_splat(-0.166666666666666657414808);
271
+
272
+ // Compute round(angle / pi)
273
+ v128_t const quotients_f64x2 = wasm_f64x2_mul(angles_radians, pi_reciprocal_f64x2);
274
+ v128_t rounded_quotients_f64x2 = wasm_f64x2_nearest(quotients_f64x2);
275
+ // relaxed_trunc: 1 instruction (cvttpd2dq) vs 7 (with NaN/overflow fixup) on x86.
276
+ // Safe because rounded_quotients_f64x2 are small integers from nearest(), never NaN or out of i32 range.
277
+ v128_t multiples_i32_f64x2 = wasm_i32x4_relaxed_trunc_f64x2_zero(rounded_quotients_f64x2);
278
+
279
+ // Two-step Cody-Waite reduction: angle - rounded * pi_high_f64x2 - rounded * pi_low_f64x2
280
+ v128_t angles_f64x2 = angles_radians;
281
+ angles_f64x2 = wasm_f64x2_relaxed_nmadd(rounded_quotients_f64x2, pi_high_f64x2, angles_f64x2);
282
+ angles_f64x2 = wasm_f64x2_relaxed_nmadd(rounded_quotients_f64x2, pi_low_f64x2, angles_f64x2);
283
+
284
+ // Check parity in i32, then widen to i64 mask for laneselect
285
+ v128_t parity_i32_i32x4 = wasm_v128_and(multiples_i32_f64x2, wasm_i32x4_splat(1));
286
+ v128_t odd_i32_i32x4 = wasm_i32x4_eq(parity_i32_i32x4, wasm_i32x4_splat(1));
287
+ // Widen: lane0 of i32 -> lanes 0-1 of i64, lane1 -> lanes 2-3
288
+ // Shuffle i32 lanes [0,0,1,1] to broadcast each i32 parity into both halves of each i64
289
+ v128_t odd_mask_i32x4 = wasm_i32x4_shuffle(odd_i32_i32x4, odd_i32_i32x4, 0, 0, 1, 1);
290
+ v128_t negated_angles_f64x2 = wasm_f64x2_neg(angles_f64x2);
291
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
292
+ // Safe because mask is lane-granular at i64 width (all-ones or all-zeros per 64-bit lane).
293
+ angles_f64x2 = wasm_i64x2_relaxed_laneselect(negated_angles_f64x2, angles_f64x2, odd_mask_i32x4);
294
+
295
+ v128_t const angles_squared_f64x2 = wasm_f64x2_mul(angles_f64x2, angles_f64x2);
296
+ v128_t const angles_cubed_f64x2 = wasm_f64x2_mul(angles_f64x2, angles_squared_f64x2);
297
+ v128_t const angles_quadratic_f64x2 = wasm_f64x2_mul(angles_squared_f64x2, angles_squared_f64x2);
298
+ v128_t const angles_octic_f64x2 = wasm_f64x2_mul(angles_quadratic_f64x2, angles_quadratic_f64x2);
299
+
300
+ // Compute polynomial terms using Estrin's scheme for better ILP
301
+ v128_t const poly_67_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_7_f64x2, coeff_6_f64x2);
302
+ v128_t const poly_45_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_5_f64x2, coeff_4_f64x2);
303
+ v128_t const poly_4567_f64x2 = wasm_f64x2_relaxed_madd(angles_quadratic_f64x2, poly_67_f64x2, poly_45_f64x2);
304
+
305
+ v128_t const poly_23_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_3_f64x2, coeff_2_f64x2);
306
+ v128_t const poly_01_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_1_f64x2, coeff_0_f64x2);
307
+ v128_t const poly_0123_f64x2 = wasm_f64x2_relaxed_madd(angles_quadratic_f64x2, poly_23_f64x2, poly_01_f64x2);
308
+
309
+ // Combine polynomial terms
310
+ v128_t results_f64x2 = wasm_f64x2_relaxed_madd(angles_octic_f64x2, poly_4567_f64x2, poly_0123_f64x2);
311
+ results_f64x2 = wasm_f64x2_relaxed_madd(results_f64x2, angles_squared_f64x2, coeff_8_f64x2);
312
+ results_f64x2 = wasm_f64x2_relaxed_madd(results_f64x2, angles_cubed_f64x2, angles_f64x2);
313
+
314
+ // Handle zero input (preserve sign of zero)
315
+ v128_t const non_zero_mask_f64x2 = wasm_f64x2_eq(angles_radians, wasm_f64x2_splat(0));
316
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
317
+ // Safe because mask is from comparison (all-ones or all-zeros per lane).
318
+ results_f64x2 = wasm_i64x2_relaxed_laneselect(angles_radians, results_f64x2, non_zero_mask_f64x2);
319
+ return results_f64x2;
320
+ }
321
+
322
+ NK_INTERNAL v128_t nk_f64x2_cos_v128relaxed_(v128_t const angles_radians) {
323
+ // Constants for argument reduction
324
+ v128_t const pi_high_half_f64x2 = wasm_f64x2_splat(3.141592653589793116 * 0.5);
325
+ v128_t const pi_low_half_f64x2 = wasm_f64x2_splat(1.2246467991473532072e-16 * 0.5);
326
+ v128_t const pi_reciprocal_f64x2 = wasm_f64x2_splat(0.31830988618379067154);
327
+
328
+ // Polynomial coefficients for cosine approximation
329
+ v128_t const coeff_0_f64x2 = wasm_f64x2_splat(+0.00833333333333332974823815);
330
+ v128_t const coeff_1_f64x2 = wasm_f64x2_splat(-0.000198412698412696162806809);
331
+ v128_t const coeff_2_f64x2 = wasm_f64x2_splat(+2.75573192239198747630416e-06);
332
+ v128_t const coeff_3_f64x2 = wasm_f64x2_splat(-2.50521083763502045810755e-08);
333
+ v128_t const coeff_4_f64x2 = wasm_f64x2_splat(+1.60590430605664501629054e-10);
334
+ v128_t const coeff_5_f64x2 = wasm_f64x2_splat(-7.64712219118158833288484e-13);
335
+ v128_t const coeff_6_f64x2 = wasm_f64x2_splat(+2.81009972710863200091251e-15);
336
+ v128_t const coeff_7_f64x2 = wasm_f64x2_splat(-7.97255955009037868891952e-18);
337
+ v128_t const coeff_8_f64x2 = wasm_f64x2_splat(-0.166666666666666657414808);
338
+
339
+ // Compute 2 * round(angle / pi - 0.5) + 1
340
+ v128_t const neg_half_f64x2 = wasm_f64x2_splat(-0.5);
341
+ v128_t const quotients_f64x2 = wasm_f64x2_relaxed_madd(angles_radians, pi_reciprocal_f64x2, neg_half_f64x2);
342
+ v128_t const rounded_f64x2 = wasm_f64x2_nearest(quotients_f64x2);
343
+ v128_t const rounded_quotients_f64x2 = wasm_f64x2_relaxed_madd(wasm_f64x2_splat(2.0), rounded_f64x2,
344
+ wasm_f64x2_splat(1.0));
345
+ // relaxed_trunc: 1 instruction (cvttpd2dq) vs 7 (with NaN/overflow fixup) on x86.
346
+ // Safe because rounded_quotients_f64x2 are small integers from nearest(), never NaN or out of i32 range.
347
+ v128_t quotients_i32_f64x2 = wasm_i32x4_relaxed_trunc_f64x2_zero(rounded_quotients_f64x2);
348
+
349
+ // Two-step Cody-Waite reduction
350
+ v128_t angles_f64x2 = angles_radians;
351
+ angles_f64x2 = wasm_f64x2_relaxed_nmadd(rounded_quotients_f64x2, pi_high_half_f64x2, angles_f64x2);
352
+ angles_f64x2 = wasm_f64x2_relaxed_nmadd(rounded_quotients_f64x2, pi_low_half_f64x2, angles_f64x2);
353
+
354
+ // Check bit 1 in i32, then widen to i64 mask for laneselect
355
+ v128_t bit2_i32_i32x4 = wasm_v128_and(quotients_i32_f64x2, wasm_i32x4_splat(2));
356
+ v128_t flip_i32_i32x4 = wasm_i32x4_eq(bit2_i32_i32x4, wasm_i32x4_splat(0));
357
+ v128_t flip_mask_i32x4 = wasm_i32x4_shuffle(flip_i32_i32x4, flip_i32_i32x4, 0, 0, 1, 1);
358
+ v128_t negated_angles_f64x2 = wasm_f64x2_neg(angles_f64x2);
359
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
360
+ // Safe because mask is lane-granular at i64 width (all-ones or all-zeros per 64-bit lane).
361
+ angles_f64x2 = wasm_i64x2_relaxed_laneselect(negated_angles_f64x2, angles_f64x2, flip_mask_i32x4);
362
+
363
+ v128_t const angles_squared_f64x2 = wasm_f64x2_mul(angles_f64x2, angles_f64x2);
364
+ v128_t const angles_cubed_f64x2 = wasm_f64x2_mul(angles_f64x2, angles_squared_f64x2);
365
+ v128_t const angles_quadratic_f64x2 = wasm_f64x2_mul(angles_squared_f64x2, angles_squared_f64x2);
366
+ v128_t const angles_octic_f64x2 = wasm_f64x2_mul(angles_quadratic_f64x2, angles_quadratic_f64x2);
367
+
368
+ // Compute polynomial terms using Estrin's scheme
369
+ v128_t const poly_67_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_7_f64x2, coeff_6_f64x2);
370
+ v128_t const poly_45_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_5_f64x2, coeff_4_f64x2);
371
+ v128_t const poly_4567_f64x2 = wasm_f64x2_relaxed_madd(angles_quadratic_f64x2, poly_67_f64x2, poly_45_f64x2);
372
+
373
+ v128_t const poly_23_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_3_f64x2, coeff_2_f64x2);
374
+ v128_t const poly_01_f64x2 = wasm_f64x2_relaxed_madd(angles_squared_f64x2, coeff_1_f64x2, coeff_0_f64x2);
375
+ v128_t const poly_0123_f64x2 = wasm_f64x2_relaxed_madd(angles_quadratic_f64x2, poly_23_f64x2, poly_01_f64x2);
376
+
377
+ // Combine polynomial terms
378
+ v128_t results_f64x2 = wasm_f64x2_relaxed_madd(angles_octic_f64x2, poly_4567_f64x2, poly_0123_f64x2);
379
+ results_f64x2 = wasm_f64x2_relaxed_madd(results_f64x2, angles_squared_f64x2, coeff_8_f64x2);
380
+ results_f64x2 = wasm_f64x2_relaxed_madd(results_f64x2, angles_cubed_f64x2, angles_f64x2);
381
+ return results_f64x2;
382
+ }
383
+
384
+ NK_INTERNAL v128_t nk_f64x2_atan_v128relaxed_(v128_t const inputs) {
385
+ // Polynomial coefficients for atan approximation (19 terms)
386
+ v128_t const coeff_19_f64x2 = wasm_f64x2_splat(-1.88796008463073496563746e-05);
387
+ v128_t const coeff_18_f64x2 = wasm_f64x2_splat(+0.000209850076645816976906797);
388
+ v128_t const coeff_17_f64x2 = wasm_f64x2_splat(-0.00110611831486672482563471);
389
+ v128_t const coeff_16_f64x2 = wasm_f64x2_splat(+0.00370026744188713119232403);
390
+ v128_t const coeff_15_f64x2 = wasm_f64x2_splat(-0.00889896195887655491740809);
391
+ v128_t const coeff_14_f64x2 = wasm_f64x2_splat(+0.016599329773529201970117);
392
+ v128_t const coeff_13_f64x2 = wasm_f64x2_splat(-0.0254517624932312641616861);
393
+ v128_t const coeff_12_f64x2 = wasm_f64x2_splat(+0.0337852580001353069993897);
394
+ v128_t const coeff_11_f64x2 = wasm_f64x2_splat(-0.0407629191276836500001934);
395
+ v128_t const coeff_10_f64x2 = wasm_f64x2_splat(+0.0466667150077840625632675);
396
+ v128_t const coeff_9_f64x2 = wasm_f64x2_splat(-0.0523674852303482457616113);
397
+ v128_t const coeff_8_f64x2 = wasm_f64x2_splat(+0.0587666392926673580854313);
398
+ v128_t const coeff_7_f64x2 = wasm_f64x2_splat(-0.0666573579361080525984562);
399
+ v128_t const coeff_6_f64x2 = wasm_f64x2_splat(+0.0769219538311769618355029);
400
+ v128_t const coeff_5_f64x2 = wasm_f64x2_splat(-0.090908995008245008229153);
401
+ v128_t const coeff_4_f64x2 = wasm_f64x2_splat(+0.111111105648261418443745);
402
+ v128_t const coeff_3_f64x2 = wasm_f64x2_splat(-0.14285714266771329383765);
403
+ v128_t const coeff_2_f64x2 = wasm_f64x2_splat(+0.199999999996591265594148);
404
+ v128_t const coeff_1_f64x2 = wasm_f64x2_splat(-0.333333333333311110369124);
405
+ v128_t const half_pi_f64x2 = wasm_f64x2_splat(1.5707963267948966);
406
+ v128_t const zeros_f64x2 = wasm_f64x2_splat(0);
407
+
408
+ // Detect negative and take absolute value
409
+ v128_t negative_mask_f64x2 = wasm_f64x2_lt(inputs, zeros_f64x2);
410
+ v128_t values_f64x2 = wasm_f64x2_abs(inputs);
411
+
412
+ // Check if values_f64x2 > 1 (need reciprocal) - use division for f64 precision
413
+ v128_t reciprocal_mask_f64x2 = wasm_f64x2_gt(values_f64x2, wasm_f64x2_splat(1.0));
414
+ v128_t reciprocal_values_f64x2 = wasm_f64x2_div(wasm_f64x2_splat(1.0), values_f64x2);
415
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
416
+ // Safe because mask is from comparison (all-ones or all-zeros_f64x2 per lane).
417
+ values_f64x2 = wasm_i64x2_relaxed_laneselect(reciprocal_values_f64x2, values_f64x2, reciprocal_mask_f64x2);
418
+
419
+ // Compute powers
420
+ v128_t const values_squared_f64x2 = wasm_f64x2_mul(values_f64x2, values_f64x2);
421
+ v128_t const values_cubed_f64x2 = wasm_f64x2_mul(values_f64x2, values_squared_f64x2);
422
+
423
+ // Polynomial evaluation using Horner's method
424
+ v128_t polynomials_f64x2 = coeff_19_f64x2;
425
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_18_f64x2);
426
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_17_f64x2);
427
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_16_f64x2);
428
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_15_f64x2);
429
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_14_f64x2);
430
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_13_f64x2);
431
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_12_f64x2);
432
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_11_f64x2);
433
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_10_f64x2);
434
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_9_f64x2);
435
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_8_f64x2);
436
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_7_f64x2);
437
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_6_f64x2);
438
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_5_f64x2);
439
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_4_f64x2);
440
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_3_f64x2);
441
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_2_f64x2);
442
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, values_squared_f64x2, coeff_1_f64x2);
443
+
444
+ // Compute result_f64x2
445
+ v128_t result_f64x2 = wasm_f64x2_relaxed_madd(values_cubed_f64x2, polynomials_f64x2, values_f64x2);
446
+
447
+ // Adjust for reciprocal: result_f64x2 = pi/2 - result_f64x2
448
+ v128_t adjusted_f64x2 = wasm_f64x2_sub(half_pi_f64x2, result_f64x2);
449
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
450
+ // Safe because mask is from comparison (all-ones or all-zeros_f64x2 per lane).
451
+ result_f64x2 = wasm_i64x2_relaxed_laneselect(adjusted_f64x2, result_f64x2, reciprocal_mask_f64x2);
452
+
453
+ // Adjust for negative: result_f64x2 = -result_f64x2
454
+ v128_t negated_f64x2 = wasm_f64x2_neg(result_f64x2);
455
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
456
+ // Safe because mask is from comparison (all-ones or all-zeros_f64x2 per lane).
457
+ result_f64x2 = wasm_i64x2_relaxed_laneselect(negated_f64x2, result_f64x2, negative_mask_f64x2);
458
+ return result_f64x2;
459
+ }
460
+
461
+ NK_INTERNAL v128_t nk_f64x2_atan2_v128relaxed_(v128_t const ys_inputs, v128_t const xs_inputs) {
462
+ // Polynomial coefficients (same as atan)
463
+ v128_t const coeff_19_f64x2 = wasm_f64x2_splat(-1.88796008463073496563746e-05);
464
+ v128_t const coeff_18_f64x2 = wasm_f64x2_splat(+0.000209850076645816976906797);
465
+ v128_t const coeff_17_f64x2 = wasm_f64x2_splat(-0.00110611831486672482563471);
466
+ v128_t const coeff_16_f64x2 = wasm_f64x2_splat(+0.00370026744188713119232403);
467
+ v128_t const coeff_15_f64x2 = wasm_f64x2_splat(-0.00889896195887655491740809);
468
+ v128_t const coeff_14_f64x2 = wasm_f64x2_splat(+0.016599329773529201970117);
469
+ v128_t const coeff_13_f64x2 = wasm_f64x2_splat(-0.0254517624932312641616861);
470
+ v128_t const coeff_12_f64x2 = wasm_f64x2_splat(+0.0337852580001353069993897);
471
+ v128_t const coeff_11_f64x2 = wasm_f64x2_splat(-0.0407629191276836500001934);
472
+ v128_t const coeff_10_f64x2 = wasm_f64x2_splat(+0.0466667150077840625632675);
473
+ v128_t const coeff_9_f64x2 = wasm_f64x2_splat(-0.0523674852303482457616113);
474
+ v128_t const coeff_8_f64x2 = wasm_f64x2_splat(+0.0587666392926673580854313);
475
+ v128_t const coeff_7_f64x2 = wasm_f64x2_splat(-0.0666573579361080525984562);
476
+ v128_t const coeff_6_f64x2 = wasm_f64x2_splat(+0.0769219538311769618355029);
477
+ v128_t const coeff_5_f64x2 = wasm_f64x2_splat(-0.090908995008245008229153);
478
+ v128_t const coeff_4_f64x2 = wasm_f64x2_splat(+0.111111105648261418443745);
479
+ v128_t const coeff_3_f64x2 = wasm_f64x2_splat(-0.14285714266771329383765);
480
+ v128_t const coeff_2_f64x2 = wasm_f64x2_splat(+0.199999999996591265594148);
481
+ v128_t const coeff_1_f64x2 = wasm_f64x2_splat(-0.333333333333311110369124);
482
+ v128_t const pi_f64x2 = wasm_f64x2_splat(3.14159265358979323846);
483
+ v128_t const half_pi_f64x2 = wasm_f64x2_splat(1.5707963267948966);
484
+ v128_t const zeros_f64x2 = wasm_f64x2_splat(0);
485
+
486
+ // Quadrant adjustments - take absolute values
487
+ v128_t xs_negative_mask_f64x2 = wasm_f64x2_lt(xs_inputs, zeros_f64x2);
488
+ v128_t xs_f64x2 = wasm_f64x2_abs(xs_inputs);
489
+ v128_t ys_f64x2 = wasm_f64x2_abs(ys_inputs);
490
+
491
+ // Ensure proper fraction where numerator < denominator
492
+ v128_t swap_mask_f64x2 = wasm_f64x2_gt(ys_f64x2, xs_f64x2);
493
+ v128_t temps_f64x2 = xs_f64x2;
494
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
495
+ // Safe because mask is from comparison (all-ones or all-zeros_f64x2 per lane).
496
+ xs_f64x2 = wasm_i64x2_relaxed_laneselect(ys_f64x2, xs_f64x2, swap_mask_f64x2);
497
+ ys_f64x2 = wasm_i64x2_relaxed_laneselect(wasm_f64x2_neg(temps_f64x2), ys_f64x2, swap_mask_f64x2);
498
+
499
+ // Division for f64 precision
500
+ v128_t const ratio_f64x2 = wasm_f64x2_div(ys_f64x2, xs_f64x2);
501
+ v128_t const ratio_squared_f64x2 = wasm_f64x2_mul(ratio_f64x2, ratio_f64x2);
502
+ v128_t const ratio_cubed_f64x2 = wasm_f64x2_mul(ratio_f64x2, ratio_squared_f64x2);
503
+
504
+ // Polynomial evaluation using Horner's method
505
+ v128_t polynomials_f64x2 = coeff_19_f64x2;
506
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_18_f64x2);
507
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_17_f64x2);
508
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_16_f64x2);
509
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_15_f64x2);
510
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_14_f64x2);
511
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_13_f64x2);
512
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_12_f64x2);
513
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_11_f64x2);
514
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_10_f64x2);
515
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_9_f64x2);
516
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_8_f64x2);
517
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_7_f64x2);
518
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_6_f64x2);
519
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_5_f64x2);
520
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_4_f64x2);
521
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_3_f64x2);
522
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_2_f64x2);
523
+ polynomials_f64x2 = wasm_f64x2_relaxed_madd(polynomials_f64x2, ratio_squared_f64x2, coeff_1_f64x2);
524
+
525
+ // Compute the result
526
+ v128_t results_f64x2 = wasm_f64x2_relaxed_madd(ratio_cubed_f64x2, polynomials_f64x2, ratio_f64x2);
527
+
528
+ // Compute quadrant_f64x2 value: 0 for x>=0 && !swap, 1 for x>=0 && swap,
529
+ // -2 for x<0 && !swap, -1 for x<0 && swap
530
+ v128_t quadrant_f64x2 = wasm_f64x2_splat(0.0);
531
+ v128_t neg_two_f64x2 = wasm_f64x2_splat(-2.0);
532
+ // relaxed_laneselect: 1 instruction (vblendvpd) vs 3 (vpand+vpandn+vpor) on x86.
533
+ // Safe because mask is from comparison (all-ones or all-zeros_f64x2 per lane).
534
+ quadrant_f64x2 = wasm_i64x2_relaxed_laneselect(neg_two_f64x2, quadrant_f64x2, xs_negative_mask_f64x2);
535
+ v128_t quadrant_incremented_f64x2 = wasm_f64x2_add(quadrant_f64x2, wasm_f64x2_splat(1.0));
536
+ quadrant_f64x2 = wasm_i64x2_relaxed_laneselect(quadrant_incremented_f64x2, quadrant_f64x2, swap_mask_f64x2);
537
+
538
+ // Adjust for quadrant_f64x2: result += quadrant_f64x2 * pi_f64x2/2
539
+ results_f64x2 = wasm_f64x2_relaxed_madd(quadrant_f64x2, half_pi_f64x2, results_f64x2);
540
+
541
+ // Transfer sign from x and y by XOR with sign bits
542
+ v128_t sign_mask_f64x2 = wasm_f64x2_splat(-0.0);
543
+ v128_t xs_sign_f64x2 = wasm_v128_and(xs_inputs, sign_mask_f64x2);
544
+ v128_t ys_sign_f64x2 = wasm_v128_and(ys_inputs, sign_mask_f64x2);
545
+ results_f64x2 = wasm_v128_xor(results_f64x2, xs_sign_f64x2);
546
+ results_f64x2 = wasm_v128_xor(results_f64x2, ys_sign_f64x2);
547
+
548
+ return results_f64x2;
549
+ }
550
+
551
+ /* NK_PUBLIC wrappers — same loop+tail pattern as neon.h.
552
+ * Full loads use wasm_v128_load/wasm_v128_store.
553
+ * Tails use nk_partial_load_b32x4_serial_/nk_partial_store_b32x4_serial_ via .v128 union member.
554
+ */
555
+
556
+ NK_PUBLIC void nk_each_sin_f32_v128relaxed(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
557
+ nk_size_t i = 0;
558
+ for (; i + 4 <= n; i += 4) {
559
+ v128_t angles_f32x4 = wasm_v128_load(ins + i);
560
+ v128_t results_f32x4 = nk_f32x4_sin_v128relaxed_(angles_f32x4);
561
+ wasm_v128_store(outs + i, results_f32x4);
562
+ }
563
+ if (i < n) {
564
+ nk_size_t remaining = n - i;
565
+ nk_b128_vec_t angles_vec;
566
+ nk_partial_load_b32x4_serial_(ins + i, &angles_vec, remaining);
567
+ nk_b128_vec_t results_vec;
568
+ results_vec.v128 = nk_f32x4_sin_v128relaxed_(angles_vec.v128);
569
+ nk_partial_store_b32x4_serial_(&results_vec, outs + i, remaining);
570
+ }
571
+ }
572
+
573
+ NK_PUBLIC void nk_each_cos_f32_v128relaxed(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
574
+ nk_size_t i = 0;
575
+ for (; i + 4 <= n; i += 4) {
576
+ v128_t angles_f32x4 = wasm_v128_load(ins + i);
577
+ v128_t results_f32x4 = nk_f32x4_cos_v128relaxed_(angles_f32x4);
578
+ wasm_v128_store(outs + i, results_f32x4);
579
+ }
580
+ if (i < n) {
581
+ nk_size_t remaining = n - i;
582
+ nk_b128_vec_t angles_vec;
583
+ nk_partial_load_b32x4_serial_(ins + i, &angles_vec, remaining);
584
+ nk_b128_vec_t results_vec;
585
+ results_vec.v128 = nk_f32x4_cos_v128relaxed_(angles_vec.v128);
586
+ nk_partial_store_b32x4_serial_(&results_vec, outs + i, remaining);
587
+ }
588
+ }
589
+
590
+ NK_PUBLIC void nk_each_atan_f32_v128relaxed(nk_f32_t const *ins, nk_size_t n, nk_f32_t *outs) {
591
+ nk_size_t i = 0;
592
+ for (; i + 4 <= n; i += 4) {
593
+ v128_t values_f32x4 = wasm_v128_load(ins + i);
594
+ v128_t results_f32x4 = nk_f32x4_atan_v128relaxed_(values_f32x4);
595
+ wasm_v128_store(outs + i, results_f32x4);
596
+ }
597
+ if (i < n) {
598
+ nk_size_t remaining = n - i;
599
+ nk_b128_vec_t values_vec;
600
+ nk_partial_load_b32x4_serial_(ins + i, &values_vec, remaining);
601
+ nk_b128_vec_t results_vec;
602
+ results_vec.v128 = nk_f32x4_atan_v128relaxed_(values_vec.v128);
603
+ nk_partial_store_b32x4_serial_(&results_vec, outs + i, remaining);
604
+ }
605
+ }
606
+
607
+ NK_PUBLIC void nk_each_sin_f64_v128relaxed(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
608
+ nk_size_t i = 0;
609
+ for (; i + 2 <= n; i += 2) {
610
+ v128_t angles_f64x2 = wasm_v128_load(ins + i);
611
+ v128_t results_f64x2 = nk_f64x2_sin_v128relaxed_(angles_f64x2);
612
+ wasm_v128_store(outs + i, results_f64x2);
613
+ }
614
+ if (i < n) {
615
+ nk_size_t remaining = n - i;
616
+ nk_b128_vec_t angles_vec;
617
+ nk_partial_load_b64x2_serial_(ins + i, &angles_vec, remaining);
618
+ nk_b128_vec_t results_vec;
619
+ results_vec.v128 = nk_f64x2_sin_v128relaxed_(angles_vec.v128);
620
+ nk_partial_store_b64x2_serial_(&results_vec, outs + i, remaining);
621
+ }
622
+ }
623
+
624
+ NK_PUBLIC void nk_each_cos_f64_v128relaxed(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
625
+ nk_size_t i = 0;
626
+ for (; i + 2 <= n; i += 2) {
627
+ v128_t angles_f64x2 = wasm_v128_load(ins + i);
628
+ v128_t results_f64x2 = nk_f64x2_cos_v128relaxed_(angles_f64x2);
629
+ wasm_v128_store(outs + i, results_f64x2);
630
+ }
631
+ if (i < n) {
632
+ nk_size_t remaining = n - i;
633
+ nk_b128_vec_t angles_vec;
634
+ nk_partial_load_b64x2_serial_(ins + i, &angles_vec, remaining);
635
+ nk_b128_vec_t results_vec;
636
+ results_vec.v128 = nk_f64x2_cos_v128relaxed_(angles_vec.v128);
637
+ nk_partial_store_b64x2_serial_(&results_vec, outs + i, remaining);
638
+ }
639
+ }
640
+
641
+ NK_PUBLIC void nk_each_atan_f64_v128relaxed(nk_f64_t const *ins, nk_size_t n, nk_f64_t *outs) {
642
+ nk_size_t i = 0;
643
+ for (; i + 2 <= n; i += 2) {
644
+ v128_t values_f64x2 = wasm_v128_load(ins + i);
645
+ v128_t results_f64x2 = nk_f64x2_atan_v128relaxed_(values_f64x2);
646
+ wasm_v128_store(outs + i, results_f64x2);
647
+ }
648
+ if (i < n) {
649
+ nk_size_t remaining = n - i;
650
+ nk_b128_vec_t values_vec;
651
+ nk_partial_load_b64x2_serial_(ins + i, &values_vec, remaining);
652
+ nk_b128_vec_t results_vec;
653
+ results_vec.v128 = nk_f64x2_atan_v128relaxed_(values_vec.v128);
654
+ nk_partial_store_b64x2_serial_(&results_vec, outs + i, remaining);
655
+ }
656
+ }
657
+
658
+ #if defined(__clang__)
659
+ #pragma clang attribute pop
660
+ #endif
661
+
662
+ #if defined(__cplusplus)
663
+ } // extern "C"
664
+ #endif
665
+
666
+ #endif // NK_TARGET_V128RELAXED
667
+ #endif // NK_TRIGONOMETRY_V128RELAXED_H