usearch 2.21.4 → 2.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -69
- package/binding.gyp +15 -37
- package/c/CMakeLists.txt +4 -5
- package/c/README.md +8 -8
- package/c/lib.cpp +32 -14
- package/c/test.c +124 -1
- package/c/usearch.h +24 -3
- package/cpp/CMakeLists.txt +4 -0
- package/cpp/README.md +5 -5
- package/cpp/bench.cpp +97 -116
- package/cpp/test.cpp +117 -20
- package/include/usearch/index.hpp +224 -48
- package/include/usearch/index_dense.hpp +105 -40
- package/include/usearch/index_plugins.hpp +1387 -204
- package/javascript/README.md +1 -1
- package/javascript/dist/cjs/usearch.d.ts +8 -3
- package/javascript/dist/cjs/usearch.js +12 -4
- package/javascript/dist/esm/usearch.d.ts +8 -3
- package/javascript/dist/esm/usearch.js +12 -4
- package/javascript/lib.cpp +17 -0
- package/javascript/usearch.test.js +117 -94
- package/javascript/usearch.ts +14 -6
- package/numkong/.clang-tidy +30 -0
- package/{simsimd → numkong}/.cmake-format.py +18 -0
- package/numkong/.editorconfig +12 -0
- package/numkong/.git-blame-ignore-revs +123 -0
- package/numkong/.mailmap +15 -0
- package/numkong/.spi.yml +11 -0
- package/numkong/.swift-format +14 -0
- package/numkong/CITATION.cff +81 -0
- package/numkong/CONTRIBUTING.md +500 -0
- package/numkong/Cargo.toml +54 -0
- package/numkong/MANIFEST.in +8 -0
- package/numkong/Package.swift +84 -0
- package/numkong/README.md +569 -0
- package/numkong/bench/README.md +217 -0
- package/numkong/bench/bench-browser.html +323 -0
- package/numkong/bench/bench.cpp +344 -0
- package/numkong/bench/bench.hpp +816 -0
- package/numkong/bench/bench.js +148 -0
- package/numkong/bench/bench.mjs +616 -0
- package/numkong/bench/bench_attention.cpp +113 -0
- package/numkong/bench/bench_cast.cpp +264 -0
- package/numkong/bench/bench_cross_amx.cpp +62 -0
- package/numkong/bench/bench_cross_arm.cpp +245 -0
- package/numkong/bench/bench_cross_blas.cpp +309 -0
- package/numkong/bench/bench_cross_loongarch.cpp +106 -0
- package/numkong/bench/bench_cross_power.cpp +84 -0
- package/numkong/bench/bench_cross_rvv.cpp +121 -0
- package/numkong/bench/bench_cross_serial.cpp +151 -0
- package/numkong/bench/bench_cross_sme.cpp +163 -0
- package/numkong/bench/bench_cross_wasm.cpp +142 -0
- package/numkong/bench/bench_cross_x86.cpp +455 -0
- package/numkong/bench/bench_curved.cpp +210 -0
- package/numkong/bench/bench_dot.cpp +315 -0
- package/numkong/bench/bench_each.cpp +503 -0
- package/numkong/bench/bench_geospatial.cpp +112 -0
- package/numkong/bench/bench_maxsim.cpp +154 -0
- package/numkong/bench/bench_mesh.cpp +148 -0
- package/numkong/bench/bench_probability.cpp +60 -0
- package/numkong/bench/bench_reduce.cpp +371 -0
- package/numkong/bench/bench_set.cpp +73 -0
- package/numkong/bench/bench_sparse.cpp +198 -0
- package/numkong/bench/bench_spatial.cpp +347 -0
- package/numkong/bench/bench_trigonometry.cpp +137 -0
- package/numkong/bench/swift/Bench.swift +506 -0
- package/numkong/binding.gyp +169 -0
- package/numkong/build.rs +484 -0
- package/numkong/c/dispatch.h +512 -0
- package/numkong/c/dispatch_bf16.c +447 -0
- package/numkong/c/dispatch_bf16c.c +52 -0
- package/numkong/c/dispatch_e2m3.c +296 -0
- package/numkong/c/dispatch_e3m2.c +284 -0
- package/numkong/c/dispatch_e4m3.c +318 -0
- package/numkong/c/dispatch_e5m2.c +316 -0
- package/numkong/c/dispatch_f16.c +452 -0
- package/numkong/c/dispatch_f16c.c +58 -0
- package/numkong/c/dispatch_f32.c +434 -0
- package/numkong/c/dispatch_f32c.c +99 -0
- package/numkong/c/dispatch_f64.c +348 -0
- package/numkong/c/dispatch_f64c.c +98 -0
- package/numkong/c/dispatch_i16.c +96 -0
- package/numkong/c/dispatch_i32.c +89 -0
- package/numkong/c/dispatch_i4.c +153 -0
- package/numkong/c/dispatch_i64.c +86 -0
- package/numkong/c/dispatch_i8.c +348 -0
- package/numkong/c/dispatch_other.c +348 -0
- package/numkong/c/dispatch_u1.c +193 -0
- package/numkong/c/dispatch_u16.c +124 -0
- package/numkong/c/dispatch_u32.c +118 -0
- package/numkong/c/dispatch_u4.c +153 -0
- package/numkong/c/dispatch_u64.c +102 -0
- package/numkong/c/dispatch_u8.c +364 -0
- package/numkong/c/numkong.c +940 -0
- package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
- package/numkong/cmake/nk_isa_probe.cmake +90 -0
- package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_math_lib.cmake +46 -0
- package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
- package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
- package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
- package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
- package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
- package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
- package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
- package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
- package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
- package/numkong/cmake/toolchain-wasi.cmake +77 -0
- package/numkong/cmake/toolchain-wasm.cmake +70 -0
- package/numkong/cmake/toolchain-wasm64.cmake +62 -0
- package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
- package/numkong/include/README.md +643 -0
- package/numkong/include/module.modulemap +129 -0
- package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
- package/numkong/include/numkong/attention/sme.h +2075 -0
- package/numkong/include/numkong/attention.h +49 -0
- package/numkong/include/numkong/capabilities.h +930 -0
- package/numkong/include/numkong/cast/README.md +262 -0
- package/numkong/include/numkong/cast/diamond.h +64 -0
- package/numkong/include/numkong/cast/haswell.h +823 -0
- package/numkong/include/numkong/cast/icelake.h +475 -0
- package/numkong/include/numkong/cast/loongsonasx.h +252 -0
- package/numkong/include/numkong/cast/neon.h +1174 -0
- package/numkong/include/numkong/cast/powervsx.h +449 -0
- package/numkong/include/numkong/cast/rvv.h +970 -0
- package/numkong/include/numkong/cast/sapphire.h +262 -0
- package/numkong/include/numkong/cast/serial.h +2336 -0
- package/numkong/include/numkong/cast/skylake.h +915 -0
- package/numkong/include/numkong/cast/v128relaxed.h +537 -0
- package/numkong/include/numkong/cast.h +254 -0
- package/numkong/include/numkong/cast.hpp +44 -0
- package/numkong/include/numkong/curved/README.md +223 -0
- package/numkong/include/numkong/curved/genoa.h +182 -0
- package/numkong/include/numkong/curved/haswell.h +276 -0
- package/numkong/include/numkong/curved/neon.h +329 -0
- package/numkong/include/numkong/curved/neonbfdot.h +211 -0
- package/numkong/include/numkong/curved/rvv.h +305 -0
- package/numkong/include/numkong/curved/serial.h +207 -0
- package/numkong/include/numkong/curved/skylake.h +457 -0
- package/numkong/include/numkong/curved/smef64.h +530 -0
- package/numkong/include/numkong/curved.h +513 -0
- package/numkong/include/numkong/curved.hpp +144 -0
- package/numkong/include/numkong/dot/README.md +442 -0
- package/numkong/include/numkong/dot/alder.h +563 -0
- package/numkong/include/numkong/dot/diamond.h +158 -0
- package/numkong/include/numkong/dot/genoa.h +289 -0
- package/numkong/include/numkong/dot/haswell.h +1723 -0
- package/numkong/include/numkong/dot/icelake.h +997 -0
- package/numkong/include/numkong/dot/loongsonasx.h +671 -0
- package/numkong/include/numkong/dot/neon.h +869 -0
- package/numkong/include/numkong/dot/neonbfdot.h +243 -0
- package/numkong/include/numkong/dot/neonfhm.h +358 -0
- package/numkong/include/numkong/dot/neonfp8.h +323 -0
- package/numkong/include/numkong/dot/neonsdot.h +622 -0
- package/numkong/include/numkong/dot/powervsx.h +752 -0
- package/numkong/include/numkong/dot/rvv.h +722 -0
- package/numkong/include/numkong/dot/rvvbb.h +72 -0
- package/numkong/include/numkong/dot/rvvbf16.h +123 -0
- package/numkong/include/numkong/dot/rvvhalf.h +129 -0
- package/numkong/include/numkong/dot/sapphire.h +141 -0
- package/numkong/include/numkong/dot/serial.h +874 -0
- package/numkong/include/numkong/dot/sierra.h +405 -0
- package/numkong/include/numkong/dot/skylake.h +1116 -0
- package/numkong/include/numkong/dot/sve.h +420 -0
- package/numkong/include/numkong/dot/svebfdot.h +75 -0
- package/numkong/include/numkong/dot/svehalf.h +168 -0
- package/numkong/include/numkong/dot/svesdot.h +90 -0
- package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
- package/numkong/include/numkong/dot.h +1136 -0
- package/numkong/include/numkong/dot.hpp +94 -0
- package/numkong/include/numkong/dots/README.md +496 -0
- package/numkong/include/numkong/dots/alder.h +117 -0
- package/numkong/include/numkong/dots/diamond.h +86 -0
- package/numkong/include/numkong/dots/genoa.h +100 -0
- package/numkong/include/numkong/dots/graniteamx.h +733 -0
- package/numkong/include/numkong/dots/haswell.h +310 -0
- package/numkong/include/numkong/dots/icelake.h +180 -0
- package/numkong/include/numkong/dots/loongsonasx.h +176 -0
- package/numkong/include/numkong/dots/neon.h +123 -0
- package/numkong/include/numkong/dots/neonbfdot.h +59 -0
- package/numkong/include/numkong/dots/neonfhm.h +96 -0
- package/numkong/include/numkong/dots/neonfp8.h +99 -0
- package/numkong/include/numkong/dots/neonsdot.h +144 -0
- package/numkong/include/numkong/dots/powervsx.h +194 -0
- package/numkong/include/numkong/dots/rvv.h +2593 -0
- package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
- package/numkong/include/numkong/dots/serial.h +2867 -0
- package/numkong/include/numkong/dots/sierra.h +100 -0
- package/numkong/include/numkong/dots/skylake.h +207 -0
- package/numkong/include/numkong/dots/sme.h +5041 -0
- package/numkong/include/numkong/dots/smebi32.h +477 -0
- package/numkong/include/numkong/dots/smef64.h +1328 -0
- package/numkong/include/numkong/dots/smehalf.h +47 -0
- package/numkong/include/numkong/dots/v128relaxed.h +317 -0
- package/numkong/include/numkong/dots.h +3110 -0
- package/numkong/include/numkong/dots.hpp +641 -0
- package/numkong/include/numkong/each/README.md +465 -0
- package/numkong/include/numkong/each/haswell.h +1658 -0
- package/numkong/include/numkong/each/icelake.h +272 -0
- package/numkong/include/numkong/each/neon.h +1138 -0
- package/numkong/include/numkong/each/neonbfdot.h +211 -0
- package/numkong/include/numkong/each/neonhalf.h +318 -0
- package/numkong/include/numkong/each/rvv.h +1121 -0
- package/numkong/include/numkong/each/sapphire.h +343 -0
- package/numkong/include/numkong/each/serial.h +282 -0
- package/numkong/include/numkong/each/skylake.h +1562 -0
- package/numkong/include/numkong/each/v128relaxed.h +562 -0
- package/numkong/include/numkong/each.h +2232 -0
- package/numkong/include/numkong/each.hpp +434 -0
- package/numkong/include/numkong/geospatial/README.md +147 -0
- package/numkong/include/numkong/geospatial/haswell.h +633 -0
- package/numkong/include/numkong/geospatial/neon.h +615 -0
- package/numkong/include/numkong/geospatial/rvv.h +701 -0
- package/numkong/include/numkong/geospatial/serial.h +309 -0
- package/numkong/include/numkong/geospatial/skylake.h +613 -0
- package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
- package/numkong/include/numkong/geospatial.h +453 -0
- package/numkong/include/numkong/geospatial.hpp +235 -0
- package/numkong/include/numkong/matrix.hpp +336 -0
- package/numkong/include/numkong/maxsim/README.md +187 -0
- package/numkong/include/numkong/maxsim/alder.h +511 -0
- package/numkong/include/numkong/maxsim/genoa.h +115 -0
- package/numkong/include/numkong/maxsim/haswell.h +553 -0
- package/numkong/include/numkong/maxsim/icelake.h +480 -0
- package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
- package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
- package/numkong/include/numkong/maxsim/serial.h +490 -0
- package/numkong/include/numkong/maxsim/sme.h +993 -0
- package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
- package/numkong/include/numkong/maxsim.h +571 -0
- package/numkong/include/numkong/maxsim.hpp +133 -0
- package/numkong/include/numkong/mesh/README.md +219 -0
- package/numkong/include/numkong/mesh/haswell.h +2013 -0
- package/numkong/include/numkong/mesh/neon.h +1821 -0
- package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
- package/numkong/include/numkong/mesh/rvv.h +936 -0
- package/numkong/include/numkong/mesh/serial.h +721 -0
- package/numkong/include/numkong/mesh/skylake.h +2344 -0
- package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
- package/numkong/include/numkong/mesh.h +666 -0
- package/numkong/include/numkong/mesh.hpp +701 -0
- package/numkong/include/numkong/numkong.h +78 -0
- package/numkong/include/numkong/numkong.hpp +58 -0
- package/numkong/include/numkong/probability/README.md +177 -0
- package/numkong/include/numkong/probability/haswell.h +267 -0
- package/numkong/include/numkong/probability/neon.h +255 -0
- package/numkong/include/numkong/probability/rvv.h +414 -0
- package/numkong/include/numkong/probability/serial.h +181 -0
- package/numkong/include/numkong/probability/skylake.h +324 -0
- package/numkong/include/numkong/probability.h +380 -0
- package/numkong/include/numkong/probability.hpp +120 -0
- package/numkong/include/numkong/random.h +50 -0
- package/numkong/include/numkong/random.hpp +285 -0
- package/numkong/include/numkong/reduce/README.md +552 -0
- package/numkong/include/numkong/reduce/alder.h +636 -0
- package/numkong/include/numkong/reduce/genoa.h +201 -0
- package/numkong/include/numkong/reduce/haswell.h +3785 -0
- package/numkong/include/numkong/reduce/icelake.h +549 -0
- package/numkong/include/numkong/reduce/neon.h +3980 -0
- package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
- package/numkong/include/numkong/reduce/neonfhm.h +293 -0
- package/numkong/include/numkong/reduce/neonsdot.h +357 -0
- package/numkong/include/numkong/reduce/rvv.h +3533 -0
- package/numkong/include/numkong/reduce/serial.h +753 -0
- package/numkong/include/numkong/reduce/sierra.h +338 -0
- package/numkong/include/numkong/reduce/skylake.h +3794 -0
- package/numkong/include/numkong/reduce/sve.h +52 -0
- package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
- package/numkong/include/numkong/reduce.h +1582 -0
- package/numkong/include/numkong/reduce.hpp +778 -0
- package/numkong/include/numkong/scalar/README.md +89 -0
- package/numkong/include/numkong/scalar/haswell.h +122 -0
- package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
- package/numkong/include/numkong/scalar/neon.h +122 -0
- package/numkong/include/numkong/scalar/neonhalf.h +70 -0
- package/numkong/include/numkong/scalar/powervsx.h +96 -0
- package/numkong/include/numkong/scalar/rvv.h +211 -0
- package/numkong/include/numkong/scalar/sapphire.h +74 -0
- package/numkong/include/numkong/scalar/serial.h +332 -0
- package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
- package/numkong/include/numkong/scalar.h +696 -0
- package/numkong/include/numkong/set/README.md +179 -0
- package/numkong/include/numkong/set/haswell.h +334 -0
- package/numkong/include/numkong/set/icelake.h +485 -0
- package/numkong/include/numkong/set/loongsonasx.h +181 -0
- package/numkong/include/numkong/set/neon.h +363 -0
- package/numkong/include/numkong/set/powervsx.h +326 -0
- package/numkong/include/numkong/set/rvv.h +226 -0
- package/numkong/include/numkong/set/rvvbb.h +117 -0
- package/numkong/include/numkong/set/serial.h +174 -0
- package/numkong/include/numkong/set/sve.h +187 -0
- package/numkong/include/numkong/set/v128relaxed.h +240 -0
- package/numkong/include/numkong/set.h +471 -0
- package/numkong/include/numkong/set.hpp +114 -0
- package/numkong/include/numkong/sets/README.md +149 -0
- package/numkong/include/numkong/sets/haswell.h +63 -0
- package/numkong/include/numkong/sets/icelake.h +66 -0
- package/numkong/include/numkong/sets/loongsonasx.h +52 -0
- package/numkong/include/numkong/sets/neon.h +61 -0
- package/numkong/include/numkong/sets/powervsx.h +65 -0
- package/numkong/include/numkong/sets/serial.h +43 -0
- package/numkong/include/numkong/sets/smebi32.h +1135 -0
- package/numkong/include/numkong/sets/v128relaxed.h +58 -0
- package/numkong/include/numkong/sets.h +382 -0
- package/numkong/include/numkong/sparse/README.md +156 -0
- package/numkong/include/numkong/sparse/icelake.h +463 -0
- package/numkong/include/numkong/sparse/neon.h +288 -0
- package/numkong/include/numkong/sparse/serial.h +117 -0
- package/numkong/include/numkong/sparse/sve2.h +504 -0
- package/numkong/include/numkong/sparse/turin.h +322 -0
- package/numkong/include/numkong/sparse.h +363 -0
- package/numkong/include/numkong/sparse.hpp +113 -0
- package/numkong/include/numkong/spatial/README.md +439 -0
- package/numkong/include/numkong/spatial/alder.h +604 -0
- package/numkong/include/numkong/spatial/diamond.h +240 -0
- package/numkong/include/numkong/spatial/genoa.h +222 -0
- package/numkong/include/numkong/spatial/haswell.h +979 -0
- package/numkong/include/numkong/spatial/icelake.h +1067 -0
- package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
- package/numkong/include/numkong/spatial/neon.h +846 -0
- package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
- package/numkong/include/numkong/spatial/neonfp8.h +258 -0
- package/numkong/include/numkong/spatial/neonsdot.h +429 -0
- package/numkong/include/numkong/spatial/powervsx.h +738 -0
- package/numkong/include/numkong/spatial/rvv.h +991 -0
- package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
- package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
- package/numkong/include/numkong/spatial/serial.h +347 -0
- package/numkong/include/numkong/spatial/sierra.h +516 -0
- package/numkong/include/numkong/spatial/skylake.h +605 -0
- package/numkong/include/numkong/spatial/sve.h +246 -0
- package/numkong/include/numkong/spatial/svebfdot.h +125 -0
- package/numkong/include/numkong/spatial/svehalf.h +136 -0
- package/numkong/include/numkong/spatial/svesdot.h +143 -0
- package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
- package/numkong/include/numkong/spatial.h +1681 -0
- package/numkong/include/numkong/spatial.hpp +183 -0
- package/numkong/include/numkong/spatials/README.md +580 -0
- package/numkong/include/numkong/spatials/alder.h +94 -0
- package/numkong/include/numkong/spatials/diamond.h +82 -0
- package/numkong/include/numkong/spatials/genoa.h +94 -0
- package/numkong/include/numkong/spatials/graniteamx.h +173 -0
- package/numkong/include/numkong/spatials/haswell.h +219 -0
- package/numkong/include/numkong/spatials/icelake.h +113 -0
- package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
- package/numkong/include/numkong/spatials/neon.h +109 -0
- package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
- package/numkong/include/numkong/spatials/neonfhm.h +92 -0
- package/numkong/include/numkong/spatials/neonfp8.h +111 -0
- package/numkong/include/numkong/spatials/neonsdot.h +143 -0
- package/numkong/include/numkong/spatials/powervsx.h +153 -0
- package/numkong/include/numkong/spatials/rvv.h +1976 -0
- package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
- package/numkong/include/numkong/spatials/serial.h +248 -0
- package/numkong/include/numkong/spatials/sierra.h +96 -0
- package/numkong/include/numkong/spatials/skylake.h +184 -0
- package/numkong/include/numkong/spatials/sme.h +1927 -0
- package/numkong/include/numkong/spatials/smef64.h +483 -0
- package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
- package/numkong/include/numkong/spatials.h +3374 -0
- package/numkong/include/numkong/spatials.hpp +509 -0
- package/numkong/include/numkong/tensor.hpp +1981 -0
- package/numkong/include/numkong/trigonometry/README.md +184 -0
- package/numkong/include/numkong/trigonometry/haswell.h +653 -0
- package/numkong/include/numkong/trigonometry/neon.h +638 -0
- package/numkong/include/numkong/trigonometry/rvv.h +700 -0
- package/numkong/include/numkong/trigonometry/serial.h +703 -0
- package/numkong/include/numkong/trigonometry/skylake.h +725 -0
- package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
- package/numkong/include/numkong/trigonometry.h +467 -0
- package/numkong/include/numkong/trigonometry.hpp +166 -0
- package/numkong/include/numkong/types.h +1695 -0
- package/numkong/include/numkong/types.hpp +6027 -0
- package/numkong/include/numkong/vector.hpp +766 -0
- package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
- package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
- package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
- package/numkong/javascript/README.md +254 -0
- package/numkong/javascript/node-gyp-build.d.ts +4 -0
- package/numkong/javascript/numkong-browser.ts +40 -0
- package/numkong/javascript/numkong-wasm.ts +750 -0
- package/numkong/javascript/numkong.c +712 -0
- package/numkong/javascript/numkong.ts +613 -0
- package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
- package/numkong/javascript/tsconfig-cjs.json +13 -0
- package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
- package/numkong/javascript/types.ts +784 -0
- package/numkong/numkong.gypi +104 -0
- package/numkong/package.json +108 -0
- package/numkong/probes/arm_neon.c +8 -0
- package/numkong/probes/arm_neon_bfdot.c +9 -0
- package/numkong/probes/arm_neon_fhm.c +9 -0
- package/numkong/probes/arm_neon_half.c +8 -0
- package/numkong/probes/arm_neon_sdot.c +9 -0
- package/numkong/probes/arm_neonfp8.c +9 -0
- package/numkong/probes/arm_sme.c +16 -0
- package/numkong/probes/arm_sme2.c +16 -0
- package/numkong/probes/arm_sme2p1.c +16 -0
- package/numkong/probes/arm_sme_bf16.c +16 -0
- package/numkong/probes/arm_sme_bi32.c +16 -0
- package/numkong/probes/arm_sme_f64.c +16 -0
- package/numkong/probes/arm_sme_fa64.c +14 -0
- package/numkong/probes/arm_sme_half.c +16 -0
- package/numkong/probes/arm_sme_lut2.c +15 -0
- package/numkong/probes/arm_sve.c +18 -0
- package/numkong/probes/arm_sve2.c +20 -0
- package/numkong/probes/arm_sve2p1.c +18 -0
- package/numkong/probes/arm_sve_bfdot.c +20 -0
- package/numkong/probes/arm_sve_half.c +18 -0
- package/numkong/probes/arm_sve_sdot.c +21 -0
- package/numkong/probes/loongarch_lasx.c +12 -0
- package/numkong/probes/power_vsx.c +12 -0
- package/numkong/probes/probe.js +127 -0
- package/numkong/probes/riscv_rvv.c +14 -0
- package/numkong/probes/riscv_rvv_bb.c +15 -0
- package/numkong/probes/riscv_rvv_bf16.c +17 -0
- package/numkong/probes/riscv_rvv_half.c +14 -0
- package/numkong/probes/wasm_v128relaxed.c +11 -0
- package/numkong/probes/x86_alder.c +17 -0
- package/numkong/probes/x86_diamond.c +17 -0
- package/numkong/probes/x86_genoa.c +17 -0
- package/numkong/probes/x86_graniteamx.c +19 -0
- package/numkong/probes/x86_haswell.c +11 -0
- package/numkong/probes/x86_icelake.c +17 -0
- package/numkong/probes/x86_sapphire.c +16 -0
- package/numkong/probes/x86_sapphireamx.c +18 -0
- package/numkong/probes/x86_sierra.c +17 -0
- package/numkong/probes/x86_skylake.c +15 -0
- package/numkong/probes/x86_turin.c +17 -0
- package/numkong/rust/README.md +698 -0
- package/numkong/rust/capabilities.rs +96 -0
- package/numkong/rust/cast.rs +314 -0
- package/numkong/rust/curved.rs +391 -0
- package/numkong/rust/each.rs +2721 -0
- package/numkong/rust/geospatial.rs +343 -0
- package/numkong/rust/matrix.rs +5424 -0
- package/numkong/rust/maxsim.rs +540 -0
- package/numkong/rust/mesh.rs +837 -0
- package/numkong/rust/numkong.rs +409 -0
- package/numkong/rust/probability.rs +272 -0
- package/numkong/rust/reduce.rs +1249 -0
- package/numkong/rust/set.rs +194 -0
- package/numkong/rust/sparse.rs +513 -0
- package/numkong/rust/spatial.rs +1815 -0
- package/numkong/rust/tensor.rs +7565 -0
- package/numkong/rust/types.rs +3666 -0
- package/numkong/rust/vector.rs +1899 -0
- package/numkong/rustfmt.toml +2 -0
- package/numkong/swift/Matrix.swift +1388 -0
- package/numkong/swift/MaxSim.swift +151 -0
- package/numkong/swift/NumKong.swift +283 -0
- package/numkong/swift/Numerics.swift +329 -0
- package/numkong/swift/README.md +433 -0
- package/numkong/swift/Scalar.swift +741 -0
- package/numkong/swift/Tensor.swift +209 -0
- package/numkong/test/README.md +315 -0
- package/numkong/test/playwright.config.ts +16 -0
- package/numkong/test/swift/Test.swift +534 -0
- package/numkong/test/test-browser-bundle-runner.mjs +36 -0
- package/numkong/test/test-browser-bundle.html +188 -0
- package/numkong/test/test-browser-runner.mjs +43 -0
- package/numkong/test/test-browser.html +305 -0
- package/numkong/test/test-dtypes.mjs +453 -0
- package/numkong/test/test-wasm.mjs +267 -0
- package/numkong/test/test.cpp +442 -0
- package/numkong/test/test.hpp +580 -0
- package/numkong/test/test.mjs +363 -0
- package/numkong/test/test_base.py +1041 -0
- package/numkong/test/test_cast.cpp +242 -0
- package/numkong/test/test_cross.hpp +551 -0
- package/numkong/test/test_cross.py +467 -0
- package/numkong/test/test_cross_amx.cpp +50 -0
- package/numkong/test/test_cross_arm.cpp +225 -0
- package/numkong/test/test_cross_blas.cpp +354 -0
- package/numkong/test/test_cross_loongarch.cpp +90 -0
- package/numkong/test/test_cross_power.cpp +73 -0
- package/numkong/test/test_cross_rvv.cpp +109 -0
- package/numkong/test/test_cross_serial.cpp +181 -0
- package/numkong/test/test_cross_sme.cpp +148 -0
- package/numkong/test/test_cross_wasm.cpp +141 -0
- package/numkong/test/test_cross_x86.cpp +442 -0
- package/numkong/test/test_curved.cpp +182 -0
- package/numkong/test/test_curved.py +207 -0
- package/numkong/test/test_dot.cpp +353 -0
- package/numkong/test/test_dot.py +296 -0
- package/numkong/test/test_each.cpp +437 -0
- package/numkong/test/test_each.py +756 -0
- package/numkong/test/test_geospatial.cpp +155 -0
- package/numkong/test/test_geospatial.py +241 -0
- package/numkong/test/test_maxsim.cpp +138 -0
- package/numkong/test/test_maxsim.py +209 -0
- package/numkong/test/test_mesh.cpp +203 -0
- package/numkong/test/test_mesh.py +394 -0
- package/numkong/test/test_probability.cpp +136 -0
- package/numkong/test/test_probability.py +166 -0
- package/numkong/test/test_reduce.cpp +563 -0
- package/numkong/test/test_reduce.py +781 -0
- package/numkong/test/test_set.cpp +151 -0
- package/numkong/test/test_set.py +120 -0
- package/numkong/test/test_similarities.py +579 -0
- package/numkong/test/test_sparse.cpp +121 -0
- package/numkong/test/test_sparse.py +118 -0
- package/numkong/test/test_spatial.cpp +518 -0
- package/numkong/test/test_spatial.py +269 -0
- package/numkong/test/test_tensor.cpp +884 -0
- package/numkong/test/test_tensor.py +1417 -0
- package/numkong/test/test_trigonometry.cpp +156 -0
- package/numkong/test/test_trigonometry.py +180 -0
- package/package.json +7 -8
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/fp16/CMakeLists.txt +0 -176
- package/fp16/LICENSE +0 -11
- package/fp16/README.md +0 -20
- package/fp16/bench/alt-element.cc +0 -89
- package/fp16/bench/from-alt-array.cc +0 -175
- package/fp16/bench/from-ieee-array.cc +0 -399
- package/fp16/bench/ieee-element.cc +0 -272
- package/fp16/bench/to-alt-array.cc +0 -91
- package/fp16/bench/to-ieee-array.cc +0 -303
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
- package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
- package/fp16/cmake/DownloadPSimd.cmake +0 -15
- package/fp16/configure.py +0 -65
- package/fp16/confu.yaml +0 -8
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +0 -50
- package/fp16/include/fp16/avx2.py +0 -53
- package/fp16/include/fp16/bitcasts.h +0 -92
- package/fp16/include/fp16/fp16.h +0 -451
- package/fp16/include/fp16/psimd.h +0 -131
- package/fp16/include/fp16.h +0 -11
- package/fp16/jni/Android.mk +0 -6
- package/fp16/jni/Application.mk +0 -4
- package/fp16/test/alt-from-fp32-value.cc +0 -498
- package/fp16/test/alt-to-fp32-bits.cc +0 -263
- package/fp16/test/alt-to-fp32-psimd.cc +0 -145
- package/fp16/test/alt-to-fp32-value.cc +0 -348
- package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
- package/fp16/test/bitcasts.cc +0 -56
- package/fp16/test/ieee-from-fp32-value.cc +0 -523
- package/fp16/test/ieee-to-fp32-bits.cc +0 -333
- package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
- package/fp16/test/ieee-to-fp32-value.cc +0 -420
- package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
- package/fp16/test/peachpy/stubs.py +0 -38
- package/fp16/test/tables.cc +0 -530
- package/fp16/test/tables.h +0 -13
- package/fp16/third-party/THHalf.h +0 -92
- package/fp16/third-party/eigen-half.h +0 -170
- package/fp16/third-party/float16-compressor.h +0 -80
- package/fp16/third-party/half.hpp +0 -2916
- package/fp16/third-party/npy-halffloat.h +0 -328
- package/simsimd/.git-blame-ignore-revs +0 -2
- package/simsimd/CONTRIBUTING.md +0 -321
- package/simsimd/Cargo.toml +0 -49
- package/simsimd/MANIFEST.in +0 -4
- package/simsimd/Package.swift +0 -28
- package/simsimd/README.md +0 -1493
- package/simsimd/binding.gyp +0 -35
- package/simsimd/build.rs +0 -70
- package/simsimd/c/lib.c +0 -374
- package/simsimd/include/module.modulemap +0 -4
- package/simsimd/include/simsimd/binary.h +0 -486
- package/simsimd/include/simsimd/curved.h +0 -1541
- package/simsimd/include/simsimd/dot.h +0 -1853
- package/simsimd/include/simsimd/elementwise.h +0 -2465
- package/simsimd/include/simsimd/geospatial.h +0 -43
- package/simsimd/include/simsimd/mesh.h +0 -69
- package/simsimd/include/simsimd/probability.h +0 -606
- package/simsimd/include/simsimd/simsimd.h +0 -2567
- package/simsimd/include/simsimd/sparse.h +0 -1384
- package/simsimd/include/simsimd/spatial.h +0 -2335
- package/simsimd/include/simsimd/types.h +0 -666
- package/simsimd/javascript/fallback.ts +0 -233
- package/simsimd/javascript/lib.c +0 -125
- package/simsimd/javascript/node-gyp-build.d.ts +0 -1
- package/simsimd/javascript/simsimd.ts +0 -179
- package/simsimd/javascript/tsconfig-cjs.json +0 -8
- package/simsimd/package-lock.json +0 -1761
- package/simsimd/package.json +0 -61
- package/simsimd/rust/lib.rs +0 -1821
- package/simsimd/scripts/bench.cxx +0 -1170
- package/simsimd/scripts/bench.ipynb +0 -187
- package/simsimd/scripts/bench.js +0 -127
- package/simsimd/scripts/bench.rs +0 -876
- package/simsimd/scripts/bench_vectors.py +0 -734
- package/simsimd/scripts/bench_vectors_live.py +0 -213
- package/simsimd/scripts/test.c +0 -187
- package/simsimd/scripts/test.mjs +0 -220
- package/simsimd/scripts/test.py +0 -1505
- package/simsimd/swift/SimSIMD.swift +0 -149
- package/simsimd/swift/Test.swift +0 -128
- /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
- /package/{simsimd → numkong}/LICENSE +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
- /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
|