react-native-executorch 0.10.6 → 0.10.7

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 (237) hide show
  1. package/lib/module/fetcher/telemetry.js +1 -1
  2. package/package.json +1 -1
  3. package/react-native-executorch.podspec +2 -0
  4. package/src/fetcher/telemetry.ts +1 -1
  5. package/third-party/common/phonemis/CMakeLists.txt +70 -14
  6. package/third-party/common/phonemis/README.md +183 -33
  7. package/third-party/common/phonemis/THIRD_PARTY_NOTICES.md +57 -0
  8. package/third-party/common/phonemis/knowledge/code_style.md +642 -0
  9. package/third-party/common/phonemis/licenses/Unicode-3.0.txt +39 -0
  10. package/third-party/common/phonemis/licenses/misaki-Apache-2.0.txt +201 -0
  11. package/third-party/common/phonemis/licenses/nlohmann-json-MIT.txt +21 -0
  12. package/third-party/common/phonemis/licenses/xsimd-BSD-3-Clause.txt +29 -0
  13. package/third-party/common/phonemis/src/phonemis/base/config.h +6 -0
  14. package/third-party/common/phonemis/src/phonemis/base/ipipeline.cpp +75 -0
  15. package/third-party/common/phonemis/src/phonemis/base/ipipeline.h +21 -0
  16. package/third-party/common/phonemis/src/phonemis/base/phonemizer/constants.h +2 -5
  17. package/third-party/common/phonemis/src/phonemis/base/phonemizer/lexicon_phonemizer.cpp +3 -4
  18. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/neural_phonemizer.cpp +17 -8
  19. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/neural_phonemizer.h +4 -0
  20. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/tokenizer.cpp +21 -6
  21. package/third-party/common/phonemis/src/phonemis/base/phonemizer/nn/tokenizer.h +13 -4
  22. package/third-party/common/phonemis/src/phonemis/base/pipeline.cpp +8 -0
  23. package/third-party/common/phonemis/src/phonemis/base/pipeline.h +19 -0
  24. package/third-party/common/phonemis/src/phonemis/base/processor/common/conditions.cpp +37 -0
  25. package/third-party/common/phonemis/src/phonemis/base/processor/common/conditions.h +45 -0
  26. package/third-party/common/phonemis/src/phonemis/base/processor/common/constants.h +10 -0
  27. package/third-party/common/phonemis/src/phonemis/base/processor/common/context.cpp +105 -0
  28. package/third-party/common/phonemis/src/phonemis/base/processor/common/context.h +49 -0
  29. package/third-party/common/phonemis/src/phonemis/base/processor/common/document.cpp +173 -0
  30. package/third-party/common/phonemis/src/phonemis/base/processor/common/document.h +67 -0
  31. package/third-party/common/phonemis/src/phonemis/base/processor/common/text.cpp +75 -0
  32. package/third-party/common/phonemis/src/phonemis/base/processor/common/text.h +60 -0
  33. package/third-party/common/phonemis/src/phonemis/base/processor/common/types.h +18 -0
  34. package/third-party/common/phonemis/src/phonemis/base/processor/config.h +53 -0
  35. package/third-party/common/phonemis/src/phonemis/base/processor/layer.h +9 -7
  36. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/constants.h +20 -0
  37. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/layer.cpp +89 -0
  38. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/layer.h +35 -0
  39. package/third-party/common/phonemis/src/phonemis/base/processor/layers/normalize/types.h +16 -0
  40. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/kind.h +40 -0
  41. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/layer.h +382 -0
  42. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/notation.h +30 -0
  43. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/numerals.cpp +51 -0
  44. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/numerals.h +31 -0
  45. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/pattern.h +30 -0
  46. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/pattern_set.cpp +17 -0
  47. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/pattern_set.h +31 -0
  48. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/patterns.cpp +811 -0
  49. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/patterns.h +285 -0
  50. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/primitives.cpp +64 -0
  51. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/primitives.h +23 -0
  52. package/third-party/common/phonemis/src/phonemis/base/processor/layers/num2word/types.h +94 -0
  53. package/third-party/common/phonemis/src/phonemis/base/processor/layers/sanitizer/layer.cpp +19 -0
  54. package/third-party/common/phonemis/src/phonemis/base/processor/{sanitizer_layer.h → layers/sanitizer/layer.h} +8 -8
  55. package/third-party/common/phonemis/src/phonemis/base/processor/layers/sym2word/layer.cpp +65 -0
  56. package/third-party/common/phonemis/src/phonemis/base/processor/layers/sym2word/layer.h +29 -0
  57. package/third-party/common/phonemis/src/phonemis/base/processor/layers/term2word/layer.cpp +170 -0
  58. package/third-party/common/phonemis/src/phonemis/base/processor/layers/term2word/layer.h +40 -0
  59. package/third-party/common/phonemis/src/phonemis/base/processor/layers/term2word/types.h +25 -0
  60. package/third-party/common/phonemis/src/phonemis/base/processor/layers/trim/layer.cpp +47 -0
  61. package/third-party/common/phonemis/src/phonemis/base/processor/layers/trim/layer.h +19 -0
  62. package/third-party/common/phonemis/src/phonemis/base/processor/preprocessor.cpp +60 -0
  63. package/third-party/common/phonemis/src/phonemis/base/processor/preprocessor.h +45 -0
  64. package/third-party/common/phonemis/src/phonemis/base/processor/processor.cpp +6 -7
  65. package/third-party/common/phonemis/src/phonemis/base/processor/processor.h +14 -10
  66. package/third-party/common/phonemis/src/phonemis/base/tagger/hmm_tagger.cpp +89 -52
  67. package/third-party/common/phonemis/src/phonemis/base/tagger/hmm_tagger.h +16 -9
  68. package/third-party/common/phonemis/src/phonemis/base/tokenizer/tokenizer.cpp +13 -12
  69. package/third-party/common/phonemis/src/phonemis/lang/de/constants.h +183 -19
  70. package/third-party/common/phonemis/src/phonemis/lang/de/num2word.cpp +355 -309
  71. package/third-party/common/phonemis/src/phonemis/lang/de/num2word.h +42 -17
  72. package/third-party/common/phonemis/src/phonemis/lang/de/patterns.cpp +56 -0
  73. package/third-party/common/phonemis/src/phonemis/lang/de/patterns.h +15 -0
  74. package/third-party/common/phonemis/src/phonemis/lang/de/pipeline.h +3 -3
  75. package/third-party/common/phonemis/src/phonemis/lang/en/constants.h +181 -30
  76. package/third-party/common/phonemis/src/phonemis/lang/en/hmm_tagger.cpp +5 -7
  77. package/third-party/common/phonemis/src/phonemis/lang/en/num2word.cpp +232 -135
  78. package/third-party/common/phonemis/src/phonemis/lang/en/num2word.h +41 -16
  79. package/third-party/common/phonemis/src/phonemis/lang/en/pipeline.h +3 -10
  80. package/third-party/common/phonemis/src/phonemis/lang/es/constants.h +182 -60
  81. package/third-party/common/phonemis/src/phonemis/lang/es/num2word.cpp +247 -212
  82. package/third-party/common/phonemis/src/phonemis/lang/es/num2word.h +38 -18
  83. package/third-party/common/phonemis/src/phonemis/lang/es/patterns.cpp +50 -0
  84. package/third-party/common/phonemis/src/phonemis/lang/es/patterns.h +15 -0
  85. package/third-party/common/phonemis/src/phonemis/lang/es/pipeline.h +3 -3
  86. package/third-party/common/phonemis/src/phonemis/lang/fr/constants.h +152 -26
  87. package/third-party/common/phonemis/src/phonemis/lang/fr/num2word.cpp +252 -179
  88. package/third-party/common/phonemis/src/phonemis/lang/fr/num2word.h +38 -15
  89. package/third-party/common/phonemis/src/phonemis/lang/fr/patterns.cpp +83 -0
  90. package/third-party/common/phonemis/src/phonemis/lang/fr/patterns.h +15 -0
  91. package/third-party/common/phonemis/src/phonemis/lang/fr/pipeline.h +3 -3
  92. package/third-party/common/phonemis/src/phonemis/lang/hi/constants.h +62 -10
  93. package/third-party/common/phonemis/src/phonemis/lang/hi/num2word.cpp +74 -123
  94. package/third-party/common/phonemis/src/phonemis/lang/hi/num2word.h +27 -16
  95. package/third-party/common/phonemis/src/phonemis/lang/hi/pipeline.h +5 -3
  96. package/third-party/common/phonemis/src/phonemis/lang/it/constants.h +122 -42
  97. package/third-party/common/phonemis/src/phonemis/lang/it/num2word.cpp +200 -207
  98. package/third-party/common/phonemis/src/phonemis/lang/it/num2word.h +30 -18
  99. package/third-party/common/phonemis/src/phonemis/lang/it/patterns.cpp +25 -0
  100. package/third-party/common/phonemis/src/phonemis/lang/it/patterns.h +15 -0
  101. package/third-party/common/phonemis/src/phonemis/lang/it/pipeline.h +3 -3
  102. package/third-party/common/phonemis/src/phonemis/lang/pl/constants.h +346 -77
  103. package/third-party/common/phonemis/src/phonemis/lang/pl/num2word.cpp +631 -246
  104. package/third-party/common/phonemis/src/phonemis/lang/pl/num2word.h +47 -15
  105. package/third-party/common/phonemis/src/phonemis/lang/pl/pipeline.h +6 -6
  106. package/third-party/common/phonemis/src/phonemis/lang/pt/constants.h +201 -0
  107. package/third-party/common/phonemis/src/phonemis/lang/pt/num2word.cpp +365 -0
  108. package/third-party/common/phonemis/src/phonemis/lang/pt/num2word.h +53 -0
  109. package/third-party/common/phonemis/src/phonemis/lang/pt/pipeline.h +4 -2
  110. package/third-party/common/phonemis/src/phonemis/main.cpp +42 -11
  111. package/third-party/common/phonemis/src/phonemis/protophone/meta.h +24 -0
  112. package/third-party/common/phonemis/src/phonemis/protophone/numeric.h +26 -0
  113. package/third-party/common/phonemis/src/phonemis/protophone/protophone.cpp +525 -0
  114. package/third-party/common/phonemis/src/phonemis/protophone/protophone.h +80 -0
  115. package/third-party/common/phonemis/src/phonemis/protophone/tensor.h +76 -0
  116. package/third-party/common/phonemis/src/phonemis/protophone/tensor_utils.h +89 -0
  117. package/third-party/common/phonemis/src/phonemis/protophone/tensor_view.h +125 -0
  118. package/third-party/common/phonemis/src/phonemis/protophone/types.h +43 -0
  119. package/third-party/common/phonemis/src/phonemis/utils/strings.h +20 -14
  120. package/third-party/common/phonemis/src/phonemis/utils/unicode.h +15 -1
  121. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_arithmetic.hpp +267 -0
  122. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_bit.hpp +232 -0
  123. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_cast.hpp +43 -0
  124. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_complex.hpp +112 -0
  125. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_details.hpp +386 -0
  126. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_logical.hpp +240 -0
  127. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_math.hpp +2601 -0
  128. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_memory.hpp +1006 -0
  129. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_rounding.hpp +72 -0
  130. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_swizzle.hpp +260 -0
  131. package/third-party/common/phonemis/src/third-party/xsimd/arch/common/xsimd_common_trigo.hpp +996 -0
  132. package/third-party/common/phonemis/src/third-party/xsimd/arch/utils/shifts.hpp +82 -0
  133. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx.hpp +2111 -0
  134. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx2.hpp +1591 -0
  135. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx2_128.hpp +170 -0
  136. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512bw.hpp +724 -0
  137. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512cd.hpp +28 -0
  138. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512dq.hpp +270 -0
  139. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512er.hpp +17 -0
  140. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512f.hpp +2919 -0
  141. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512ifma.hpp +17 -0
  142. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512pf.hpp +17 -0
  143. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vbmi.hpp +76 -0
  144. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vbmi2.hpp +130 -0
  145. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vnni_avx512bw.hpp +17 -0
  146. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx512vnni_avx512vbmi2.hpp +17 -0
  147. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avx_128.hpp +164 -0
  148. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_avxvnni.hpp +17 -0
  149. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_common.hpp +26 -0
  150. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_common_fwd.hpp +127 -0
  151. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_constants.hpp +393 -0
  152. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_emulated.hpp +787 -0
  153. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma3_avx.hpp +93 -0
  154. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma3_avx2.hpp +46 -0
  155. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma3_sse.hpp +97 -0
  156. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_fma4.hpp +92 -0
  157. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_i8mm_neon64.hpp +17 -0
  158. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_isa.hpp +148 -0
  159. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_neon.hpp +3580 -0
  160. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_neon64.hpp +1614 -0
  161. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_rvv.hpp +1515 -0
  162. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_scalar.hpp +1210 -0
  163. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse2.hpp +2333 -0
  164. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse3.hpp +66 -0
  165. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse4_1.hpp +510 -0
  166. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sse4_2.hpp +44 -0
  167. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_ssse3.hpp +186 -0
  168. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_sve.hpp +1186 -0
  169. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_vsx.hpp +947 -0
  170. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_vxe.hpp +787 -0
  171. package/third-party/common/phonemis/src/third-party/xsimd/arch/xsimd_wasm.hpp +1819 -0
  172. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_arch.hpp +242 -0
  173. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_config.hpp +633 -0
  174. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features.hpp +50 -0
  175. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_arm.hpp +132 -0
  176. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_ppc.hpp +54 -0
  177. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_riscv.hpp +95 -0
  178. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_s390x.hpp +56 -0
  179. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpu_features_x86.hpp +1121 -0
  180. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_cpuid.hpp +144 -0
  181. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_getauxval.hpp +159 -0
  182. package/third-party/common/phonemis/src/third-party/xsimd/config/xsimd_macros.hpp +78 -0
  183. package/third-party/common/phonemis/src/third-party/xsimd/math/xsimd_rem_pio2.hpp +707 -0
  184. package/third-party/common/phonemis/src/third-party/xsimd/memory/xsimd_aligned_allocator.hpp +349 -0
  185. package/third-party/common/phonemis/src/third-party/xsimd/memory/xsimd_alignment.hpp +102 -0
  186. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_all_registers.hpp +57 -0
  187. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_api.hpp +3106 -0
  188. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx2_register.hpp +57 -0
  189. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512bw_register.hpp +51 -0
  190. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512cd_register.hpp +51 -0
  191. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512dq_register.hpp +51 -0
  192. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512er_register.hpp +51 -0
  193. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512f_register.hpp +77 -0
  194. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512ifma_register.hpp +51 -0
  195. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512pf_register.hpp +51 -0
  196. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vbmi2_register.hpp +51 -0
  197. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vbmi_register.hpp +51 -0
  198. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vnni_avx512bw_register.hpp +54 -0
  199. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx512vnni_avx512vbmi2_register.hpp +53 -0
  200. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avx_register.hpp +79 -0
  201. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_avxvnni_register.hpp +44 -0
  202. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_batch.hpp +1666 -0
  203. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_batch_constant.hpp +572 -0
  204. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_batch_fwd.hpp +41 -0
  205. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_common_arch.hpp +49 -0
  206. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_emulated_register.hpp +80 -0
  207. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma3_avx2_register.hpp +50 -0
  208. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma3_avx_register.hpp +50 -0
  209. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma3_sse_register.hpp +50 -0
  210. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_fma4_register.hpp +50 -0
  211. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_i8mm_neon64_register.hpp +55 -0
  212. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_neon64_register.hpp +55 -0
  213. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_neon_register.hpp +130 -0
  214. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_register.hpp +96 -0
  215. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_rvv_register.hpp +491 -0
  216. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse2_register.hpp +59 -0
  217. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse3_register.hpp +49 -0
  218. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse4_1_register.hpp +48 -0
  219. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sse4_2_register.hpp +48 -0
  220. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_ssse3_register.hpp +48 -0
  221. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_sve_register.hpp +216 -0
  222. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_traits.hpp +409 -0
  223. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_utils.hpp +462 -0
  224. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_vsx_register.hpp +84 -0
  225. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_vxe_register.hpp +86 -0
  226. package/third-party/common/phonemis/src/third-party/xsimd/types/xsimd_wasm_register.hpp +59 -0
  227. package/third-party/common/phonemis/src/third-party/xsimd/utils/bits.hpp +122 -0
  228. package/third-party/common/phonemis/src/third-party/xsimd/utils/xsimd_type_traits.hpp +145 -0
  229. package/third-party/common/phonemis/src/third-party/xsimd/xsimd.hpp +43 -0
  230. package/third-party/common/phonemis/src/phonemis/base/processor/constants.h +0 -11
  231. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/config.h +0 -16
  232. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/layer.cpp +0 -271
  233. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/layer.h +0 -45
  234. package/third-party/common/phonemis/src/phonemis/base/processor/num2word/types.h +0 -29
  235. package/third-party/common/phonemis/src/phonemis/base/processor/sanitizer_layer.cpp +0 -22
  236. package/third-party/common/phonemis/src/phonemis/base/processor/trim_layer.cpp +0 -40
  237. package/third-party/common/phonemis/src/phonemis/base/processor/trim_layer.h +0 -22
