simd128_ref.inl 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. /*
  2. * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #ifndef BX_SIMD_T_H_HEADER_GUARD
  6. # error "Must be included from bx/simd_t.h!"
  7. #endif // BX_SIMD_T_H_HEADER_GUARD
  8. namespace bx
  9. {
  10. BX_CONST_FUNC float sqrt(float);
  11. BX_CONST_FUNC float rsqrt(float);
  12. #define ELEMx 0
  13. #define ELEMy 1
  14. #define ELEMz 2
  15. #define ELEMw 3
  16. #define BX_SIMD128_IMPLEMENT_SWIZZLE(_x, _y, _z, _w) \
  17. template<> \
  18. BX_SIMD_FORCE_INLINE simd128_ref_t simd_swiz_##_x##_y##_z##_w(simd128_ref_t _a) \
  19. { \
  20. simd128_ref_t result; \
  21. result.ixyzw[0] = _a.ixyzw[ELEM##_x]; \
  22. result.ixyzw[1] = _a.ixyzw[ELEM##_y]; \
  23. result.ixyzw[2] = _a.ixyzw[ELEM##_z]; \
  24. result.ixyzw[3] = _a.ixyzw[ELEM##_w]; \
  25. return result; \
  26. }
  27. #include "simd128_swizzle.inl"
  28. #undef BX_SIMD128_IMPLEMENT_SWIZZLE
  29. #undef ELEMw
  30. #undef ELEMz
  31. #undef ELEMy
  32. #undef ELEMx
  33. #define BX_SIMD128_IMPLEMENT_TEST(_xyzw, _mask) \
  34. template<> \
  35. BX_SIMD_FORCE_INLINE bool simd_test_any_##_xyzw(simd128_ref_t _test) \
  36. { \
  37. uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \
  38. | ( (_test.uxyzw[2]>>31)<<2) \
  39. | ( (_test.uxyzw[1]>>31)<<1) \
  40. | ( _test.uxyzw[0]>>31) \
  41. ; \
  42. return 0 != (tmp&(_mask) ); \
  43. } \
  44. \
  45. template<> \
  46. BX_SIMD_FORCE_INLINE bool simd_test_all_##_xyzw(simd128_ref_t _test) \
  47. { \
  48. uint32_t tmp = ( (_test.uxyzw[3]>>31)<<3) \
  49. | ( (_test.uxyzw[2]>>31)<<2) \
  50. | ( (_test.uxyzw[1]>>31)<<1) \
  51. | ( _test.uxyzw[0]>>31) \
  52. ; \
  53. return (_mask) == (tmp&(_mask) ); \
  54. }
  55. BX_SIMD128_IMPLEMENT_TEST(x , 0x1);
  56. BX_SIMD128_IMPLEMENT_TEST(y , 0x2);
  57. BX_SIMD128_IMPLEMENT_TEST(xy , 0x3);
  58. BX_SIMD128_IMPLEMENT_TEST(z , 0x4);
  59. BX_SIMD128_IMPLEMENT_TEST(xz , 0x5);
  60. BX_SIMD128_IMPLEMENT_TEST(yz , 0x6);
  61. BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7);
  62. BX_SIMD128_IMPLEMENT_TEST(w , 0x8);
  63. BX_SIMD128_IMPLEMENT_TEST(xw , 0x9);
  64. BX_SIMD128_IMPLEMENT_TEST(yw , 0xa);
  65. BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb);
  66. BX_SIMD128_IMPLEMENT_TEST(zw , 0xc);
  67. BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd);
  68. BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe);
  69. BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
  70. #undef BX_SIMD128_IMPLEMENT_TEST
  71. template<>
  72. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_xyAB(simd128_ref_t _a, simd128_ref_t _b)
  73. {
  74. simd128_ref_t result;
  75. result.uxyzw[0] = _a.uxyzw[0];
  76. result.uxyzw[1] = _a.uxyzw[1];
  77. result.uxyzw[2] = _b.uxyzw[0];
  78. result.uxyzw[3] = _b.uxyzw[1];
  79. return result;
  80. }
  81. template<>
  82. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_ABxy(simd128_ref_t _a, simd128_ref_t _b)
  83. {
  84. simd128_ref_t result;
  85. result.uxyzw[0] = _b.uxyzw[0];
  86. result.uxyzw[1] = _b.uxyzw[1];
  87. result.uxyzw[2] = _a.uxyzw[0];
  88. result.uxyzw[3] = _a.uxyzw[1];
  89. return result;
  90. }
  91. template<>
  92. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_CDzw(simd128_ref_t _a, simd128_ref_t _b)
  93. {
  94. simd128_ref_t result;
  95. result.uxyzw[0] = _b.uxyzw[2];
  96. result.uxyzw[1] = _b.uxyzw[3];
  97. result.uxyzw[2] = _a.uxyzw[2];
  98. result.uxyzw[3] = _a.uxyzw[3];
  99. return result;
  100. }
  101. template<>
  102. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_zwCD(simd128_ref_t _a, simd128_ref_t _b)
  103. {
  104. simd128_ref_t result;
  105. result.uxyzw[0] = _a.uxyzw[2];
  106. result.uxyzw[1] = _a.uxyzw[3];
  107. result.uxyzw[2] = _b.uxyzw[2];
  108. result.uxyzw[3] = _b.uxyzw[3];
  109. return result;
  110. }
  111. template<>
  112. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_xAyB(simd128_ref_t _a, simd128_ref_t _b)
  113. {
  114. simd128_ref_t result;
  115. result.uxyzw[0] = _a.uxyzw[0];
  116. result.uxyzw[1] = _b.uxyzw[0];
  117. result.uxyzw[2] = _a.uxyzw[1];
  118. result.uxyzw[3] = _b.uxyzw[1];
  119. return result;
  120. }
  121. template<>
  122. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_AxBy(simd128_ref_t _a, simd128_ref_t _b)
  123. {
  124. simd128_ref_t result;
  125. result.uxyzw[0] = _a.uxyzw[1];
  126. result.uxyzw[1] = _b.uxyzw[1];
  127. result.uxyzw[2] = _a.uxyzw[0];
  128. result.uxyzw[3] = _b.uxyzw[0];
  129. return result;
  130. }
  131. template<>
  132. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_zCwD(simd128_ref_t _a, simd128_ref_t _b)
  133. {
  134. simd128_ref_t result;
  135. result.uxyzw[0] = _a.uxyzw[2];
  136. result.uxyzw[1] = _b.uxyzw[2];
  137. result.uxyzw[2] = _a.uxyzw[3];
  138. result.uxyzw[3] = _b.uxyzw[3];
  139. return result;
  140. }
  141. template<>
  142. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_CzDw(simd128_ref_t _a, simd128_ref_t _b)
  143. {
  144. simd128_ref_t result;
  145. result.uxyzw[0] = _b.uxyzw[2];
  146. result.uxyzw[1] = _a.uxyzw[2];
  147. result.uxyzw[2] = _b.uxyzw[3];
  148. result.uxyzw[3] = _a.uxyzw[3];
  149. return result;
  150. }
  151. template<>
  152. BX_SIMD_FORCE_INLINE float simd_x(simd128_ref_t _a)
  153. {
  154. return _a.fxyzw[0];
  155. }
  156. template<>
  157. BX_SIMD_FORCE_INLINE float simd_y(simd128_ref_t _a)
  158. {
  159. return _a.fxyzw[1];
  160. }
  161. template<>
  162. BX_SIMD_FORCE_INLINE float simd_z(simd128_ref_t _a)
  163. {
  164. return _a.fxyzw[2];
  165. }
  166. template<>
  167. BX_SIMD_FORCE_INLINE float simd_w(simd128_ref_t _a)
  168. {
  169. return _a.fxyzw[3];
  170. }
  171. template<>
  172. BX_SIMD_FORCE_INLINE simd128_ref_t simd_ld(const void* _ptr)
  173. {
  174. const uint32_t* input = reinterpret_cast<const uint32_t*>(_ptr);
  175. simd128_ref_t result;
  176. result.uxyzw[0] = input[0];
  177. result.uxyzw[1] = input[1];
  178. result.uxyzw[2] = input[2];
  179. result.uxyzw[3] = input[3];
  180. return result;
  181. }
  182. template<>
  183. BX_SIMD_FORCE_INLINE void simd_st(void* _ptr, simd128_ref_t _a)
  184. {
  185. uint32_t* result = reinterpret_cast<uint32_t*>(_ptr);
  186. result[0] = _a.uxyzw[0];
  187. result[1] = _a.uxyzw[1];
  188. result[2] = _a.uxyzw[2];
  189. result[3] = _a.uxyzw[3];
  190. }
  191. template<>
  192. BX_SIMD_FORCE_INLINE void simd_stx(void* _ptr, simd128_ref_t _a)
  193. {
  194. uint32_t* result = reinterpret_cast<uint32_t*>(_ptr);
  195. result[0] = _a.uxyzw[0];
  196. }
  197. template<>
  198. BX_SIMD_FORCE_INLINE void simd_stream(void* _ptr, simd128_ref_t _a)
  199. {
  200. uint32_t* result = reinterpret_cast<uint32_t*>(_ptr);
  201. result[0] = _a.uxyzw[0];
  202. result[1] = _a.uxyzw[1];
  203. result[2] = _a.uxyzw[2];
  204. result[3] = _a.uxyzw[3];
  205. }
  206. template<>
  207. BX_SIMD_FORCE_INLINE simd128_ref_t simd_ld(float _x, float _y, float _z, float _w)
  208. {
  209. simd128_ref_t result;
  210. result.fxyzw[0] = _x;
  211. result.fxyzw[1] = _y;
  212. result.fxyzw[2] = _z;
  213. result.fxyzw[3] = _w;
  214. return result;
  215. }
  216. template<>
  217. BX_SIMD_FORCE_INLINE simd128_ref_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w)
  218. {
  219. simd128_ref_t result;
  220. result.uxyzw[0] = _x;
  221. result.uxyzw[1] = _y;
  222. result.uxyzw[2] = _z;
  223. result.uxyzw[3] = _w;
  224. return result;
  225. }
  226. template<>
  227. BX_SIMD_FORCE_INLINE simd128_ref_t simd_splat(const void* _ptr)
  228. {
  229. const uint32_t val = *reinterpret_cast<const uint32_t*>(_ptr);
  230. simd128_ref_t result;
  231. result.uxyzw[0] = val;
  232. result.uxyzw[1] = val;
  233. result.uxyzw[2] = val;
  234. result.uxyzw[3] = val;
  235. return result;
  236. }
  237. template<>
  238. BX_SIMD_FORCE_INLINE simd128_ref_t simd_splat(float _a)
  239. {
  240. return simd_ld<simd128_ref_t>(_a, _a, _a, _a);
  241. }
  242. template<>
  243. BX_SIMD_FORCE_INLINE simd128_ref_t simd_isplat(uint32_t _a)
  244. {
  245. return simd_ild<simd128_ref_t>(_a, _a, _a, _a);
  246. }
  247. template<>
  248. BX_SIMD_FORCE_INLINE simd128_ref_t simd_zero()
  249. {
  250. return simd_ild<simd128_ref_t>(0, 0, 0, 0);
  251. }
  252. template<>
  253. BX_SIMD_FORCE_INLINE simd128_ref_t simd_itof(simd128_ref_t _a)
  254. {
  255. simd128_ref_t result;
  256. result.fxyzw[0] = (float)_a.ixyzw[0];
  257. result.fxyzw[1] = (float)_a.ixyzw[1];
  258. result.fxyzw[2] = (float)_a.ixyzw[2];
  259. result.fxyzw[3] = (float)_a.ixyzw[3];
  260. return result;
  261. }
  262. template<>
  263. BX_SIMD_FORCE_INLINE simd128_ref_t simd_ftoi(simd128_ref_t _a)
  264. {
  265. simd128_ref_t result;
  266. result.ixyzw[0] = (int)_a.fxyzw[0];
  267. result.ixyzw[1] = (int)_a.fxyzw[1];
  268. result.ixyzw[2] = (int)_a.fxyzw[2];
  269. result.ixyzw[3] = (int)_a.fxyzw[3];
  270. return result;
  271. }
  272. template<>
  273. BX_SIMD_FORCE_INLINE simd128_ref_t simd_round(simd128_ref_t _a)
  274. {
  275. return simd_round_ni(_a);
  276. }
  277. template<>
  278. BX_SIMD_FORCE_INLINE simd128_ref_t simd_add(simd128_ref_t _a, simd128_ref_t _b)
  279. {
  280. simd128_ref_t result;
  281. result.fxyzw[0] = _a.fxyzw[0] + _b.fxyzw[0];
  282. result.fxyzw[1] = _a.fxyzw[1] + _b.fxyzw[1];
  283. result.fxyzw[2] = _a.fxyzw[2] + _b.fxyzw[2];
  284. result.fxyzw[3] = _a.fxyzw[3] + _b.fxyzw[3];
  285. return result;
  286. }
  287. template<>
  288. BX_SIMD_FORCE_INLINE simd128_ref_t simd_sub(simd128_ref_t _a, simd128_ref_t _b)
  289. {
  290. simd128_ref_t result;
  291. result.fxyzw[0] = _a.fxyzw[0] - _b.fxyzw[0];
  292. result.fxyzw[1] = _a.fxyzw[1] - _b.fxyzw[1];
  293. result.fxyzw[2] = _a.fxyzw[2] - _b.fxyzw[2];
  294. result.fxyzw[3] = _a.fxyzw[3] - _b.fxyzw[3];
  295. return result;
  296. }
  297. template<>
  298. BX_SIMD_FORCE_INLINE simd128_ref_t simd_mul(simd128_ref_t _a, simd128_ref_t _b)
  299. {
  300. simd128_ref_t result;
  301. result.fxyzw[0] = _a.fxyzw[0] * _b.fxyzw[0];
  302. result.fxyzw[1] = _a.fxyzw[1] * _b.fxyzw[1];
  303. result.fxyzw[2] = _a.fxyzw[2] * _b.fxyzw[2];
  304. result.fxyzw[3] = _a.fxyzw[3] * _b.fxyzw[3];
  305. return result;
  306. }
  307. template<>
  308. BX_SIMD_FORCE_INLINE simd128_ref_t simd_div(simd128_ref_t _a, simd128_ref_t _b)
  309. {
  310. simd128_ref_t result;
  311. result.fxyzw[0] = _a.fxyzw[0] / _b.fxyzw[0];
  312. result.fxyzw[1] = _a.fxyzw[1] / _b.fxyzw[1];
  313. result.fxyzw[2] = _a.fxyzw[2] / _b.fxyzw[2];
  314. result.fxyzw[3] = _a.fxyzw[3] / _b.fxyzw[3];
  315. return result;
  316. }
  317. template<>
  318. BX_SIMD_FORCE_INLINE simd128_ref_t simd_rcp_est(simd128_ref_t _a)
  319. {
  320. simd128_ref_t result;
  321. result.fxyzw[0] = 1.0f / _a.fxyzw[0];
  322. result.fxyzw[1] = 1.0f / _a.fxyzw[1];
  323. result.fxyzw[2] = 1.0f / _a.fxyzw[2];
  324. result.fxyzw[3] = 1.0f / _a.fxyzw[3];
  325. return result;
  326. }
  327. template<>
  328. BX_SIMD_FORCE_INLINE simd128_ref_t simd_sqrt(simd128_ref_t _a)
  329. {
  330. simd128_ref_t result;
  331. result.fxyzw[0] = sqrt(_a.fxyzw[0]);
  332. result.fxyzw[1] = sqrt(_a.fxyzw[1]);
  333. result.fxyzw[2] = sqrt(_a.fxyzw[2]);
  334. result.fxyzw[3] = sqrt(_a.fxyzw[3]);
  335. return result;
  336. }
  337. template<>
  338. BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt_est(simd128_ref_t _a)
  339. {
  340. simd128_ref_t result;
  341. result.fxyzw[0] = rsqrt(_a.fxyzw[0]);
  342. result.fxyzw[1] = rsqrt(_a.fxyzw[1]);
  343. result.fxyzw[2] = rsqrt(_a.fxyzw[2]);
  344. result.fxyzw[3] = rsqrt(_a.fxyzw[3]);
  345. return result;
  346. }
  347. template<>
  348. BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpeq(simd128_ref_t _a, simd128_ref_t _b)
  349. {
  350. simd128_ref_t result;
  351. result.ixyzw[0] = _a.fxyzw[0] == _b.fxyzw[0] ? 0xffffffff : 0x0;
  352. result.ixyzw[1] = _a.fxyzw[1] == _b.fxyzw[1] ? 0xffffffff : 0x0;
  353. result.ixyzw[2] = _a.fxyzw[2] == _b.fxyzw[2] ? 0xffffffff : 0x0;
  354. result.ixyzw[3] = _a.fxyzw[3] == _b.fxyzw[3] ? 0xffffffff : 0x0;
  355. return result;
  356. }
  357. template<>
  358. BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmplt(simd128_ref_t _a, simd128_ref_t _b)
  359. {
  360. simd128_ref_t result;
  361. result.ixyzw[0] = _a.fxyzw[0] < _b.fxyzw[0] ? 0xffffffff : 0x0;
  362. result.ixyzw[1] = _a.fxyzw[1] < _b.fxyzw[1] ? 0xffffffff : 0x0;
  363. result.ixyzw[2] = _a.fxyzw[2] < _b.fxyzw[2] ? 0xffffffff : 0x0;
  364. result.ixyzw[3] = _a.fxyzw[3] < _b.fxyzw[3] ? 0xffffffff : 0x0;
  365. return result;
  366. }
  367. template<>
  368. BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmple(simd128_ref_t _a, simd128_ref_t _b)
  369. {
  370. simd128_ref_t result;
  371. result.ixyzw[0] = _a.fxyzw[0] <= _b.fxyzw[0] ? 0xffffffff : 0x0;
  372. result.ixyzw[1] = _a.fxyzw[1] <= _b.fxyzw[1] ? 0xffffffff : 0x0;
  373. result.ixyzw[2] = _a.fxyzw[2] <= _b.fxyzw[2] ? 0xffffffff : 0x0;
  374. result.ixyzw[3] = _a.fxyzw[3] <= _b.fxyzw[3] ? 0xffffffff : 0x0;
  375. return result;
  376. }
  377. template<>
  378. BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpgt(simd128_ref_t _a, simd128_ref_t _b)
  379. {
  380. simd128_ref_t result;
  381. result.ixyzw[0] = _a.fxyzw[0] > _b.fxyzw[0] ? 0xffffffff : 0x0;
  382. result.ixyzw[1] = _a.fxyzw[1] > _b.fxyzw[1] ? 0xffffffff : 0x0;
  383. result.ixyzw[2] = _a.fxyzw[2] > _b.fxyzw[2] ? 0xffffffff : 0x0;
  384. result.ixyzw[3] = _a.fxyzw[3] > _b.fxyzw[3] ? 0xffffffff : 0x0;
  385. return result;
  386. }
  387. template<>
  388. BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpge(simd128_ref_t _a, simd128_ref_t _b)
  389. {
  390. simd128_ref_t result;
  391. result.ixyzw[0] = _a.fxyzw[0] >= _b.fxyzw[0] ? 0xffffffff : 0x0;
  392. result.ixyzw[1] = _a.fxyzw[1] >= _b.fxyzw[1] ? 0xffffffff : 0x0;
  393. result.ixyzw[2] = _a.fxyzw[2] >= _b.fxyzw[2] ? 0xffffffff : 0x0;
  394. result.ixyzw[3] = _a.fxyzw[3] >= _b.fxyzw[3] ? 0xffffffff : 0x0;
  395. return result;
  396. }
  397. template<>
  398. BX_SIMD_FORCE_INLINE simd128_ref_t simd_min(simd128_ref_t _a, simd128_ref_t _b)
  399. {
  400. simd128_ref_t result;
  401. result.fxyzw[0] = _a.fxyzw[0] < _b.fxyzw[0] ? _a.fxyzw[0] : _b.fxyzw[0];
  402. result.fxyzw[1] = _a.fxyzw[1] < _b.fxyzw[1] ? _a.fxyzw[1] : _b.fxyzw[1];
  403. result.fxyzw[2] = _a.fxyzw[2] < _b.fxyzw[2] ? _a.fxyzw[2] : _b.fxyzw[2];
  404. result.fxyzw[3] = _a.fxyzw[3] < _b.fxyzw[3] ? _a.fxyzw[3] : _b.fxyzw[3];
  405. return result;
  406. }
  407. template<>
  408. BX_SIMD_FORCE_INLINE simd128_ref_t simd_max(simd128_ref_t _a, simd128_ref_t _b)
  409. {
  410. simd128_ref_t result;
  411. result.fxyzw[0] = _a.fxyzw[0] > _b.fxyzw[0] ? _a.fxyzw[0] : _b.fxyzw[0];
  412. result.fxyzw[1] = _a.fxyzw[1] > _b.fxyzw[1] ? _a.fxyzw[1] : _b.fxyzw[1];
  413. result.fxyzw[2] = _a.fxyzw[2] > _b.fxyzw[2] ? _a.fxyzw[2] : _b.fxyzw[2];
  414. result.fxyzw[3] = _a.fxyzw[3] > _b.fxyzw[3] ? _a.fxyzw[3] : _b.fxyzw[3];
  415. return result;
  416. }
  417. template<>
  418. BX_SIMD_FORCE_INLINE simd128_ref_t simd_and(simd128_ref_t _a, simd128_ref_t _b)
  419. {
  420. simd128_ref_t result;
  421. result.uxyzw[0] = _a.uxyzw[0] & _b.uxyzw[0];
  422. result.uxyzw[1] = _a.uxyzw[1] & _b.uxyzw[1];
  423. result.uxyzw[2] = _a.uxyzw[2] & _b.uxyzw[2];
  424. result.uxyzw[3] = _a.uxyzw[3] & _b.uxyzw[3];
  425. return result;
  426. }
  427. template<>
  428. BX_SIMD_FORCE_INLINE simd128_ref_t simd_andc(simd128_ref_t _a, simd128_ref_t _b)
  429. {
  430. simd128_ref_t result;
  431. result.uxyzw[0] = _a.uxyzw[0] & ~_b.uxyzw[0];
  432. result.uxyzw[1] = _a.uxyzw[1] & ~_b.uxyzw[1];
  433. result.uxyzw[2] = _a.uxyzw[2] & ~_b.uxyzw[2];
  434. result.uxyzw[3] = _a.uxyzw[3] & ~_b.uxyzw[3];
  435. return result;
  436. }
  437. template<>
  438. BX_SIMD_FORCE_INLINE simd128_ref_t simd_or(simd128_ref_t _a, simd128_ref_t _b)
  439. {
  440. simd128_ref_t result;
  441. result.uxyzw[0] = _a.uxyzw[0] | _b.uxyzw[0];
  442. result.uxyzw[1] = _a.uxyzw[1] | _b.uxyzw[1];
  443. result.uxyzw[2] = _a.uxyzw[2] | _b.uxyzw[2];
  444. result.uxyzw[3] = _a.uxyzw[3] | _b.uxyzw[3];
  445. return result;
  446. }
  447. template<>
  448. BX_SIMD_FORCE_INLINE simd128_ref_t simd_xor(simd128_ref_t _a, simd128_ref_t _b)
  449. {
  450. simd128_ref_t result;
  451. result.uxyzw[0] = _a.uxyzw[0] ^ _b.uxyzw[0];
  452. result.uxyzw[1] = _a.uxyzw[1] ^ _b.uxyzw[1];
  453. result.uxyzw[2] = _a.uxyzw[2] ^ _b.uxyzw[2];
  454. result.uxyzw[3] = _a.uxyzw[3] ^ _b.uxyzw[3];
  455. return result;
  456. }
  457. template<>
  458. BX_SIMD_FORCE_INLINE simd128_ref_t simd_sll(simd128_ref_t _a, int _count)
  459. {
  460. simd128_ref_t result;
  461. result.uxyzw[0] = _a.uxyzw[0] << _count;
  462. result.uxyzw[1] = _a.uxyzw[1] << _count;
  463. result.uxyzw[2] = _a.uxyzw[2] << _count;
  464. result.uxyzw[3] = _a.uxyzw[3] << _count;
  465. return result;
  466. }
  467. template<>
  468. BX_SIMD_FORCE_INLINE simd128_ref_t simd_srl(simd128_ref_t _a, int _count)
  469. {
  470. simd128_ref_t result;
  471. result.uxyzw[0] = _a.uxyzw[0] >> _count;
  472. result.uxyzw[1] = _a.uxyzw[1] >> _count;
  473. result.uxyzw[2] = _a.uxyzw[2] >> _count;
  474. result.uxyzw[3] = _a.uxyzw[3] >> _count;
  475. return result;
  476. }
  477. template<>
  478. BX_SIMD_FORCE_INLINE simd128_ref_t simd_sra(simd128_ref_t _a, int _count)
  479. {
  480. simd128_ref_t result;
  481. result.ixyzw[0] = _a.ixyzw[0] >> _count;
  482. result.ixyzw[1] = _a.ixyzw[1] >> _count;
  483. result.ixyzw[2] = _a.ixyzw[2] >> _count;
  484. result.ixyzw[3] = _a.ixyzw[3] >> _count;
  485. return result;
  486. }
  487. template<>
  488. BX_SIMD_FORCE_INLINE simd128_ref_t simd_icmpeq(simd128_ref_t _a, simd128_ref_t _b)
  489. {
  490. simd128_ref_t result;
  491. result.ixyzw[0] = _a.ixyzw[0] == _b.ixyzw[0] ? 0xffffffff : 0x0;
  492. result.ixyzw[1] = _a.ixyzw[1] == _b.ixyzw[1] ? 0xffffffff : 0x0;
  493. result.ixyzw[2] = _a.ixyzw[2] == _b.ixyzw[2] ? 0xffffffff : 0x0;
  494. result.ixyzw[3] = _a.ixyzw[3] == _b.ixyzw[3] ? 0xffffffff : 0x0;
  495. return result;
  496. }
  497. template<>
  498. BX_SIMD_FORCE_INLINE simd128_ref_t simd_icmplt(simd128_ref_t _a, simd128_ref_t _b)
  499. {
  500. simd128_ref_t result;
  501. result.ixyzw[0] = _a.ixyzw[0] < _b.ixyzw[0] ? 0xffffffff : 0x0;
  502. result.ixyzw[1] = _a.ixyzw[1] < _b.ixyzw[1] ? 0xffffffff : 0x0;
  503. result.ixyzw[2] = _a.ixyzw[2] < _b.ixyzw[2] ? 0xffffffff : 0x0;
  504. result.ixyzw[3] = _a.ixyzw[3] < _b.ixyzw[3] ? 0xffffffff : 0x0;
  505. return result;
  506. }
  507. template<>
  508. BX_SIMD_FORCE_INLINE simd128_ref_t simd_icmpgt(simd128_ref_t _a, simd128_ref_t _b)
  509. {
  510. simd128_ref_t result;
  511. result.ixyzw[0] = _a.ixyzw[0] > _b.ixyzw[0] ? 0xffffffff : 0x0;
  512. result.ixyzw[1] = _a.ixyzw[1] > _b.ixyzw[1] ? 0xffffffff : 0x0;
  513. result.ixyzw[2] = _a.ixyzw[2] > _b.ixyzw[2] ? 0xffffffff : 0x0;
  514. result.ixyzw[3] = _a.ixyzw[3] > _b.ixyzw[3] ? 0xffffffff : 0x0;
  515. return result;
  516. }
  517. template<>
  518. BX_SIMD_FORCE_INLINE simd128_ref_t simd_imin(simd128_ref_t _a, simd128_ref_t _b)
  519. {
  520. simd128_ref_t result;
  521. result.ixyzw[0] = _a.ixyzw[0] < _b.ixyzw[0] ? _a.ixyzw[0] : _b.ixyzw[0];
  522. result.ixyzw[1] = _a.ixyzw[1] < _b.ixyzw[1] ? _a.ixyzw[1] : _b.ixyzw[1];
  523. result.ixyzw[2] = _a.ixyzw[2] < _b.ixyzw[2] ? _a.ixyzw[2] : _b.ixyzw[2];
  524. result.ixyzw[3] = _a.ixyzw[3] < _b.ixyzw[3] ? _a.ixyzw[3] : _b.ixyzw[3];
  525. return result;
  526. }
  527. template<>
  528. BX_SIMD_FORCE_INLINE simd128_ref_t simd_imax(simd128_ref_t _a, simd128_ref_t _b)
  529. {
  530. simd128_ref_t result;
  531. result.ixyzw[0] = _a.ixyzw[0] > _b.ixyzw[0] ? _a.ixyzw[0] : _b.ixyzw[0];
  532. result.ixyzw[1] = _a.ixyzw[1] > _b.ixyzw[1] ? _a.ixyzw[1] : _b.ixyzw[1];
  533. result.ixyzw[2] = _a.ixyzw[2] > _b.ixyzw[2] ? _a.ixyzw[2] : _b.ixyzw[2];
  534. result.ixyzw[3] = _a.ixyzw[3] > _b.ixyzw[3] ? _a.ixyzw[3] : _b.ixyzw[3];
  535. return result;
  536. }
  537. template<>
  538. BX_SIMD_FORCE_INLINE simd128_ref_t simd_iadd(simd128_ref_t _a, simd128_ref_t _b)
  539. {
  540. simd128_ref_t result;
  541. result.ixyzw[0] = _a.ixyzw[0] + _b.ixyzw[0];
  542. result.ixyzw[1] = _a.ixyzw[1] + _b.ixyzw[1];
  543. result.ixyzw[2] = _a.ixyzw[2] + _b.ixyzw[2];
  544. result.ixyzw[3] = _a.ixyzw[3] + _b.ixyzw[3];
  545. return result;
  546. }
  547. template<>
  548. BX_SIMD_FORCE_INLINE simd128_ref_t simd_isub(simd128_ref_t _a, simd128_ref_t _b)
  549. {
  550. simd128_ref_t result;
  551. result.ixyzw[0] = _a.ixyzw[0] - _b.ixyzw[0];
  552. result.ixyzw[1] = _a.ixyzw[1] - _b.ixyzw[1];
  553. result.ixyzw[2] = _a.ixyzw[2] - _b.ixyzw[2];
  554. result.ixyzw[3] = _a.ixyzw[3] - _b.ixyzw[3];
  555. return result;
  556. }
  557. BX_SIMD_FORCE_INLINE simd128_t simd_zero()
  558. {
  559. return simd_zero<simd128_t>();
  560. }
  561. BX_SIMD_FORCE_INLINE simd128_t simd_ld(const void* _ptr)
  562. {
  563. return simd_ld<simd128_t>(_ptr);
  564. }
  565. BX_SIMD_FORCE_INLINE simd128_t simd_ld(float _x, float _y, float _z, float _w)
  566. {
  567. return simd_ld<simd128_t>(_x, _y, _z, _w);
  568. }
  569. BX_SIMD_FORCE_INLINE simd128_t simd_ild(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w)
  570. {
  571. return simd_ild<simd128_t>(_x, _y, _z, _w);
  572. }
  573. BX_SIMD_FORCE_INLINE simd128_t simd_splat(const void* _ptr)
  574. {
  575. return simd_splat<simd128_t>(_ptr);
  576. }
  577. BX_SIMD_FORCE_INLINE simd128_t simd_splat(float _a)
  578. {
  579. return simd_splat<simd128_t>(_a);
  580. }
  581. BX_SIMD_FORCE_INLINE simd128_t simd_isplat(uint32_t _a)
  582. {
  583. return simd_isplat<simd128_t>(_a);
  584. }
  585. template<>
  586. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_xAzC(simd128_ref_t _a, simd128_ref_t _b)
  587. {
  588. return simd_shuf_xAzC_ni(_a, _b);
  589. }
  590. template<>
  591. BX_SIMD_FORCE_INLINE simd128_ref_t simd_shuf_yBwD(simd128_ref_t _a, simd128_ref_t _b)
  592. {
  593. return simd_shuf_yBwD_ni(_a, _b);
  594. }
  595. template<>
  596. BX_SIMD_FORCE_INLINE simd128_ref_t simd_rcp(simd128_ref_t _a)
  597. {
  598. return simd_rcp_ni(_a);
  599. }
  600. template<>
  601. BX_SIMD_FORCE_INLINE simd128_ref_t simd_orx(simd128_ref_t _a)
  602. {
  603. return simd_orx_ni(_a);
  604. }
  605. template<>
  606. BX_SIMD_FORCE_INLINE simd128_ref_t simd_orc(simd128_ref_t _a, simd128_ref_t _b)
  607. {
  608. return simd_orc_ni(_a, _b);
  609. }
  610. template<>
  611. BX_SIMD_FORCE_INLINE simd128_ref_t simd_neg(simd128_ref_t _a)
  612. {
  613. return simd_neg_ni(_a);
  614. }
  615. template<>
  616. BX_SIMD_FORCE_INLINE simd128_ref_t simd_madd(simd128_ref_t _a, simd128_ref_t _b, simd128_ref_t _c)
  617. {
  618. return simd_madd_ni(_a, _b, _c);
  619. }
  620. template<>
  621. BX_SIMD_FORCE_INLINE simd128_ref_t simd_nmsub(simd128_ref_t _a, simd128_ref_t _b, simd128_ref_t _c)
  622. {
  623. return simd_nmsub_ni(_a, _b, _c);
  624. }
  625. template<>
  626. BX_SIMD_FORCE_INLINE simd128_ref_t simd_div_nr(simd128_ref_t _a, simd128_ref_t _b)
  627. {
  628. return simd_div_nr_ni(_a, _b);
  629. }
  630. template<>
  631. BX_SIMD_FORCE_INLINE simd128_ref_t simd_selb(simd128_ref_t _mask, simd128_ref_t _a, simd128_ref_t _b)
  632. {
  633. return simd_selb_ni(_mask, _a, _b);
  634. }
  635. template<>
  636. BX_SIMD_FORCE_INLINE simd128_ref_t simd_sels(simd128_ref_t _test, simd128_ref_t _a, simd128_ref_t _b)
  637. {
  638. return simd_sels_ni(_test, _a, _b);
  639. }
  640. template<>
  641. BX_SIMD_FORCE_INLINE simd128_ref_t simd_not(simd128_ref_t _a)
  642. {
  643. return simd_not_ni(_a);
  644. }
  645. template<>
  646. BX_SIMD_FORCE_INLINE simd128_ref_t simd_abs(simd128_ref_t _a)
  647. {
  648. return simd_abs_ni(_a);
  649. }
  650. template<>
  651. BX_SIMD_FORCE_INLINE simd128_ref_t simd_clamp(simd128_ref_t _a, simd128_ref_t _min, simd128_ref_t _max)
  652. {
  653. return simd_clamp_ni(_a, _min, _max);
  654. }
  655. template<>
  656. BX_SIMD_FORCE_INLINE simd128_ref_t simd_lerp(simd128_ref_t _a, simd128_ref_t _b, simd128_ref_t _s)
  657. {
  658. return simd_lerp_ni(_a, _b, _s);
  659. }
  660. template<>
  661. BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt(simd128_ref_t _a)
  662. {
  663. return simd_rsqrt_ni(_a);
  664. }
  665. template<>
  666. BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt_nr(simd128_ref_t _a)
  667. {
  668. return simd_rsqrt_nr_ni(_a);
  669. }
  670. template<>
  671. BX_SIMD_FORCE_INLINE simd128_ref_t simd_rsqrt_carmack(simd128_ref_t _a)
  672. {
  673. return simd_rsqrt_carmack_ni(_a);
  674. }
  675. template<>
  676. BX_SIMD_FORCE_INLINE simd128_ref_t simd_sqrt_nr(simd128_ref_t _a)
  677. {
  678. return simd_sqrt_nr_ni(_a);
  679. }
  680. template<>
  681. BX_SIMD_FORCE_INLINE simd128_ref_t simd_log2(simd128_ref_t _a)
  682. {
  683. return simd_log2_ni(_a);
  684. }
  685. template<>
  686. BX_SIMD_FORCE_INLINE simd128_ref_t simd_exp2(simd128_ref_t _a)
  687. {
  688. return simd_exp2_ni(_a);
  689. }
  690. template<>
  691. BX_SIMD_FORCE_INLINE simd128_ref_t simd_pow(simd128_ref_t _a, simd128_ref_t _b)
  692. {
  693. return simd_pow_ni(_a, _b);
  694. }
  695. template<>
  696. BX_SIMD_FORCE_INLINE simd128_ref_t simd_cross3(simd128_ref_t _a, simd128_ref_t _b)
  697. {
  698. return simd_cross3_ni(_a, _b);
  699. }
  700. template<>
  701. BX_SIMD_FORCE_INLINE simd128_ref_t simd_normalize3(simd128_ref_t _a)
  702. {
  703. return simd_normalize3_ni(_a);
  704. }
  705. template<>
  706. BX_SIMD_FORCE_INLINE simd128_ref_t simd_dot3(simd128_ref_t _a, simd128_ref_t _b)
  707. {
  708. return simd_dot3_ni(_a, _b);
  709. }
  710. template<>
  711. BX_SIMD_FORCE_INLINE simd128_ref_t simd_dot(simd128_ref_t _a, simd128_ref_t _b)
  712. {
  713. return simd_dot_ni(_a, _b);
  714. }
  715. template<>
  716. BX_SIMD_FORCE_INLINE simd128_ref_t simd_ceil(simd128_ref_t _a)
  717. {
  718. return simd_ceil_ni(_a);
  719. }
  720. template<>
  721. BX_SIMD_FORCE_INLINE simd128_ref_t simd_floor(simd128_ref_t _a)
  722. {
  723. return simd_floor_ni(_a);
  724. }
  725. } // namespace bx