@@ -0,0 +1,1614 @@
1
+ /***************************************************************************
2
+ * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3
+ * Martin Renou *
4
+ * Copyright (c) QuantStack *
5
+ * Copyright (c) Serge Guelton *
6
+ * *
7
+ * Distributed under the terms of the BSD 3-Clause License. *
8
+ * *
9
+ * The full license is in the file LICENSE, distributed with this software. *
10
+ ****************************************************************************/
11
+
12
+ #ifndef XSIMD_NEON64_HPP
13
+ #define XSIMD_NEON64_HPP
14
+
15
+ #include <cassert>
16
+ #include <complex>
17
+ #include <cstddef>
18
+ #include <cstring>
19
+ #include <utility>
20
+
21
+ #include "../types/xsimd_neon64_register.hpp"
22
+ #include "../types/xsimd_utils.hpp"
23
+ #include "./xsimd_neon.hpp"
24
+
25
+ namespace xsimd
26
+ {
27
+ template <typename T, class A, bool... Values>
28
+ struct batch_bool_constant;
29
+
30
+ namespace kernel
31
+ {
32
+ using namespace types;
33
+
34
+ namespace detail
35
+ {
36
+
37
+ template <class T>
38
+ using enable_neon64_type_t = std::enable_if_t<std::is_integral<T>::value || std::is_same<T, float>::value || std::is_same<T, double>::value,
39
+ int>;
40
+ }
41
+
42
+ // get
43
+ template <class A, size_t I>
44
+ XSIMD_INLINE double get(batch<double, A> const& self, ::xsimd::index<I>, requires_arch<neon64>) noexcept
45
+ {
46
+ return vgetq_lane_f64(self, I);
47
+ }
48
+
49
+ // first
50
+ template <class A>
51
+ XSIMD_INLINE double first(batch<double, A> const& self, requires_arch<neon64>) noexcept
52
+ {
53
+ return vgetq_lane_f64(self, 0);
54
+ }
55
+
56
+ /*******
57
+ * all *
58
+ *******/
59
+
60
+ template <class A, class T, detail::enable_sized_t<T, 4> = 0>
61
+ XSIMD_INLINE bool all(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
62
+ {
63
+ return vminvq_u32(arg) == ~0U;
64
+ }
65
+
66
+ template <class A, class T, detail::enable_sized_t<T, 1> = 0>
67
+ XSIMD_INLINE bool all(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
68
+ {
69
+ return all(batch_bool<uint32_t, A>(vreinterpretq_u32_u8(arg)), neon64 {});
70
+ }
71
+
72
+ template <class A, class T, detail::enable_sized_t<T, 2> = 0>
73
+ XSIMD_INLINE bool all(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
74
+ {
75
+ return all(batch_bool<uint32_t, A>(vreinterpretq_u32_u16(arg)), neon64 {});
76
+ }
77
+
78
+ template <class A, class T, detail::enable_sized_t<T, 8> = 0>
79
+ XSIMD_INLINE bool all(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
80
+ {
81
+ return all(batch_bool<uint32_t, A>(vreinterpretq_u32_u64(arg)), neon64 {});
82
+ }
83
+
84
+ /*******
85
+ * any *
86
+ *******/
87
+
88
+ template <class A, class T, detail::enable_sized_t<T, 4> = 0>
89
+ XSIMD_INLINE bool any(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
90
+ {
91
+ return vmaxvq_u32(arg) != 0;
92
+ }
93
+
94
+ template <class A, class T, detail::enable_sized_t<T, 1> = 0>
95
+ XSIMD_INLINE bool any(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
96
+ {
97
+ return any(batch_bool<uint32_t, A>(vreinterpretq_u32_u8(arg)), neon64 {});
98
+ }
99
+
100
+ template <class A, class T, detail::enable_sized_t<T, 2> = 0>
101
+ XSIMD_INLINE bool any(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
102
+ {
103
+ return any(batch_bool<uint32_t, A>(vreinterpretq_u32_u16(arg)), neon64 {});
104
+ }
105
+
106
+ template <class A, class T, detail::enable_sized_t<T, 8> = 0>
107
+ XSIMD_INLINE bool any(batch_bool<T, A> const& arg, requires_arch<neon64>) noexcept
108
+ {
109
+ return any(batch_bool<uint32_t, A>(vreinterpretq_u32_u64(arg)), neon64 {});
110
+ }
111
+
112
+ /*************
113
+ * broadcast *
114
+ *************/
115
+
116
+ // Required to avoid ambiguous call
117
+ template <class A, class T>
118
+ XSIMD_INLINE batch<T, A> broadcast(T val, requires_arch<neon64>) noexcept
119
+ {
120
+ return broadcast<A>(val, neon {});
121
+ }
122
+
123
+ template <class A>
124
+ XSIMD_INLINE batch<double, A> broadcast(double val, requires_arch<neon64>) noexcept
125
+ {
126
+ return vdupq_n_f64(val);
127
+ }
128
+
129
+ /*************
130
+ * from_bool *
131
+ *************/
132
+
133
+ template <class A>
134
+ XSIMD_INLINE batch<double, A> from_bool(batch_bool<double, A> const& arg, requires_arch<neon64>) noexcept
135
+ {
136
+ return vreinterpretq_f64_u64(vandq_u64(arg, vreinterpretq_u64_f64(vdupq_n_f64(1.))));
137
+ }
138
+
139
+ /********
140
+ * load *
141
+ ********/
142
+ #if defined(__clang__) || defined(__GNUC__)
143
+ #define xsimd_aligned_load(inst, type, expr) inst((type)__builtin_assume_aligned(expr, 16))
144
+ #else
145
+ #define xsimd_aligned_load(inst, type, expr) inst((type)expr)
146
+ #endif
147
+
148
+ template <class A>
149
+ XSIMD_INLINE batch<double, A> load_aligned(double const* src, convert<double>, requires_arch<neon64>) noexcept
150
+ {
151
+ return xsimd_aligned_load(vld1q_f64, double*, src);
152
+ }
153
+
154
+ template <class A>
155
+ XSIMD_INLINE batch<double, A> load_unaligned(double const* src, convert<double>, requires_arch<neon64>) noexcept
156
+ {
157
+ return vld1q_f64(src);
158
+ }
159
+ #undef xsimd_aligned_load
160
+
161
+ /*********
162
+ * store *
163
+ *********/
164
+
165
+ template <class A>
166
+ XSIMD_INLINE void store_aligned(double* dst, batch<double, A> const& src, requires_arch<neon64>) noexcept
167
+ {
168
+ vst1q_f64(dst, src);
169
+ }
170
+
171
+ template <class A>
172
+ XSIMD_INLINE void store_unaligned(double* dst, batch<double, A> const& src, requires_arch<neon64>) noexcept
173
+ {
174
+ return store_aligned<A>(dst, src, A {});
175
+ }
176
+
177
+ /****************
178
+ * store_stream *
179
+ ****************/
180
+
181
+ #if defined(__GNUC__)
182
+ template <class A>
183
+ XSIMD_INLINE void store_stream(float* mem, batch<float, A> const& val, requires_arch<neon64>) noexcept
184
+ {
185
+ float32x2_t lo = vget_low_f32(val);
186
+ float32x2_t hi = vget_high_f32(val);
187
+ __asm__ __volatile__("stnp %d[lo], %d[hi], [%[mem]]"
188
+ :
189
+ : [lo] "w"(lo), [hi] "w"(hi), [mem] "r"(mem)
190
+ : "memory");
191
+ }
192
+
193
+ template <class A>
194
+ XSIMD_INLINE void store_stream(double* mem, batch<double, A> const& val, requires_arch<neon64>) noexcept
195
+ {
196
+ float64x1_t lo = vget_low_f64(val);
197
+ float64x1_t hi = vget_high_f64(val);
198
+ __asm__ __volatile__("stnp %d[lo], %d[hi], [%[mem]]"
199
+ :
200
+ : [lo] "w"(lo), [hi] "w"(hi), [mem] "r"(mem)
201
+ : "memory");
202
+ }
203
+
204
+ template <class A, class T, class = typename std::enable_if<std::is_integral<T>::value, void>::type>
205
+ XSIMD_INLINE void store_stream(T* mem, batch<T, A> const& val, requires_arch<neon64>) noexcept
206
+ {
207
+ uint64x2_t u64;
208
+ std::memcpy(&u64, &val, sizeof(u64));
209
+ uint64x1_t lo = vget_low_u64(u64);
210
+ uint64x1_t hi = vget_high_u64(u64);
211
+ __asm__ __volatile__("stnp %d[lo], %d[hi], [%[mem]]"
212
+ :
213
+ : [lo] "w"(lo), [hi] "w"(hi), [mem] "r"(mem)
214
+ : "memory");
215
+ }
216
+ #endif
217
+
218
+ /***************
219
+ * load_stream *
220
+ ***************/
221
+
222
+ #if defined(__GNUC__)
223
+ template <class A>
224
+ XSIMD_INLINE batch<float, A> load_stream(float const* mem, convert<float>, requires_arch<neon64>) noexcept
225
+ {
226
+ float32x2_t lo, hi;
227
+ __asm__ __volatile__("ldnp %d[lo], %d[hi], [%[mem]]"
228
+ : [lo] "=w"(lo), [hi] "=w"(hi)
229
+ : [mem] "r"(mem)
230
+ : "memory");
231
+ return vcombine_f32(lo, hi);
232
+ }
233
+
234
+ template <class A>
235
+ XSIMD_INLINE batch<double, A> load_stream(double const* mem, convert<double>, requires_arch<neon64>) noexcept
236
+ {
237
+ float64x1_t lo, hi;
238
+ __asm__ __volatile__("ldnp %d[lo], %d[hi], [%[mem]]"
239
+ : [lo] "=w"(lo), [hi] "=w"(hi)
240
+ : [mem] "r"(mem)
241
+ : "memory");
242
+ return vcombine_f64(lo, hi);
243
+ }
244
+
245
+ template <class A, class T, class = typename std::enable_if<std::is_integral<T>::value, void>::type>
246
+ XSIMD_INLINE batch<T, A> load_stream(T const* mem, convert<T>, requires_arch<neon64>) noexcept
247
+ {
248
+ uint64x1_t lo, hi;
249
+ __asm__ __volatile__("ldnp %d[lo], %d[hi], [%[mem]]"
250
+ : [lo] "=w"(lo), [hi] "=w"(hi)
251
+ : [mem] "r"(mem)
252
+ : "memory");
253
+ uint64x2_t u64 = vcombine_u64(lo, hi);
254
+ batch<T, A> result;
255
+ std::memcpy(&result, &u64, sizeof(u64));
256
+ return result;
257
+ }
258
+ #endif
259
+
260
+ /*********************
261
+ * store<batch_bool> *
262
+ *********************/
263
+
264
+ template <class A>
265
+ XSIMD_INLINE void store(batch_bool<double, A> b, bool* mem, requires_arch<neon>) noexcept
266
+ {
267
+ store(batch_bool<uint64_t, A>(b.data), mem, A {});
268
+ }
269
+
270
+ /****************
271
+ * load_complex *
272
+ ****************/
273
+
274
+ template <class A>
275
+ XSIMD_INLINE batch<std::complex<double>, A> load_complex_aligned(std::complex<double> const* mem, convert<std::complex<double>>, requires_arch<neon64>) noexcept
276
+ {
277
+ using real_batch = batch<double, A>;
278
+ const double* buf = reinterpret_cast<const double*>(mem);
279
+ float64x2x2_t tmp = vld2q_f64(buf);
280
+ real_batch real = tmp.val[0],
281
+ imag = tmp.val[1];
282
+ return batch<std::complex<double>, A> { real, imag };
283
+ }
284
+
285
+ template <class A>
286
+ XSIMD_INLINE batch<std::complex<double>, A> load_complex_unaligned(std::complex<double> const* mem, convert<std::complex<double>> cvt, requires_arch<neon64>) noexcept
287
+ {
288
+ return load_complex_aligned<A>(mem, cvt, A {});
289
+ }
290
+
291
+ /*****************
292
+ * store_complex *
293
+ *****************/
294
+
295
+ template <class A>
296
+ XSIMD_INLINE void store_complex_aligned(std::complex<double>* dst, batch<std::complex<double>, A> const& src, requires_arch<neon64>) noexcept
297
+ {
298
+ float64x2x2_t tmp;
299
+ tmp.val[0] = src.real();
300
+ tmp.val[1] = src.imag();
301
+ double* buf = reinterpret_cast<double*>(dst);
302
+ vst2q_f64(buf, tmp);
303
+ }
304
+
305
+ template <class A>
306
+ XSIMD_INLINE void store_complex_unaligned(std::complex<double>* dst, batch<std::complex<double>, A> const& src, requires_arch<neon64>) noexcept
307
+ {
308
+ store_complex_aligned(dst, src, A {});
309
+ }
310
+
311
+ /*******
312
+ * set *
313
+ *******/
314
+
315
+ template <class A>
316
+ XSIMD_INLINE batch<double, A> set(batch<double, A> const&, requires_arch<neon64> req, double d0, double d1) noexcept
317
+ {
318
+ alignas(A::alignment()) double data[] = { d0, d1 };
319
+ return load_aligned<A>(data, {}, req);
320
+ }
321
+
322
+ template <class A>
323
+ XSIMD_INLINE batch_bool<double, A> set(batch_bool<double, A> const&, requires_arch<neon64>, bool b0, bool b1) noexcept
324
+ {
325
+ using unsigned_type = as_unsigned_integer_t<double>;
326
+ auto const out = batch<unsigned_type, A> {
327
+ static_cast<unsigned_type>(b0 ? -1LL : 0LL),
328
+ static_cast<unsigned_type>(b1 ? -1LL : 0LL)
329
+ };
330
+ return { out.data };
331
+ }
332
+
333
+ /*******
334
+ * neg *
335
+ *******/
336
+
337
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
338
+ XSIMD_INLINE batch<T, A> neg(batch<T, A> const& rhs, requires_arch<neon64>) noexcept
339
+ {
340
+ return vreinterpretq_u64_s64(vnegq_s64(vreinterpretq_s64_u64(rhs)));
341
+ }
342
+
343
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
344
+ XSIMD_INLINE batch<T, A> neg(batch<T, A> const& rhs, requires_arch<neon64>) noexcept
345
+ {
346
+ return vnegq_s64(rhs);
347
+ }
348
+
349
+ template <class A>
350
+ XSIMD_INLINE batch<double, A> neg(batch<double, A> const& rhs, requires_arch<neon64>) noexcept
351
+ {
352
+ return vnegq_f64(rhs);
353
+ }
354
+
355
+ /*******
356
+ * add *
357
+ *******/
358
+
359
+ template <class A>
360
+ XSIMD_INLINE batch<double, A> add(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
361
+ {
362
+ return vaddq_f64(lhs, rhs);
363
+ }
364
+
365
+ /********
366
+ * sadd *
367
+ ********/
368
+
369
+ template <class A>
370
+ XSIMD_INLINE batch<double, A> sadd(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
371
+ {
372
+ return add(lhs, rhs, neon64 {});
373
+ }
374
+
375
+ /*******
376
+ * sub *
377
+ *******/
378
+
379
+ template <class A>
380
+ XSIMD_INLINE batch<double, A> sub(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
381
+ {
382
+ return vsubq_f64(lhs, rhs);
383
+ }
384
+
385
+ /********
386
+ * ssub *
387
+ ********/
388
+
389
+ template <class A>
390
+ XSIMD_INLINE batch<double, A> ssub(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
391
+ {
392
+ return sub(lhs, rhs, neon64 {});
393
+ }
394
+
395
+ /*******
396
+ * mul *
397
+ *******/
398
+
399
+ template <class A>
400
+ XSIMD_INLINE batch<double, A> mul(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
401
+ {
402
+ return vmulq_f64(lhs, rhs);
403
+ }
404
+
405
+ /*******
406
+ * div *
407
+ *******/
408
+
409
+ #if defined(XSIMD_FAST_INTEGER_DIVISION)
410
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
411
+ XSIMD_INLINE batch<T, A> div(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
412
+ {
413
+ return vcvtq_u64_f64(vcvtq_f64_u64(lhs) / vcvtq_f64_u64(rhs));
414
+ }
415
+
416
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
417
+ XSIMD_INLINE batch<T, A> div(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
418
+ {
419
+ return vcvtq_s64_f64(vcvtq_f64_s64(lhs) / vcvtq_f64_s64(rhs));
420
+ }
421
+ #endif
422
+ template <class A>
423
+ XSIMD_INLINE batch<double, A> div(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
424
+ {
425
+ return vdivq_f64(lhs, rhs);
426
+ }
427
+
428
+ /******
429
+ * eq *
430
+ ******/
431
+
432
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
433
+ XSIMD_INLINE batch_bool<T, A> eq(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
434
+ {
435
+ return vceqq_u64(lhs, rhs);
436
+ }
437
+
438
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
439
+ XSIMD_INLINE batch_bool<T, A> eq(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
440
+ {
441
+ return vceqq_s64(lhs, rhs);
442
+ }
443
+
444
+ template <class A>
445
+ XSIMD_INLINE batch_bool<double, A> eq(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
446
+ {
447
+ return vceqq_f64(lhs, rhs);
448
+ }
449
+
450
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
451
+ XSIMD_INLINE batch_bool<T, A> eq(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<neon64>) noexcept
452
+ {
453
+ return vceqq_u64(lhs, rhs);
454
+ }
455
+
456
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
457
+ XSIMD_INLINE batch_bool<T, A> eq(batch_bool<T, A> const& lhs, batch_bool<T, A> const& rhs, requires_arch<neon64>) noexcept
458
+ {
459
+ return vceqq_u64(lhs, rhs);
460
+ }
461
+
462
+ template <class A>
463
+ XSIMD_INLINE batch_bool<double, A> eq(batch_bool<double, A> const& lhs, batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
464
+ {
465
+ return vceqq_u64(lhs, rhs);
466
+ }
467
+
468
+ /*************
469
+ * fast_cast *
470
+ *************/
471
+ namespace detail
472
+ {
473
+ template <class A>
474
+ XSIMD_INLINE batch<double, A> fast_cast(batch<int64_t, A> const& x, batch<double, A> const&, requires_arch<neon64>) noexcept
475
+ {
476
+ return vcvtq_f64_s64(x);
477
+ }
478
+
479
+ template <class A>
480
+ XSIMD_INLINE batch<double, A> fast_cast(batch<uint64_t, A> const& x, batch<double, A> const&, requires_arch<neon64>) noexcept
481
+ {
482
+ return vcvtq_f64_u64(x);
483
+ }
484
+
485
+ template <class A>
486
+ XSIMD_INLINE batch<int64_t, A> fast_cast(batch<double, A> const& x, batch<int64_t, A> const&, requires_arch<neon64>) noexcept
487
+ {
488
+ return vcvtq_s64_f64(x);
489
+ }
490
+
491
+ template <class A>
492
+ XSIMD_INLINE batch<uint64_t, A> fast_cast(batch<double, A> const& x, batch<uint64_t, A> const&, requires_arch<neon64>) noexcept
493
+ {
494
+ return vcvtq_u64_f64(x);
495
+ }
496
+
497
+ }
498
+
499
+ /******
500
+ * lt *
501
+ ******/
502
+
503
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
504
+ XSIMD_INLINE batch_bool<T, A> lt(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
505
+ {
506
+ return vcltq_u64(lhs, rhs);
507
+ }
508
+
509
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
510
+ XSIMD_INLINE batch_bool<T, A> lt(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
511
+ {
512
+ return vcltq_s64(lhs, rhs);
513
+ }
514
+
515
+ template <class A>
516
+ XSIMD_INLINE batch_bool<double, A> lt(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
517
+ {
518
+ return vcltq_f64(lhs, rhs);
519
+ }
520
+
521
+ /******
522
+ * le *
523
+ ******/
524
+
525
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
526
+ XSIMD_INLINE batch_bool<T, A> le(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
527
+ {
528
+ return vcleq_u64(lhs, rhs);
529
+ }
530
+
531
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
532
+ XSIMD_INLINE batch_bool<T, A> le(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
533
+ {
534
+ return vcleq_s64(lhs, rhs);
535
+ }
536
+
537
+ template <class A>
538
+ XSIMD_INLINE batch_bool<double, A> le(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
539
+ {
540
+ return vcleq_f64(lhs, rhs);
541
+ }
542
+
543
+ /******
544
+ * gt *
545
+ ******/
546
+
547
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
548
+ XSIMD_INLINE batch_bool<T, A> gt(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
549
+ {
550
+ return vcgtq_u64(lhs, rhs);
551
+ }
552
+
553
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
554
+ XSIMD_INLINE batch_bool<T, A> gt(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
555
+ {
556
+ return vcgtq_s64(lhs, rhs);
557
+ }
558
+
559
+ template <class A>
560
+ XSIMD_INLINE batch_bool<double, A> gt(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
561
+ {
562
+ return vcgtq_f64(lhs, rhs);
563
+ }
564
+
565
+ /******
566
+ * ge *
567
+ ******/
568
+
569
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
570
+ XSIMD_INLINE batch_bool<T, A> ge(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
571
+ {
572
+ return vcgeq_u64(lhs, rhs);
573
+ }
574
+
575
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
576
+ XSIMD_INLINE batch_bool<T, A> ge(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
577
+ {
578
+ return vcgeq_s64(lhs, rhs);
579
+ }
580
+
581
+ template <class A>
582
+ XSIMD_INLINE batch_bool<double, A> ge(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
583
+ {
584
+ return vcgeq_f64(lhs, rhs);
585
+ }
586
+
587
+ /*******************
588
+ * batch_bool_cast *
589
+ *******************/
590
+
591
+ template <class A, class T_out, class T_in>
592
+ XSIMD_INLINE batch_bool<T_out, A> batch_bool_cast(batch_bool<T_in, A> const& self, batch_bool<T_out, A> const&, requires_arch<neon64>) noexcept
593
+ {
594
+ using register_type = typename batch_bool<T_out, A>::register_type;
595
+ return register_type(self);
596
+ }
597
+
598
+ /***************
599
+ * bitwise_and *
600
+ ***************/
601
+
602
+ template <class A>
603
+ XSIMD_INLINE batch<double, A> bitwise_and(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
604
+ {
605
+ return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(lhs),
606
+ vreinterpretq_u64_f64(rhs)));
607
+ }
608
+
609
+ template <class A>
610
+ XSIMD_INLINE batch_bool<double, A> bitwise_and(batch_bool<double, A> const& lhs, batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
611
+ {
612
+ return vandq_u64(lhs, rhs);
613
+ }
614
+
615
+ /**************
616
+ * bitwise_or *
617
+ **************/
618
+
619
+ template <class A>
620
+ XSIMD_INLINE batch<double, A> bitwise_or(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
621
+ {
622
+ return vreinterpretq_f64_u64(vorrq_u64(vreinterpretq_u64_f64(lhs),
623
+ vreinterpretq_u64_f64(rhs)));
624
+ }
625
+
626
+ template <class A>
627
+ XSIMD_INLINE batch_bool<double, A> bitwise_or(batch_bool<double, A> const& lhs, batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
628
+ {
629
+ return vorrq_u64(lhs, rhs);
630
+ }
631
+
632
+ /***************
633
+ * bitwise_xor *
634
+ ***************/
635
+
636
+ template <class A>
637
+ XSIMD_INLINE batch<double, A> bitwise_xor(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
638
+ {
639
+ return vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(lhs),
640
+ vreinterpretq_u64_f64(rhs)));
641
+ }
642
+
643
+ template <class A>
644
+ XSIMD_INLINE batch_bool<double, A> bitwise_xor(batch_bool<double, A> const& lhs, batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
645
+ {
646
+ return veorq_u64(lhs, rhs);
647
+ }
648
+
649
+ /*******
650
+ * neq *
651
+ *******/
652
+
653
+ template <class A>
654
+ XSIMD_INLINE batch_bool<double, A> neq(batch_bool<double, A> const& lhs, batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
655
+ {
656
+ return bitwise_xor(lhs, rhs, A {});
657
+ }
658
+
659
+ /***************
660
+ * bitwise_not *
661
+ ***************/
662
+
663
+ template <class A>
664
+ XSIMD_INLINE batch<double, A> bitwise_not(batch<double, A> const& rhs, requires_arch<neon64>) noexcept
665
+ {
666
+ return vreinterpretq_f64_u32(vmvnq_u32(vreinterpretq_u32_f64(rhs)));
667
+ }
668
+
669
+ template <class A>
670
+ XSIMD_INLINE batch_bool<double, A> bitwise_not(batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
671
+ {
672
+ return vreinterpretq_u64_u32(vmvnq_u32(vreinterpretq_u32_u64(rhs)));
673
+ }
674
+
675
+ /******************
676
+ * bitwise_andnot *
677
+ ******************/
678
+
679
+ template <class A>
680
+ XSIMD_INLINE batch<double, A> bitwise_andnot(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
681
+ {
682
+ return vreinterpretq_f64_u64(vbicq_u64(vreinterpretq_u64_f64(lhs),
683
+ vreinterpretq_u64_f64(rhs)));
684
+ }
685
+
686
+ template <class A>
687
+ XSIMD_INLINE batch_bool<double, A> bitwise_andnot(batch_bool<double, A> const& lhs, batch_bool<double, A> const& rhs, requires_arch<neon64>) noexcept
688
+ {
689
+ return vbicq_u64(lhs, rhs);
690
+ }
691
+
692
+ /*******
693
+ * min *
694
+ *******/
695
+
696
+ template <class A>
697
+ XSIMD_INLINE batch<double, A> min(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
698
+ {
699
+ return vminq_f64(lhs, rhs);
700
+ }
701
+
702
+ /*******
703
+ * max *
704
+ *******/
705
+
706
+ template <class A>
707
+ XSIMD_INLINE batch<double, A> max(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
708
+ {
709
+ return vmaxq_f64(lhs, rhs);
710
+ }
711
+
712
+ /********
713
+ * mask *
714
+ ********/
715
+
716
+ template <class A, class T, detail::enable_sized_t<T, 1> = 0>
717
+ XSIMD_INLINE uint64_t mask(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
718
+ {
719
+ // From https://github.com/DLTcollab/sse2neon/blob/master/sse2neon.h
720
+ // Extract most significant bit
721
+ uint8x16_t msbs = vshrq_n_u8(self, 7);
722
+ // Position it appropriately
723
+ static constexpr int8_t shift_table[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 };
724
+ int8x16_t shifts = vld1q_s8(shift_table);
725
+ uint8x16_t positioned = vshlq_u8(msbs, shifts);
726
+ // Horizontal reduction
727
+ return vaddv_u8(vget_low_u8(positioned)) | (vaddv_u8(vget_high_u8(positioned)) << 8);
728
+ }
729
+
730
+ template <class A, class T, detail::enable_sized_t<T, 2> = 0>
731
+ XSIMD_INLINE uint64_t mask(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
732
+ {
733
+ // Extract most significant bit
734
+ uint16x8_t msbs = vshrq_n_u16(self, 15);
735
+ // Position it appropriately
736
+ static constexpr int16_t shift_table[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
737
+ int16x8_t shifts = vld1q_s16(shift_table);
738
+ uint16x8_t positioned = vshlq_u16(msbs, shifts);
739
+ // Horizontal reduction
740
+ return vaddvq_u16(positioned);
741
+ }
742
+
743
+ template <class A, class T, detail::enable_sized_t<T, 4> = 0>
744
+ XSIMD_INLINE uint64_t mask(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
745
+ {
746
+ // Extract most significant bit
747
+ uint32x4_t msbs = vshrq_n_u32(self, 31);
748
+ // Position it appropriately
749
+ static constexpr int32_t shift_table[4] = { 0, 1, 2, 3 };
750
+ int32x4_t shifts = vld1q_s32(shift_table);
751
+ uint32x4_t positioned = vshlq_u32(msbs, shifts);
752
+ // Horizontal reduction
753
+ return vaddvq_u32(positioned);
754
+ }
755
+
756
+ /*********
757
+ * count *
758
+ *********/
759
+ template <class A, class T, detail::enable_sized_t<T, 1> = 0>
760
+ XSIMD_INLINE size_t count(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
761
+ {
762
+ return vaddvq_u8(vshrq_n_u8(self, 7));
763
+ }
764
+
765
+ template <class A, class T, detail::enable_sized_t<T, 2> = 0>
766
+ XSIMD_INLINE size_t count(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
767
+ {
768
+ return vaddvq_u16(vshrq_n_u16(self, 15));
769
+ }
770
+
771
+ template <class A, class T, detail::enable_sized_t<T, 4> = 0>
772
+ XSIMD_INLINE size_t count(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
773
+ {
774
+ return vaddvq_u32(vshrq_n_u32(self, 31));
775
+ }
776
+
777
+ template <class A, class T, detail::enable_sized_t<T, 8> = 0>
778
+ XSIMD_INLINE size_t count(batch_bool<T, A> const& self, requires_arch<neon64>) noexcept
779
+ {
780
+ return vaddvq_u64(vshrq_n_u64(self, 63));
781
+ }
782
+
783
+ /*******
784
+ * abs *
785
+ *******/
786
+
787
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
788
+ XSIMD_INLINE batch<T, A> abs(batch<T, A> const& rhs, requires_arch<neon64>) noexcept
789
+ {
790
+ return rhs;
791
+ }
792
+
793
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
794
+ XSIMD_INLINE batch<T, A> abs(batch<T, A> const& rhs, requires_arch<neon64>) noexcept
795
+ {
796
+ return vabsq_s64(rhs);
797
+ }
798
+
799
+ template <class A>
800
+ XSIMD_INLINE batch<double, A> abs(batch<double, A> const& rhs, requires_arch<neon64>) noexcept
801
+ {
802
+ return vabsq_f64(rhs);
803
+ }
804
+
805
+ template <class A>
806
+ XSIMD_INLINE batch<int32_t, A> nearbyint_as_int(batch<float, A> const& self,
807
+ requires_arch<neon64>) noexcept
808
+ {
809
+ return vcvtnq_s32_f32(self);
810
+ }
811
+
812
+ #if !defined(__GNUC__)
813
+ template <class A>
814
+ XSIMD_INLINE batch<int64_t, A> nearbyint_as_int(batch<double, A> const& self,
815
+ requires_arch<neon64>) noexcept
816
+ {
817
+ return vcvtnq_s64_f64(self);
818
+ }
819
+ #endif
820
+
821
+ /**************
822
+ * reciprocal *
823
+ **************/
824
+
825
+ template <class A>
826
+ XSIMD_INLINE batch<double, A>
827
+ reciprocal(const batch<double, A>& x,
828
+ kernel::requires_arch<neon64>) noexcept
829
+ {
830
+ return vrecpeq_f64(x);
831
+ }
832
+
833
+ /********
834
+ * rsqrt *
835
+ ********/
836
+
837
+ template <class A>
838
+ XSIMD_INLINE batch<double, A> rsqrt(batch<double, A> const& rhs, requires_arch<neon64>) noexcept
839
+ {
840
+ return vrsqrteq_f64(rhs);
841
+ }
842
+
843
+ /********
844
+ * sqrt *
845
+ ********/
846
+
847
+ template <class A>
848
+ XSIMD_INLINE batch<double, A> sqrt(batch<double, A> const& rhs, requires_arch<neon64>) noexcept
849
+ {
850
+ return vsqrtq_f64(rhs);
851
+ }
852
+
853
+ /********************
854
+ * Fused operations *
855
+ ********************/
856
+
857
+ #ifdef __ARM_FEATURE_FMA
858
+ template <class A>
859
+ XSIMD_INLINE batch<double, A> fma(batch<double, A> const& x, batch<double, A> const& y, batch<double, A> const& z, requires_arch<neon64>) noexcept
860
+ {
861
+ return vfmaq_f64(z, x, y);
862
+ }
863
+
864
+ template <class A>
865
+ XSIMD_INLINE batch<double, A> fms(batch<double, A> const& x, batch<double, A> const& y, batch<double, A> const& z, requires_arch<neon64>) noexcept
866
+ {
867
+ return vfmaq_f64(-z, x, y);
868
+ }
869
+ #endif
870
+
871
+ /*********
872
+ * haddp *
873
+ *********/
874
+
875
+ template <class A>
876
+ XSIMD_INLINE batch<double, A> haddp(const batch<double, A>* row, requires_arch<neon64>) noexcept
877
+ {
878
+ return vpaddq_f64(row[0], row[1]);
879
+ }
880
+
881
+ /**********
882
+ * insert *
883
+ **********/
884
+
885
+ template <class A, size_t I>
886
+ XSIMD_INLINE batch<double, A> insert(batch<double, A> const& self, double val, index<I>, requires_arch<neon64>) noexcept
887
+ {
888
+ return vsetq_lane_f64(val, self, I);
889
+ }
890
+
891
+ /**************
892
+ * reduce_add *
893
+ **************/
894
+
895
+ namespace wrap
896
+ {
897
+ // TODO(c++17): Make a single function with if constexpr switch
898
+ // Templating on the scalar type `T` is required because in some compilers (e.g. MSVC)
899
+ // the vector types are all aliases of the same type.
900
+ template <class T, std::enable_if_t<std::is_same<T, uint8_t>::value, int> = 0>
901
+ XSIMD_INLINE uint8_t x_vaddvq(uint8x16_t a) noexcept { return vaddvq_u8(a); }
902
+ template <class T, std::enable_if_t<std::is_same<T, int8_t>::value, int> = 0>
903
+ XSIMD_INLINE int8_t x_vaddvq(int8x16_t a) noexcept { return vaddvq_s8(a); }
904
+ template <class T, std::enable_if_t<std::is_same<T, uint16_t>::value, int> = 0>
905
+ XSIMD_INLINE uint16_t x_vaddvq(uint16x8_t a) noexcept { return vaddvq_u16(a); }
906
+ template <class T, std::enable_if_t<std::is_same<T, int16_t>::value, int> = 0>
907
+ XSIMD_INLINE int16_t x_vaddvq(int16x8_t a) noexcept { return vaddvq_s16(a); }
908
+ template <class T, std::enable_if_t<std::is_same<T, uint32_t>::value, int> = 0>
909
+ XSIMD_INLINE uint32_t x_vaddvq(uint32x4_t a) noexcept { return vaddvq_u32(a); }
910
+ template <class T, std::enable_if_t<std::is_same<T, int32_t>::value, int> = 0>
911
+ XSIMD_INLINE int32_t x_vaddvq(int32x4_t a) noexcept { return vaddvq_s32(a); }
912
+ template <class T, std::enable_if_t<std::is_same<T, uint64_t>::value, int> = 0>
913
+ XSIMD_INLINE uint64_t x_vaddvq(uint64x2_t a) noexcept { return vaddvq_u64(a); }
914
+ template <class T, std::enable_if_t<std::is_same<T, int64_t>::value, int> = 0>
915
+ XSIMD_INLINE int64_t x_vaddvq(int64x2_t a) noexcept { return vaddvq_s64(a); }
916
+ template <class T, std::enable_if_t<std::is_same<T, float>::value, int> = 0>
917
+ XSIMD_INLINE float x_vaddvq(float32x4_t a) noexcept { return vaddvq_f32(a); }
918
+ template <class T, std::enable_if_t<std::is_same<T, double>::value, int> = 0>
919
+ XSIMD_INLINE double x_vaddvq(float64x2_t a) noexcept { return vaddvq_f64(a); }
920
+ }
921
+
922
+ template <class A, class T, detail::enable_neon64_type_t<T> = 0>
923
+ XSIMD_INLINE typename batch<T, A>::value_type reduce_add(batch<T, A> const& arg, requires_arch<neon64>) noexcept
924
+ {
925
+ using register_type = typename batch<T, A>::register_type;
926
+ return wrap::x_vaddvq<T>(register_type(arg));
927
+ }
928
+
929
+ /**************
930
+ * reduce_max *
931
+ **************/
932
+
933
+ namespace wrap
934
+ {
935
+ // TODO(c++17): Make a single function with if constexpr switch
936
+ // Templating on the scalar type `T` is required because in some compilers (e.g. MSVC)
937
+ // the vector types are all aliases of the same type.
938
+ template <class T, std::enable_if_t<std::is_same<T, uint8_t>::value, int> = 0>
939
+ XSIMD_INLINE uint8_t x_vmaxvq(uint8x16_t a) noexcept { return vmaxvq_u8(a); }
940
+ template <class T, std::enable_if_t<std::is_same<T, int8_t>::value, int> = 0>
941
+ XSIMD_INLINE int8_t x_vmaxvq(int8x16_t a) noexcept { return vmaxvq_s8(a); }
942
+ template <class T, std::enable_if_t<std::is_same<T, uint16_t>::value, int> = 0>
943
+ XSIMD_INLINE uint16_t x_vmaxvq(uint16x8_t a) noexcept { return vmaxvq_u16(a); }
944
+ template <class T, std::enable_if_t<std::is_same<T, int16_t>::value, int> = 0>
945
+ XSIMD_INLINE int16_t x_vmaxvq(int16x8_t a) noexcept { return vmaxvq_s16(a); }
946
+ template <class T, std::enable_if_t<std::is_same<T, uint32_t>::value, int> = 0>
947
+ XSIMD_INLINE uint32_t x_vmaxvq(uint32x4_t a) noexcept { return vmaxvq_u32(a); }
948
+ template <class T, std::enable_if_t<std::is_same<T, int32_t>::value, int> = 0>
949
+ XSIMD_INLINE int32_t x_vmaxvq(int32x4_t a) noexcept { return vmaxvq_s32(a); }
950
+ template <class T, std::enable_if_t<std::is_same<T, float>::value, int> = 0>
951
+ XSIMD_INLINE float x_vmaxvq(float32x4_t a) noexcept { return vmaxvq_f32(a); }
952
+ template <class T, std::enable_if_t<std::is_same<T, double>::value, int> = 0>
953
+ XSIMD_INLINE double x_vmaxvq(float64x2_t a) noexcept { return vmaxvq_f64(a); }
954
+
955
+ template <class T, std::enable_if_t<std::is_same<T, uint64_t>::value, int> = 0>
956
+ XSIMD_INLINE uint64_t x_vmaxvq(uint64x2_t a) noexcept
957
+ {
958
+ return std::max(vdupd_laneq_u64(a, 0), vdupd_laneq_u64(a, 1));
959
+ }
960
+ template <class T, std::enable_if_t<std::is_same<T, int64_t>::value, int> = 0>
961
+ XSIMD_INLINE int64_t x_vmaxvq(int64x2_t a) noexcept
962
+ {
963
+ return std::max(vdupd_laneq_s64(a, 0), vdupd_laneq_s64(a, 1));
964
+ }
965
+ }
966
+
967
+ template <class A, class T, detail::enable_neon64_type_t<T> = 0>
968
+ XSIMD_INLINE typename batch<T, A>::value_type reduce_max(batch<T, A> const& arg, requires_arch<neon64>) noexcept
969
+ {
970
+ using register_type = typename batch<T, A>::register_type;
971
+ return wrap::x_vmaxvq<T>(register_type(arg));
972
+ }
973
+
974
+ /**************
975
+ * reduce_min *
976
+ **************/
977
+
978
+ namespace wrap
979
+ {
980
+ // TODO(c++17): Make a single function with if constexpr switch
981
+ // Templating on the scalar type `T` is required because in some compilers (e.g. MSVC)
982
+ // the vector types are all aliases of the same type.
983
+ template <class T, std::enable_if_t<std::is_same<T, uint8_t>::value, int> = 0>
984
+ XSIMD_INLINE uint8_t x_vminvq(uint8x16_t a) noexcept { return vminvq_u8(a); }
985
+ template <class T, std::enable_if_t<std::is_same<T, int8_t>::value, int> = 0>
986
+ XSIMD_INLINE int8_t x_vminvq(int8x16_t a) noexcept { return vminvq_s8(a); }
987
+ template <class T, std::enable_if_t<std::is_same<T, uint16_t>::value, int> = 0>
988
+ XSIMD_INLINE uint16_t x_vminvq(uint16x8_t a) noexcept { return vminvq_u16(a); }
989
+ template <class T, std::enable_if_t<std::is_same<T, int16_t>::value, int> = 0>
990
+ XSIMD_INLINE int16_t x_vminvq(int16x8_t a) noexcept { return vminvq_s16(a); }
991
+ template <class T, std::enable_if_t<std::is_same<T, uint32_t>::value, int> = 0>
992
+ XSIMD_INLINE uint32_t x_vminvq(uint32x4_t a) noexcept { return vminvq_u32(a); }
993
+ template <class T, std::enable_if_t<std::is_same<T, int32_t>::value, int> = 0>
994
+ XSIMD_INLINE int32_t x_vminvq(int32x4_t a) noexcept { return vminvq_s32(a); }
995
+ template <class T, std::enable_if_t<std::is_same<T, float>::value, int> = 0>
996
+ XSIMD_INLINE float x_vminvq(float32x4_t a) noexcept { return vminvq_f32(a); }
997
+ template <class T, std::enable_if_t<std::is_same<T, double>::value, int> = 0>
998
+ XSIMD_INLINE double x_vminvq(float64x2_t a) noexcept { return vminvq_f64(a); }
999
+
1000
+ template <class T, std::enable_if_t<std::is_same<T, uint64_t>::value, int> = 0>
1001
+ XSIMD_INLINE uint64_t x_vminvq(uint64x2_t a) noexcept
1002
+ {
1003
+ return std::min(vdupd_laneq_u64(a, 0), vdupd_laneq_u64(a, 1));
1004
+ }
1005
+ template <class T, std::enable_if_t<std::is_same<T, int64_t>::value, int> = 0>
1006
+ XSIMD_INLINE int64_t x_vminvq(int64x2_t a) noexcept
1007
+ {
1008
+ return std::min(vdupd_laneq_s64(a, 0), vdupd_laneq_s64(a, 1));
1009
+ }
1010
+ }
1011
+
1012
+ template <class A, class T, detail::enable_neon64_type_t<T> = 0>
1013
+ XSIMD_INLINE typename batch<T, A>::value_type reduce_min(batch<T, A> const& arg, requires_arch<neon64>) noexcept
1014
+ {
1015
+ using register_type = typename batch<T, A>::register_type;
1016
+ return wrap::x_vminvq<T>(register_type(arg));
1017
+ }
1018
+
1019
+ /**********
1020
+ * select *
1021
+ **********/
1022
+
1023
+ template <class A>
1024
+ XSIMD_INLINE batch<double, A> select(batch_bool<double, A> const& cond, batch<double, A> const& a, batch<double, A> const& b, requires_arch<neon64>) noexcept
1025
+ {
1026
+ return vbslq_f64(cond, a, b);
1027
+ }
1028
+
1029
+ template <class A, bool... b>
1030
+ XSIMD_INLINE batch<double, A> select(batch_bool_constant<double, A, b...> const&,
1031
+ batch<double, A> const& true_br,
1032
+ batch<double, A> const& false_br,
1033
+ requires_arch<neon64>) noexcept
1034
+ {
1035
+ return select(batch_bool<double, A> { b... }, true_br, false_br, neon64 {});
1036
+ }
1037
+
1038
+ template <class A>
1039
+ XSIMD_INLINE void transpose(batch<double, A>* matrix_begin, batch<double, A>* matrix_end, requires_arch<neon64>) noexcept
1040
+ {
1041
+ assert((matrix_end - matrix_begin == batch<double, A>::size) && "correctly sized matrix");
1042
+ (void)matrix_end;
1043
+ auto r0 = matrix_begin[0], r1 = matrix_begin[1];
1044
+ matrix_begin[0] = vzip1q_f64(r0, r1);
1045
+ matrix_begin[1] = vzip2q_f64(r0, r1);
1046
+ }
1047
+
1048
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
1049
+ XSIMD_INLINE void transpose(batch<T, A>* matrix_begin, batch<T, A>* matrix_end, requires_arch<neon64>) noexcept
1050
+ {
1051
+ assert((matrix_end - matrix_begin == batch<T, A>::size) && "correctly sized matrix");
1052
+ (void)matrix_end;
1053
+ auto r0 = matrix_begin[0], r1 = matrix_begin[1];
1054
+ matrix_begin[0] = vzip1q_u64(r0, r1);
1055
+ matrix_begin[1] = vzip2q_u64(r0, r1);
1056
+ }
1057
+
1058
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
1059
+ XSIMD_INLINE void transpose(batch<T, A>* matrix_begin, batch<T, A>* matrix_end, requires_arch<neon64>) noexcept
1060
+ {
1061
+ assert((matrix_end - matrix_begin == batch<T, A>::size) && "correctly sized matrix");
1062
+ (void)matrix_end;
1063
+ auto r0 = matrix_begin[0], r1 = matrix_begin[1];
1064
+ matrix_begin[0] = vzip1q_s64(r0, r1);
1065
+ matrix_begin[1] = vzip2q_s64(r0, r1);
1066
+ }
1067
+
1068
+ /**********
1069
+ * zip_lo *
1070
+ **********/
1071
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 1> = 0>
1072
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1073
+ {
1074
+ return vzip1q_u8(lhs, rhs);
1075
+ }
1076
+
1077
+ template <class A, class T, detail::enable_sized_signed_t<T, 1> = 0>
1078
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1079
+ {
1080
+ return vzip1q_s8(lhs, rhs);
1081
+ }
1082
+
1083
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 2> = 0>
1084
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1085
+ {
1086
+ return vzip1q_u16(lhs, rhs);
1087
+ }
1088
+
1089
+ template <class A, class T, detail::enable_sized_signed_t<T, 2> = 0>
1090
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1091
+ {
1092
+ return vzip1q_s16(lhs, rhs);
1093
+ }
1094
+
1095
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 4> = 0>
1096
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1097
+ {
1098
+ return vzip1q_u32(lhs, rhs);
1099
+ }
1100
+
1101
+ template <class A, class T, detail::enable_sized_signed_t<T, 4> = 0>
1102
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1103
+ {
1104
+ return vzip1q_s32(lhs, rhs);
1105
+ }
1106
+
1107
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
1108
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1109
+ {
1110
+ return vzip1q_u64(lhs, rhs);
1111
+ }
1112
+
1113
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
1114
+ XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1115
+ {
1116
+ return vzip1q_s64(lhs, rhs);
1117
+ }
1118
+
1119
+ template <class A>
1120
+ XSIMD_INLINE batch<float, A> zip_lo(batch<float, A> const& lhs, batch<float, A> const& rhs, requires_arch<neon64>) noexcept
1121
+ {
1122
+ return vzip1q_f32(lhs, rhs);
1123
+ }
1124
+
1125
+ template <class A>
1126
+ XSIMD_INLINE batch<double, A> zip_lo(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
1127
+ {
1128
+ return vzip1q_f64(lhs, rhs);
1129
+ }
1130
+
1131
+ /**********
1132
+ * zip_hi *
1133
+ **********/
1134
+
1135
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 1> = 0>
1136
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1137
+ {
1138
+ return vzip2q_u8(lhs, rhs);
1139
+ }
1140
+
1141
+ template <class A, class T, detail::enable_sized_signed_t<T, 1> = 0>
1142
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1143
+ {
1144
+ return vzip2q_s8(lhs, rhs);
1145
+ }
1146
+
1147
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 2> = 0>
1148
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1149
+ {
1150
+ return vzip2q_u16(lhs, rhs);
1151
+ }
1152
+
1153
+ template <class A, class T, detail::enable_sized_signed_t<T, 2> = 0>
1154
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1155
+ {
1156
+ return vzip2q_s16(lhs, rhs);
1157
+ }
1158
+
1159
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 4> = 0>
1160
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1161
+ {
1162
+ return vzip2q_u32(lhs, rhs);
1163
+ }
1164
+
1165
+ template <class A, class T, detail::enable_sized_signed_t<T, 4> = 0>
1166
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1167
+ {
1168
+ return vzip2q_s32(lhs, rhs);
1169
+ }
1170
+
1171
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
1172
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1173
+ {
1174
+ return vzip2q_u64(lhs, rhs);
1175
+ }
1176
+
1177
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
1178
+ XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1179
+ {
1180
+ return vzip2q_s64(lhs, rhs);
1181
+ }
1182
+
1183
+ template <class A>
1184
+ XSIMD_INLINE batch<float, A> zip_hi(batch<float, A> const& lhs, batch<float, A> const& rhs, requires_arch<neon64>) noexcept
1185
+ {
1186
+ return vzip2q_f32(lhs, rhs);
1187
+ }
1188
+
1189
+ template <class A>
1190
+ XSIMD_INLINE batch<double, A> zip_hi(batch<double, A> const& lhs, batch<double, A> const& rhs, requires_arch<neon64>) noexcept
1191
+ {
1192
+ return vzip2q_f64(lhs, rhs);
1193
+ }
1194
+
1195
+ /****************
1196
+ * extract_pair *
1197
+ ****************/
1198
+
1199
+ namespace detail
1200
+ {
1201
+ template <class A, size_t I, size_t... Is>
1202
+ XSIMD_INLINE batch<double, A> extract_pair(batch<double, A> const& lhs, batch<double, A> const& rhs, std::size_t n,
1203
+ std::index_sequence<I, Is...>) noexcept
1204
+ {
1205
+ if (n == I)
1206
+ {
1207
+ return vextq_f64(rhs, lhs, I);
1208
+ }
1209
+ else
1210
+ {
1211
+ return extract_pair(lhs, rhs, n, std::index_sequence<Is...>());
1212
+ }
1213
+ }
1214
+ }
1215
+
1216
+ template <class A>
1217
+ XSIMD_INLINE batch<double, A> extract_pair(batch<double, A> const& lhs, batch<double, A> const& rhs, std::size_t n, requires_arch<neon64>) noexcept
1218
+ {
1219
+ constexpr std::size_t size = batch<double, A>::size;
1220
+ assert(n < size && "index in bounds");
1221
+ return detail::extract_pair(lhs, rhs, n, std::make_index_sequence<size>());
1222
+ }
1223
+
1224
+ /******************
1225
+ * bitwise_rshift *
1226
+ ******************/
1227
+
1228
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
1229
+ XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& lhs, int n, requires_arch<neon64>) noexcept
1230
+ {
1231
+ return bitwise_rshift<A>(lhs, n, neon {});
1232
+ }
1233
+
1234
+ template <class A, class T, detail::enable_sized_unsigned_t<T, 8> = 0>
1235
+ XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1236
+ {
1237
+ // Blindly converting to signed since out of bounds shifts are UB anyways
1238
+ assert(detail::shifts_all_positive(rhs));
1239
+ return vshlq_u64(lhs, vnegq_s64(vreinterpretq_s64_u64(rhs)));
1240
+ }
1241
+
1242
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
1243
+ XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& lhs, int n, requires_arch<neon64>) noexcept
1244
+ {
1245
+ return bitwise_rshift<A>(lhs, n, neon {});
1246
+ }
1247
+
1248
+ template <class A, class T, detail::enable_sized_signed_t<T, 8> = 0>
1249
+ XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& lhs, batch<T, A> const& rhs, requires_arch<neon64>) noexcept
1250
+ {
1251
+ return vshlq_s64(lhs, vnegq_s64(rhs));
1252
+ }
1253
+
1254
+ /****************
1255
+ * bitwise_cast *
1256
+ ****************/
1257
+
1258
+ namespace wrap
1259
+ {
1260
+ // TODO(c++17): Make a single function with if constexpr switch
1261
+ // Templating on the scalar type `T` is required because in some compilers (e.g. MSVC)
1262
+ // the vector types are all aliases of the same type.
1263
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, uint8_t>::value, int> = 0>
1264
+ XSIMD_INLINE float64x2_t x_vreinterpretq(uint8x16_t a) noexcept { return vreinterpretq_f64_u8(a); }
1265
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, int8_t>::value, int> = 0>
1266
+ XSIMD_INLINE float64x2_t x_vreinterpretq(int8x16_t a) noexcept { return vreinterpretq_f64_s8(a); }
1267
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, uint16_t>::value, int> = 0>
1268
+ XSIMD_INLINE float64x2_t x_vreinterpretq(uint16x8_t a) noexcept { return vreinterpretq_f64_u16(a); }
1269
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, int16_t>::value, int> = 0>
1270
+ XSIMD_INLINE float64x2_t x_vreinterpretq(int16x8_t a) noexcept { return vreinterpretq_f64_s16(a); }
1271
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, uint32_t>::value, int> = 0>
1272
+ XSIMD_INLINE float64x2_t x_vreinterpretq(uint32x4_t a) noexcept { return vreinterpretq_f64_u32(a); }
1273
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, int32_t>::value, int> = 0>
1274
+ XSIMD_INLINE float64x2_t x_vreinterpretq(int32x4_t a) noexcept { return vreinterpretq_f64_s32(a); }
1275
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, uint64_t>::value, int> = 0>
1276
+ XSIMD_INLINE float64x2_t x_vreinterpretq(uint64x2_t a) noexcept { return vreinterpretq_f64_u64(a); }
1277
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, int64_t>::value, int> = 0>
1278
+ XSIMD_INLINE float64x2_t x_vreinterpretq(int64x2_t a) noexcept { return vreinterpretq_f64_s64(a); }
1279
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, float>::value, int> = 0>
1280
+ XSIMD_INLINE float64x2_t x_vreinterpretq(float32x4_t a) noexcept { return vreinterpretq_f64_f32(a); }
1281
+ template <class R, class T, std::enable_if_t<std::is_same<R, double>::value && std::is_same<T, double>::value, int> = 0>
1282
+ XSIMD_INLINE float64x2_t x_vreinterpretq(float64x2_t a) noexcept { return a; }
1283
+
1284
+ // TODO(c++17): Make a single function with if constexpr switch
1285
+ // Templating on the scalar type `T` is required because in some compilers (e.g. MSVC)
1286
+ // the vector types are all aliases of the same type.
1287
+ template <class R, class T, std::enable_if_t<std::is_same<R, uint8_t>::value && std::is_same<T, double>::value, int> = 0>
1288
+ XSIMD_INLINE uint8x16_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_u8_f64(a); }
1289
+ template <class R, class T, std::enable_if_t<std::is_same<R, int8_t>::value && std::is_same<T, double>::value, int> = 0>
1290
+ XSIMD_INLINE int8x16_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_s8_f64(a); }
1291
+ template <class R, class T, std::enable_if_t<std::is_same<R, uint16_t>::value && std::is_same<T, double>::value, int> = 0>
1292
+ XSIMD_INLINE uint16x8_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_u16_f64(a); }
1293
+ template <class R, class T, std::enable_if_t<std::is_same<R, int16_t>::value && std::is_same<T, double>::value, int> = 0>
1294
+ XSIMD_INLINE int16x8_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_s16_f64(a); }
1295
+ template <class R, class T, std::enable_if_t<std::is_same<R, uint32_t>::value && std::is_same<T, double>::value, int> = 0>
1296
+ XSIMD_INLINE uint32x4_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_u32_f64(a); }
1297
+ template <class R, class T, std::enable_if_t<std::is_same<R, int32_t>::value && std::is_same<T, double>::value, int> = 0>
1298
+ XSIMD_INLINE int32x4_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_s32_f64(a); }
1299
+ template <class R, class T, std::enable_if_t<std::is_same<R, uint64_t>::value && std::is_same<T, double>::value, int> = 0>
1300
+ XSIMD_INLINE uint64x2_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_u64_f64(a); }
1301
+ template <class R, class T, std::enable_if_t<std::is_same<R, int64_t>::value && std::is_same<T, double>::value, int> = 0>
1302
+ XSIMD_INLINE int64x2_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_s64_f64(a); }
1303
+ template <class R, class T, std::enable_if_t<std::is_same<R, float>::value && std::is_same<T, double>::value, int> = 0>
1304
+ XSIMD_INLINE float32x4_t x_vreinterpretq(float64x2_t a) noexcept { return vreinterpretq_f32_f64(a); }
1305
+
1306
+ }
1307
+
1308
+ template <class A, class T>
1309
+ XSIMD_INLINE batch<double, A> bitwise_cast(batch<T, A> const& arg, batch<double, A> const&, requires_arch<neon64>) noexcept
1310
+ {
1311
+ using register_type = typename batch<T, A>::register_type;
1312
+ return wrap::x_vreinterpretq<double, map_to_sized_type_t<T>>(register_type(arg));
1313
+ }
1314
+
1315
+ template <class A, class R>
1316
+ XSIMD_INLINE batch<R, A> bitwise_cast(batch<double, A> const& arg, batch<R, A> const&, requires_arch<neon64>) noexcept
1317
+ {
1318
+ using src_register_type = typename batch<double, A>::register_type;
1319
+ return wrap::x_vreinterpretq<map_to_sized_type_t<R>, double>(src_register_type(arg));
1320
+ }
1321
+
1322
+ template <class A>
1323
+ XSIMD_INLINE batch<double, A> bitwise_cast(batch<double, A> const& arg, batch<double, A> const&, requires_arch<neon64>) noexcept
1324
+ {
1325
+ return arg;
1326
+ }
1327
+
1328
+ /*********
1329
+ * isnan *
1330
+ *********/
1331
+
1332
+ template <class A>
1333
+ XSIMD_INLINE batch_bool<double, A> isnan(batch<double, A> const& arg, requires_arch<neon64>) noexcept
1334
+ {
1335
+ return !(arg == arg);
1336
+ }
1337
+
1338
+ /****************
1339
+ * rotate_left *
1340
+ ****************/
1341
+ template <size_t N, class A>
1342
+ XSIMD_INLINE batch<double, A> rotate_left(batch<double, A> const& a, requires_arch<neon64>) noexcept
1343
+ {
1344
+ return vextq_f64(a, a, N);
1345
+ }
1346
+ }
1347
+
1348
+ template <typename T, class A, T... Values>
1349
+ struct batch_constant;
1350
+
1351
+ namespace kernel
1352
+ {
1353
+ /*********************
1354
+ * swizzle (dynamic) *
1355
+ *********************/
1356
+ template <class A>
1357
+ XSIMD_INLINE batch<uint8_t, A> swizzle(batch<uint8_t, A> const& self, batch<uint8_t, A> idx,
1358
+ requires_arch<neon64>) noexcept
1359
+ {
1360
+ return vqtbl1q_u8(self, idx);
1361
+ }
1362
+
1363
+ template <class A>
1364
+ XSIMD_INLINE batch<int8_t, A> swizzle(batch<int8_t, A> const& self, batch<uint8_t, A> idx,
1365
+ requires_arch<neon64>) noexcept
1366
+ {
1367
+ return vqtbl1q_s8(self, idx);
1368
+ }
1369
+
1370
+ template <class A>
1371
+ XSIMD_INLINE batch<uint16_t, A> swizzle(batch<uint16_t, A> const& self,
1372
+ batch<uint16_t, A> idx,
1373
+ requires_arch<neon64>) noexcept
1374
+ {
1375
+ using batch_type = batch<uint8_t, A>;
1376
+ using index_type = batch<uint8_t, A>;
1377
+ return vreinterpretq_u16_u8(swizzle(batch_type(vreinterpretq_u8_u16(self)),
1378
+ index_type(vreinterpretq_u8_u16(idx * 0x0202 + 0x0100)),
1379
+ neon64 {}));
1380
+ }
1381
+
1382
+ template <class A>
1383
+ XSIMD_INLINE batch<int16_t, A> swizzle(batch<int16_t, A> const& self,
1384
+ batch<uint16_t, A> idx,
1385
+ requires_arch<neon64>) noexcept
1386
+ {
1387
+ return bitwise_cast<int16_t>(swizzle(bitwise_cast<uint16_t>(self), idx, neon64 {}));
1388
+ }
1389
+
1390
+ template <class A>
1391
+ XSIMD_INLINE batch<uint32_t, A> swizzle(batch<uint32_t, A> const& self,
1392
+ batch<uint32_t, A> idx,
1393
+ requires_arch<neon64>) noexcept
1394
+ {
1395
+ using batch_type = batch<uint8_t, A>;
1396
+ using index_type = batch<uint8_t, A>;
1397
+ return vreinterpretq_u32_u8(swizzle(batch_type(vreinterpretq_u8_u32(self)),
1398
+ index_type(vreinterpretq_u8_u32(idx * 0x04040404 + 0x03020100)),
1399
+ neon64 {}));
1400
+ }
1401
+
1402
+ template <class A>
1403
+ XSIMD_INLINE batch<int32_t, A> swizzle(batch<int32_t, A> const& self,
1404
+ batch<uint32_t, A> idx,
1405
+ requires_arch<neon64>) noexcept
1406
+ {
1407
+ return bitwise_cast<int32_t>(swizzle(bitwise_cast<uint32_t>(self), idx, neon64 {}));
1408
+ }
1409
+
1410
+ template <class A>
1411
+ XSIMD_INLINE batch<uint64_t, A> swizzle(batch<uint64_t, A> const& self,
1412
+ batch<uint64_t, A> idx,
1413
+ requires_arch<neon64>) noexcept
1414
+ {
1415
+ using batch_type = batch<uint8_t, A>;
1416
+ using index_type = batch<uint8_t, A>;
1417
+ return vreinterpretq_u64_u8(swizzle(batch_type(vreinterpretq_u8_u64(self)),
1418
+ index_type(vreinterpretq_u8_u64(idx * 0x0808080808080808ull + 0x0706050403020100ull)),
1419
+ neon64 {}));
1420
+ }
1421
+
1422
+ template <class A>
1423
+ XSIMD_INLINE batch<int64_t, A> swizzle(batch<int64_t, A> const& self,
1424
+ batch<uint64_t, A> idx,
1425
+ requires_arch<neon64>) noexcept
1426
+ {
1427
+ return bitwise_cast<int64_t>(swizzle(bitwise_cast<uint64_t>(self), idx, neon64 {}));
1428
+ }
1429
+
1430
+ template <class A>
1431
+ XSIMD_INLINE batch<float, A> swizzle(batch<float, A> const& self,
1432
+ batch<uint32_t, A> idx,
1433
+ requires_arch<neon64>) noexcept
1434
+ {
1435
+ return bitwise_cast<float>(swizzle(bitwise_cast<uint32_t>(self), idx, neon64 {}));
1436
+ }
1437
+
1438
+ template <class A>
1439
+ XSIMD_INLINE batch<double, A> swizzle(batch<double, A> const& self,
1440
+ batch<uint64_t, A> idx,
1441
+ requires_arch<neon64>) noexcept
1442
+ {
1443
+ return bitwise_cast<double>(swizzle(bitwise_cast<uint64_t>(self), idx, neon64 {}));
1444
+ }
1445
+
1446
+ /********************
1447
+ * swizzle (static) *
1448
+ ********************/
1449
+
1450
+ namespace detail
1451
+ {
1452
+ using ::xsimd::batch_constant;
1453
+
1454
+ template <class CB1, class CB2, class IS>
1455
+ struct index_burst_impl;
1456
+
1457
+ template <typename T1, class A, typename T2, T2... V,
1458
+ T2... incr>
1459
+ struct index_burst_impl<batch_constant<T1, A>, batch_constant<T2, A, V...>,
1460
+ std::integer_sequence<T2, incr...>>
1461
+ {
1462
+ using type = batch_constant<T2, A, V...>;
1463
+ };
1464
+
1465
+ template <typename T1, class A, T1 V0, T1... V1,
1466
+ typename T2, T2... V2, T2... incr>
1467
+ struct index_burst_impl<batch_constant<T1, A, V0, V1...>, batch_constant<T2, A, V2...>,
1468
+ std::integer_sequence<T2, incr...>>
1469
+ {
1470
+ using next_input = batch_constant<T1, A, V1...>;
1471
+ using next_output = batch_constant<T2, A, V2..., (V0 + incr)...>;
1472
+ using type = typename index_burst_impl<next_input, next_output, std::integer_sequence<T2, incr...>>::type;
1473
+ };
1474
+
1475
+ template <class B, class T>
1476
+ struct index_burst;
1477
+
1478
+ template <typename Tp, class A, Tp... V, typename T>
1479
+ struct index_burst<batch_constant<Tp, A, V...>, T>
1480
+ {
1481
+ static constexpr size_t mul = sizeof(Tp) / sizeof(T);
1482
+ using input = batch_constant<Tp, A, (mul * V)...>;
1483
+ using output = batch_constant<T, A>;
1484
+ using type = typename index_burst_impl<input, output, std::make_integer_sequence<T, mul>>::type;
1485
+ };
1486
+
1487
+ template <class B, typename T>
1488
+ using index_burst_t = typename index_burst<B, T>::type;
1489
+
1490
+ template <typename T, class B>
1491
+ XSIMD_INLINE index_burst_t<B, T> burst_index(B)
1492
+ {
1493
+ return index_burst_t<B, T>();
1494
+ }
1495
+ }
1496
+
1497
+ template <class A, uint8_t V0, uint8_t V1, uint8_t V2, uint8_t V3, uint8_t V4, uint8_t V5, uint8_t V6, uint8_t V7,
1498
+ uint8_t V8, uint8_t V9, uint8_t V10, uint8_t V11, uint8_t V12, uint8_t V13, uint8_t V14, uint8_t V15>
1499
+ XSIMD_INLINE batch<uint8_t, A> swizzle(batch<uint8_t, A> const& self,
1500
+ batch_constant<uint8_t, A, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15> idx,
1501
+ requires_arch<neon64>) noexcept
1502
+ {
1503
+ return vqtbl1q_u8(self, idx.as_batch());
1504
+ }
1505
+
1506
+ template <class A, uint8_t V0, uint8_t V1, uint8_t V2, uint8_t V3, uint8_t V4, uint8_t V5, uint8_t V6, uint8_t V7,
1507
+ uint8_t V8, uint8_t V9, uint8_t V10, uint8_t V11, uint8_t V12, uint8_t V13, uint8_t V14, uint8_t V15>
1508
+ XSIMD_INLINE batch<int8_t, A> swizzle(batch<int8_t, A> const& self,
1509
+ batch_constant<uint8_t, A, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15> idx,
1510
+ requires_arch<neon64>) noexcept
1511
+ {
1512
+ return vqtbl1q_s8(self, idx.as_batch());
1513
+ }
1514
+
1515
+ template <class A, uint16_t V0, uint16_t V1, uint16_t V2, uint16_t V3, uint16_t V4, uint16_t V5, uint16_t V6, uint16_t V7>
1516
+ XSIMD_INLINE batch<uint16_t, A> swizzle(batch<uint16_t, A> const& self,
1517
+ batch_constant<uint16_t, A, V0, V1, V2, V3, V4, V5, V6, V7> idx,
1518
+ requires_arch<neon64>) noexcept
1519
+ {
1520
+ using batch_type = batch<uint8_t, A>;
1521
+ return vreinterpretq_u16_u8(swizzle<A>(batch_type(vreinterpretq_u8_u16(self)), detail::burst_index<uint8_t>(idx), A()));
1522
+ }
1523
+
1524
+ template <class A, uint16_t V0, uint16_t V1, uint16_t V2, uint16_t V3, uint16_t V4, uint16_t V5, uint16_t V6, uint16_t V7>
1525
+ XSIMD_INLINE batch<int16_t, A> swizzle(batch<int16_t, A> const& self,
1526
+ batch_constant<uint16_t, A, V0, V1, V2, V3, V4, V5, V6, V7> idx,
1527
+ requires_arch<neon64>) noexcept
1528
+ {
1529
+ using batch_type = batch<int8_t, A>;
1530
+ return vreinterpretq_s16_s8(swizzle<A>(batch_type(vreinterpretq_s8_s16(self)), detail::burst_index<uint8_t>(idx), A()));
1531
+ }
1532
+
1533
+ template <class A, uint32_t V0, uint32_t V1, uint32_t V2, uint32_t V3>
1534
+ XSIMD_INLINE batch<uint32_t, A> swizzle(batch<uint32_t, A> const& self,
1535
+ batch_constant<uint32_t, A, V0, V1, V2, V3> idx,
1536
+ requires_arch<neon64>) noexcept
1537
+ {
1538
+ using batch_type = batch<uint8_t, A>;
1539
+ return vreinterpretq_u32_u8(swizzle<A>(batch_type(vreinterpretq_u8_u32(self)), detail::burst_index<uint8_t>(idx), A()));
1540
+ }
1541
+
1542
+ template <class A, uint32_t V0, uint32_t V1, uint32_t V2, uint32_t V3>
1543
+ XSIMD_INLINE batch<int32_t, A> swizzle(batch<int32_t, A> const& self,
1544
+ batch_constant<uint32_t, A, V0, V1, V2, V3> idx,
1545
+ requires_arch<neon64>) noexcept
1546
+ {
1547
+ using batch_type = batch<int8_t, A>;
1548
+ return vreinterpretq_s32_s8(swizzle<A>(batch_type(vreinterpretq_s8_s32(self)), detail::burst_index<uint8_t>(idx), A()));
1549
+ }
1550
+
1551
+ template <class A, uint64_t V0, uint64_t V1>
1552
+ XSIMD_INLINE batch<uint64_t, A> swizzle(batch<uint64_t, A> const& self,
1553
+ batch_constant<uint64_t, A, V0, V1> idx,
1554
+ requires_arch<neon64>) noexcept
1555
+ {
1556
+ using batch_type = batch<uint8_t, A>;
1557
+ return vreinterpretq_u64_u8(swizzle<A>(batch_type(vreinterpretq_u8_u64(self)), detail::burst_index<uint8_t>(idx), A()));
1558
+ }
1559
+
1560
+ template <class A, uint64_t V0, uint64_t V1>
1561
+ XSIMD_INLINE batch<int64_t, A> swizzle(batch<int64_t, A> const& self,
1562
+ batch_constant<uint64_t, A, V0, V1> idx,
1563
+ requires_arch<neon64>) noexcept
1564
+ {
1565
+ using batch_type = batch<int8_t, A>;
1566
+ return vreinterpretq_s64_s8(swizzle<A>(batch_type(vreinterpretq_s8_s64(self)), detail::burst_index<uint8_t>(idx), A()));
1567
+ }
1568
+
1569
+ template <class A, uint32_t V0, uint32_t V1, uint32_t V2, uint32_t V3>
1570
+ XSIMD_INLINE batch<float, A> swizzle(batch<float, A> const& self,
1571
+ batch_constant<uint32_t, A, V0, V1, V2, V3> idx,
1572
+ requires_arch<neon64>) noexcept
1573
+ {
1574
+ using batch_type = batch<uint8_t, A>;
1575
+ return vreinterpretq_f32_u8(swizzle<A>(batch_type(vreinterpretq_u8_f32(self)), detail::burst_index<uint8_t>(idx), A()));
1576
+ }
1577
+
1578
+ template <class A, uint64_t V0, uint64_t V1>
1579
+ XSIMD_INLINE batch<double, A> swizzle(batch<double, A> const& self,
1580
+ batch_constant<uint64_t, A, V0, V1> idx,
1581
+ requires_arch<neon64>) noexcept
1582
+ {
1583
+ using batch_type = batch<uint8_t, A>;
1584
+ return vreinterpretq_f64_u8(swizzle<A>(batch_type(vreinterpretq_u8_f64(self)), detail::burst_index<uint8_t>(idx), A()));
1585
+ }
1586
+
1587
+ template <class A, uint32_t V0, uint32_t V1, uint32_t V2, uint32_t V3>
1588
+ XSIMD_INLINE batch<std::complex<float>, A> swizzle(batch<std::complex<float>, A> const& self,
1589
+ batch_constant<uint32_t, A, V0, V1, V2, V3> idx,
1590
+ requires_arch<neon64>) noexcept
1591
+ {
1592
+ return batch<std::complex<float>>(swizzle(self.real(), idx, A()), swizzle(self.imag(), idx, A()));
1593
+ }
1594
+
1595
+ template <class A, uint64_t V0, uint64_t V1>
1596
+ XSIMD_INLINE batch<std::complex<double>, A> swizzle(batch<std::complex<double>, A> const& self,
1597
+ batch_constant<uint64_t, A, V0, V1> idx,
1598
+ requires_arch<neon64>) noexcept
1599
+ {
1600
+ return batch<std::complex<double>>(swizzle(self.real(), idx, A()), swizzle(self.imag(), idx, A()));
1601
+ }
1602
+
1603
+ /*********
1604
+ * widen *
1605
+ *********/
1606
+ template <class A>
1607
+ XSIMD_INLINE std::array<batch<double, A>, 2> widen(batch<float, A> const& x, requires_arch<neon64>) noexcept
1608
+ {
1609
+ return { batch<double, A>(vcvt_f64_f32(vget_low_f32(x))), batch<double, A>(vcvt_high_f64_f32(x)) };
1610
+ }
1611
+ }
1612
+ }
1613
+
1614
+ #endif