2
0

core_func_integer.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2011-05-03
  5. // Updated : 2011-05-03
  6. // Licence : This source is under MIT licence
  7. // File : test/core/func_integer.cpp
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include <glm/integer.hpp>
  10. #include <glm/gtc/vec1.hpp>
  11. #include <vector>
  12. #include <ctime>
  13. #include <cstdio>
  14. enum result
  15. {
  16. SUCCESS,
  17. FAIL,
  18. ASSERT,
  19. STATIC_ASSERT
  20. };
  21. namespace bitfieldInsert
  22. {
  23. template <typename genType, typename sizeType>
  24. struct type
  25. {
  26. genType Base;
  27. genType Insert;
  28. sizeType Offset;
  29. sizeType Bits;
  30. genType Return;
  31. };
  32. typedef type<glm::uint, glm::uint> typeU32;
  33. typeU32 const Data32[] =
  34. {
  35. {0x00000000, 0xffffffff, 0, 31, 0x7fffffff},
  36. {0x00000000, 0xffffffff, 0, 32, 0xffffffff},
  37. {0x00000000, 0xffffffff, 0, 0, 0x00000000},
  38. {0xff000000, 0x0000ff00, 8, 8, 0xff00ff00},
  39. {0xffff0000, 0x0000ffff, 16, 16, 0x00000000},
  40. {0x0000ffff, 0xffff0000, 16, 16, 0xffffffff}
  41. };
  42. int test()
  43. {
  44. int Error = 0;
  45. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  46. for(glm::uint i = 0; i < count; ++i)
  47. {
  48. glm::uint Return = glm::bitfieldInsert(
  49. Data32[i].Base,
  50. Data32[i].Insert,
  51. Data32[i].Offset,
  52. Data32[i].Bits);
  53. Error += Data32[i].Return == Return ? 0 : 1;
  54. }
  55. return Error;
  56. }
  57. }//bitfieldInsert
  58. namespace bitfieldExtract
  59. {
  60. template <typename genType, typename sizeType>
  61. struct type
  62. {
  63. genType Value;
  64. sizeType Offset;
  65. sizeType Bits;
  66. genType Return;
  67. result Result;
  68. };
  69. typedef type<glm::uint, glm::uint> typeU32;
  70. typeU32 const Data32[] =
  71. {
  72. {0xffffffff, 0,32, 0xffffffff, SUCCESS},
  73. {0xffffffff, 8, 0, 0x00000000, SUCCESS},
  74. {0x00000000, 0,32, 0x00000000, SUCCESS},
  75. {0x0f0f0f0f, 0,32, 0x0f0f0f0f, SUCCESS},
  76. {0x00000000, 8, 0, 0x00000000, SUCCESS},
  77. {0x80000000,31, 1, 0x00000001, SUCCESS},
  78. {0x7fffffff,31, 1, 0x00000000, SUCCESS},
  79. {0x00000300, 8, 8, 0x00000003, SUCCESS},
  80. {0x0000ff00, 8, 8, 0x000000ff, SUCCESS},
  81. {0xfffffff0, 0, 5, 0x00000010, SUCCESS},
  82. {0x000000ff, 1, 3, 0x00000007, SUCCESS},
  83. {0x000000ff, 0, 3, 0x00000007, SUCCESS},
  84. {0x00000000, 0, 2, 0x00000000, SUCCESS},
  85. {0xffffffff, 0, 8, 0x000000ff, SUCCESS},
  86. {0xffff0000,16,16, 0x0000ffff, SUCCESS},
  87. {0xfffffff0, 0, 8, 0x00000000, FAIL},
  88. {0xffffffff,16,16, 0x00000000, FAIL},
  89. //{0xffffffff,32, 1, 0x00000000, ASSERT}, // Throw an assert
  90. //{0xffffffff, 0,33, 0x00000000, ASSERT}, // Throw an assert
  91. //{0xffffffff,16,16, 0x00000000, ASSERT}, // Throw an assert
  92. };
  93. int test()
  94. {
  95. int Error = 0;
  96. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  97. for(glm::uint i = 0; i < count; ++i)
  98. {
  99. glm::uint Return = glm::bitfieldExtract(
  100. Data32[i].Value,
  101. Data32[i].Offset,
  102. Data32[i].Bits);
  103. bool Compare = Data32[i].Return == Return;
  104. if(Data32[i].Result == SUCCESS && Compare)
  105. continue;
  106. else if(Data32[i].Result == FAIL && !Compare)
  107. continue;
  108. Error += 1;
  109. }
  110. return Error;
  111. }
  112. }//extractField
  113. namespace bitfieldReverse
  114. {
  115. template <typename genType>
  116. struct type
  117. {
  118. genType Value;
  119. genType Return;
  120. result Result;
  121. };
  122. typedef type<glm::uint> typeU32;
  123. typeU32 const Data32[] =
  124. {
  125. {0xffffffff, 0xffffffff, SUCCESS},
  126. {0x00000000, 0x00000000, SUCCESS},
  127. {0xf0000000, 0x0000000f, SUCCESS},
  128. };
  129. typedef type<glm::uint64> typeU64;
  130. #if(((GLM_COMPILER & GLM_COMPILER_GCC) == GLM_COMPILER_GCC) && (GLM_COMPILER < GLM_COMPILER_GCC44))
  131. typeU64 const Data64[] =
  132. {
  133. {0xffffffffffffffffLLU, 0xffffffffffffffffLLU, SUCCESS},
  134. {0x0000000000000000LLU, 0x0000000000000000LLU, SUCCESS},
  135. {0xf000000000000000LLU, 0x000000000000000fLLU, SUCCESS},
  136. };
  137. #else
  138. typeU64 const Data64[] =
  139. {
  140. {0xffffffffffffffff, 0xffffffffffffffff, SUCCESS},
  141. {0x0000000000000000, 0x0000000000000000, SUCCESS},
  142. {0xf000000000000000, 0x000000000000000f, SUCCESS},
  143. };
  144. #endif
  145. int test32()
  146. {
  147. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  148. for(glm::uint i = 0; i < count; ++i)
  149. {
  150. glm::uint Return = glm::bitfieldReverse(
  151. Data32[i].Value);
  152. bool Compare = Data32[i].Return == Return;
  153. if(Data32[i].Result == SUCCESS && Compare)
  154. continue;
  155. else if(Data32[i].Result == FAIL && !Compare)
  156. continue;
  157. std::printf("glm::bitfieldReverse test fail on test %d\n", static_cast<unsigned int>(i));
  158. return 1;
  159. }
  160. return 0;
  161. }
  162. int test64()
  163. {
  164. glm::uint32 count = sizeof(Data64) / sizeof(typeU64);
  165. for(glm::uint32 i = 0; i < count; ++i)
  166. {
  167. glm::uint64 Return = glm::bitfieldReverse(
  168. Data64[i].Value);
  169. bool Compare = Data64[i].Return == Return;
  170. if(Data64[i].Result == SUCCESS && Compare)
  171. continue;
  172. else if(Data64[i].Result == FAIL && !Compare)
  173. continue;
  174. std::printf("glm::extractfield test fail on test %d\n", static_cast<unsigned int>(i));
  175. return 1;
  176. }
  177. return 0;
  178. }
  179. int test()
  180. {
  181. int Error = 0;
  182. Error += test32();
  183. Error += test64();
  184. return Error;
  185. }
  186. }//bitfieldReverse
  187. namespace findMSB
  188. {
  189. template <typename genType>
  190. struct type
  191. {
  192. genType Value;
  193. genType Return;
  194. };
  195. template <typename genIUType>
  196. GLM_FUNC_QUALIFIER int findMSB_095(genIUType Value)
  197. {
  198. GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findMSB' only accept integer values");
  199. if(Value == genIUType(0) || Value == genIUType(-1))
  200. return -1;
  201. else if(Value > 0)
  202. {
  203. genIUType Bit = genIUType(-1);
  204. for(genIUType tmp = Value; tmp > 0; tmp >>= 1, ++Bit){}
  205. return Bit;
  206. }
  207. else //if(Value < 0)
  208. {
  209. int const BitCount(sizeof(genIUType) * 8);
  210. int MostSignificantBit(-1);
  211. for(int BitIndex(0); BitIndex < BitCount; ++BitIndex)
  212. MostSignificantBit = (Value & (1 << BitIndex)) ? MostSignificantBit : BitIndex;
  213. assert(MostSignificantBit >= 0);
  214. return MostSignificantBit;
  215. }
  216. }
  217. template <typename genIUType>
  218. GLM_FUNC_QUALIFIER int findMSB_nlz1(genIUType x)
  219. {
  220. GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findMSB' only accept integer values");
  221. /*
  222. int Result = 0;
  223. for(std::size_t i = 0, n = sizeof(genIUType) * 8; i < n; ++i)
  224. Result = Value & static_cast<genIUType>(1 << i) ? static_cast<int>(i) : Result;
  225. return Result;
  226. */
  227. /*
  228. genIUType Bit = genIUType(-1);
  229. for(genIUType tmp = Value; tmp > 0; tmp >>= 1, ++Bit){}
  230. return Bit;
  231. */
  232. int n;
  233. if (x == 0) return(32);
  234. n = 0;
  235. if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
  236. if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
  237. if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
  238. if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
  239. if (x <= 0x7FFFFFFF) {n = n + 1;}
  240. return n;
  241. }
  242. int findMSB_nlz2(unsigned int x)
  243. {
  244. unsigned y;
  245. int n;
  246. n = 32;
  247. y = x >>16; if (y != 0) {n = n -16; x = y;}
  248. y = x >> 8; if (y != 0) {n = n - 8; x = y;}
  249. y = x >> 4; if (y != 0) {n = n - 4; x = y;}
  250. y = x >> 2; if (y != 0) {n = n - 2; x = y;}
  251. y = x >> 1; if (y != 0) return n - 2;
  252. return n - x;
  253. }
  254. int perf_950()
  255. {
  256. type<glm::uint> const Data[] =
  257. {
  258. //{0x00000000, -1},
  259. {0x00000001, 0},
  260. {0x00000002, 1},
  261. {0x00000003, 1},
  262. {0x00000004, 2},
  263. {0x00000005, 2},
  264. {0x00000007, 2},
  265. {0x00000008, 3},
  266. {0x00000010, 4},
  267. {0x00000020, 5},
  268. {0x00000040, 6},
  269. {0x00000080, 7},
  270. {0x00000100, 8},
  271. {0x00000200, 9},
  272. {0x00000400, 10},
  273. {0x00000800, 11},
  274. {0x00001000, 12},
  275. {0x00002000, 13},
  276. {0x00004000, 14},
  277. {0x00008000, 15},
  278. {0x00010000, 16},
  279. {0x00020000, 17},
  280. {0x00040000, 18},
  281. {0x00080000, 19},
  282. {0x00100000, 20},
  283. {0x00200000, 21},
  284. {0x00400000, 22},
  285. {0x00800000, 23},
  286. {0x01000000, 24},
  287. {0x02000000, 25},
  288. {0x04000000, 26},
  289. {0x08000000, 27},
  290. {0x10000000, 28},
  291. {0x20000000, 29},
  292. {0x40000000, 30}
  293. };
  294. int Error(0);
  295. std::clock_t Timestamps1 = std::clock();
  296. for(std::size_t k = 0; k < 1000000; ++k)
  297. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<int>); ++i)
  298. {
  299. int Result = findMSB_095(Data[i].Value);
  300. Error += Data[i].Return == Result ? 0 : 1;
  301. }
  302. std::clock_t Timestamps2 = std::clock();
  303. std::printf("findMSB - 0.9.5: %d clocks\n", static_cast<unsigned int>(Timestamps2 - Timestamps1));
  304. return Error;
  305. }
  306. int perf_ops()
  307. {
  308. type<int> const Data[] =
  309. {
  310. {0x00000000, -1},
  311. {0x00000001, 0},
  312. {0x00000002, 1},
  313. {0x00000003, 1},
  314. {0x00000004, 2},
  315. {0x00000005, 2},
  316. {0x00000007, 2},
  317. {0x00000008, 3},
  318. {0x00000010, 4},
  319. {0x00000020, 5},
  320. {0x00000040, 6},
  321. {0x00000080, 7},
  322. {0x00000100, 8},
  323. {0x00000200, 9},
  324. {0x00000400, 10},
  325. {0x00000800, 11},
  326. {0x00001000, 12},
  327. {0x00002000, 13},
  328. {0x00004000, 14},
  329. {0x00008000, 15},
  330. {0x00010000, 16},
  331. {0x00020000, 17},
  332. {0x00040000, 18},
  333. {0x00080000, 19},
  334. {0x00100000, 20},
  335. {0x00200000, 21},
  336. {0x00400000, 22},
  337. {0x00800000, 23},
  338. {0x01000000, 24},
  339. {0x02000000, 25},
  340. {0x04000000, 26},
  341. {0x08000000, 27},
  342. {0x10000000, 28},
  343. {0x20000000, 29},
  344. {0x40000000, 30}
  345. };
  346. int Error(0);
  347. std::clock_t Timestamps1 = std::clock();
  348. for(std::size_t k = 0; k < 1000000; ++k)
  349. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<int>); ++i)
  350. {
  351. int Result = findMSB_nlz1(Data[i].Value);
  352. Error += Data[i].Return == Result ? 0 : 1;
  353. }
  354. std::clock_t Timestamps2 = std::clock();
  355. std::printf("findMSB - nlz1: %d clocks\n", static_cast<unsigned int>(Timestamps2 - Timestamps1));
  356. return Error;
  357. }
  358. int test_findMSB()
  359. {
  360. type<glm::uint> const Data[] =
  361. {
  362. //{0x00000000, -1},
  363. {0x00000001, 0},
  364. {0x00000002, 1},
  365. {0x00000003, 1},
  366. {0x00000004, 2},
  367. {0x00000005, 2},
  368. {0x00000007, 2},
  369. {0x00000008, 3},
  370. {0x00000010, 4},
  371. {0x00000020, 5},
  372. {0x00000040, 6},
  373. {0x00000080, 7},
  374. {0x00000100, 8},
  375. {0x00000200, 9},
  376. {0x00000400, 10},
  377. {0x00000800, 11},
  378. {0x00001000, 12},
  379. {0x00002000, 13},
  380. {0x00004000, 14},
  381. {0x00008000, 15},
  382. {0x00010000, 16},
  383. {0x00020000, 17},
  384. {0x00040000, 18},
  385. {0x00080000, 19},
  386. {0x00100000, 20},
  387. {0x00200000, 21},
  388. {0x00400000, 22},
  389. {0x00800000, 23},
  390. {0x01000000, 24},
  391. {0x02000000, 25},
  392. {0x04000000, 26},
  393. {0x08000000, 27},
  394. {0x10000000, 28},
  395. {0x20000000, 29},
  396. {0x40000000, 30}
  397. };
  398. int Error(0);
  399. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<int>); ++i)
  400. {
  401. int Result = glm::findMSB(Data[i].Value);
  402. Error += Data[i].Return == Result ? 0 : 1;
  403. assert(!Error);
  404. }
  405. return Error;
  406. }
  407. int test_nlz1()
  408. {
  409. type<glm::uint> const Data[] =
  410. {
  411. //{0x00000000, -1},
  412. {0x00000001, 0},
  413. {0x00000002, 1},
  414. {0x00000003, 1},
  415. {0x00000004, 2},
  416. {0x00000005, 2},
  417. {0x00000007, 2},
  418. {0x00000008, 3},
  419. {0x00000010, 4},
  420. {0x00000020, 5},
  421. {0x00000040, 6},
  422. {0x00000080, 7},
  423. {0x00000100, 8},
  424. {0x00000200, 9},
  425. {0x00000400, 10},
  426. {0x00000800, 11},
  427. {0x00001000, 12},
  428. {0x00002000, 13},
  429. {0x00004000, 14},
  430. {0x00008000, 15},
  431. {0x00010000, 16},
  432. {0x00020000, 17},
  433. {0x00040000, 18},
  434. {0x00080000, 19},
  435. {0x00100000, 20},
  436. {0x00200000, 21},
  437. {0x00400000, 22},
  438. {0x00800000, 23},
  439. {0x01000000, 24},
  440. {0x02000000, 25},
  441. {0x04000000, 26},
  442. {0x08000000, 27},
  443. {0x10000000, 28},
  444. {0x20000000, 29},
  445. {0x40000000, 30}
  446. };
  447. int Error(0);
  448. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<int>); ++i)
  449. {
  450. int Result = findMSB_nlz2(Data[i].Value);
  451. Error += Data[i].Return == Result ? 0 : 1;
  452. }
  453. return Error;
  454. }
  455. int test()
  456. {
  457. int Error(0);
  458. Error += test_findMSB();
  459. //Error += test_nlz1();
  460. return Error;
  461. }
  462. int perf()
  463. {
  464. int Error(0);
  465. Error += perf_950();
  466. //Error += perf_ops();
  467. return Error;
  468. }
  469. }//findMSB
  470. namespace findLSB
  471. {
  472. template <typename genType>
  473. struct type
  474. {
  475. genType Value;
  476. genType Return;
  477. };
  478. type<int> const DataI32[] =
  479. {
  480. {0x00000001, 0},
  481. {0x00000003, 0},
  482. {0x00000002, 1}
  483. };
  484. int test()
  485. {
  486. int Error(0);
  487. for(std::size_t i = 0; i < sizeof(DataI32) / sizeof(type<int>); ++i)
  488. {
  489. int Result = glm::findLSB(DataI32[i].Value);
  490. Error += DataI32[i].Return == Result ? 0 : 1;
  491. assert(!Error);
  492. }
  493. return Error;
  494. }
  495. }//findLSB
  496. namespace uaddCarry
  497. {
  498. int test()
  499. {
  500. int Error(0);
  501. {
  502. glm::uint x = 16;
  503. glm::uint y = 17;
  504. glm::uint Carry = 0;
  505. glm::uint Result = glm::uaddCarry(x, y, Carry);
  506. Error += Carry == 1 ? 0 : 1;
  507. Error += Result == 33 ? 0 : 1;
  508. }
  509. {
  510. glm::uvec1 x(16);
  511. glm::uvec1 y(17);
  512. glm::uvec1 Carry(0);
  513. glm::uvec1 Result(glm::uaddCarry(x, y, Carry));
  514. Error += glm::all(glm::equal(Carry, glm::uvec1(1))) ? 0 : 1;
  515. Error += glm::all(glm::equal(Result, glm::uvec1(33))) ? 0 : 1;
  516. }
  517. {
  518. glm::uvec2 x(16);
  519. glm::uvec2 y(17);
  520. glm::uvec2 Carry(0);
  521. glm::uvec2 Result(glm::uaddCarry(x, y, Carry));
  522. Error += glm::all(glm::equal(Carry, glm::uvec2(1))) ? 0 : 1;
  523. Error += glm::all(glm::equal(Result, glm::uvec2(33))) ? 0 : 1;
  524. }
  525. {
  526. glm::uvec3 x(16);
  527. glm::uvec3 y(17);
  528. glm::uvec3 Carry(0);
  529. glm::uvec3 Result(glm::uaddCarry(x, y, Carry));
  530. Error += glm::all(glm::equal(Carry, glm::uvec3(1))) ? 0 : 1;
  531. Error += glm::all(glm::equal(Result, glm::uvec3(33))) ? 0 : 1;
  532. }
  533. {
  534. glm::uvec4 x(16);
  535. glm::uvec4 y(17);
  536. glm::uvec4 Carry(0);
  537. glm::uvec4 Result(glm::uaddCarry(x, y, Carry));
  538. Error += glm::all(glm::equal(Carry, glm::uvec4(1))) ? 0 : 1;
  539. Error += glm::all(glm::equal(Result, glm::uvec4(33))) ? 0 : 1;
  540. }
  541. return Error;
  542. }
  543. }//namespace uaddCarry
  544. namespace usubBorrow
  545. {
  546. int test()
  547. {
  548. int Error(0);
  549. {
  550. glm::uint x = 16;
  551. glm::uint y = 17;
  552. glm::uint Borrow = 0;
  553. glm::uint Result = glm::usubBorrow(x, y, Borrow);
  554. Error += Borrow == 1 ? 0 : 1;
  555. Error += Result == 1 ? 0 : 1;
  556. }
  557. {
  558. glm::uvec1 x(16);
  559. glm::uvec1 y(17);
  560. glm::uvec1 Borrow(0);
  561. glm::uvec1 Result(glm::usubBorrow(x, y, Borrow));
  562. Error += glm::all(glm::equal(Borrow, glm::uvec1(1))) ? 0 : 1;
  563. Error += glm::all(glm::equal(Result, glm::uvec1(1))) ? 0 : 1;
  564. }
  565. {
  566. glm::uvec2 x(16);
  567. glm::uvec2 y(17);
  568. glm::uvec2 Borrow(0);
  569. glm::uvec2 Result(glm::usubBorrow(x, y, Borrow));
  570. Error += glm::all(glm::equal(Borrow, glm::uvec2(1))) ? 0 : 1;
  571. Error += glm::all(glm::equal(Result, glm::uvec2(1))) ? 0 : 1;
  572. }
  573. {
  574. glm::uvec3 x(16);
  575. glm::uvec3 y(17);
  576. glm::uvec3 Borrow(0);
  577. glm::uvec3 Result(glm::usubBorrow(x, y, Borrow));
  578. Error += glm::all(glm::equal(Borrow, glm::uvec3(1))) ? 0 : 1;
  579. Error += glm::all(glm::equal(Result, glm::uvec3(1))) ? 0 : 1;
  580. }
  581. {
  582. glm::uvec4 x(16);
  583. glm::uvec4 y(17);
  584. glm::uvec4 Borrow(0);
  585. glm::uvec4 Result(glm::usubBorrow(x, y, Borrow));
  586. Error += glm::all(glm::equal(Borrow, glm::uvec4(1))) ? 0 : 1;
  587. Error += glm::all(glm::equal(Result, glm::uvec4(1))) ? 0 : 1;
  588. }
  589. return Error;
  590. }
  591. }//namespace usubBorrow
  592. namespace umulExtended
  593. {
  594. int test()
  595. {
  596. int Error(0);
  597. {
  598. glm::uint x = 2;
  599. glm::uint y = 3;
  600. glm::uint msb = 0;
  601. glm::uint lsb = 0;
  602. glm::umulExtended(x, y, msb, lsb);
  603. Error += msb == 0 ? 0 : 1;
  604. Error += lsb == 6 ? 0 : 1;
  605. }
  606. {
  607. glm::uvec1 x(2);
  608. glm::uvec1 y(3);
  609. glm::uvec1 msb(0);
  610. glm::uvec1 lsb(0);
  611. glm::umulExtended(x, y, msb, lsb);
  612. Error += glm::all(glm::equal(msb, glm::uvec1(0))) ? 0 : 1;
  613. Error += glm::all(glm::equal(lsb, glm::uvec1(6))) ? 0 : 1;
  614. }
  615. {
  616. glm::uvec2 x(2);
  617. glm::uvec2 y(3);
  618. glm::uvec2 msb(0);
  619. glm::uvec2 lsb(0);
  620. glm::umulExtended(x, y, msb, lsb);
  621. Error += glm::all(glm::equal(msb, glm::uvec2(0))) ? 0 : 1;
  622. Error += glm::all(glm::equal(lsb, glm::uvec2(6))) ? 0 : 1;
  623. }
  624. {
  625. glm::uvec3 x(2);
  626. glm::uvec3 y(3);
  627. glm::uvec3 msb(0);
  628. glm::uvec3 lsb(0);
  629. glm::umulExtended(x, y, msb, lsb);
  630. Error += glm::all(glm::equal(msb, glm::uvec3(0))) ? 0 : 1;
  631. Error += glm::all(glm::equal(lsb, glm::uvec3(6))) ? 0 : 1;
  632. }
  633. {
  634. glm::uvec4 x(2);
  635. glm::uvec4 y(3);
  636. glm::uvec4 msb(0);
  637. glm::uvec4 lsb(0);
  638. glm::umulExtended(x, y, msb, lsb);
  639. Error += glm::all(glm::equal(msb, glm::uvec4(0))) ? 0 : 1;
  640. Error += glm::all(glm::equal(lsb, glm::uvec4(6))) ? 0 : 1;
  641. }
  642. return Error;
  643. }
  644. }//namespace umulExtended
  645. namespace imulExtended
  646. {
  647. int test()
  648. {
  649. int Error(0);
  650. {
  651. int x = 2;
  652. int y = 3;
  653. int msb = 0;
  654. int lsb = 0;
  655. glm::imulExtended(x, y, msb, lsb);
  656. Error += msb == 0 ? 0 : 1;
  657. Error += lsb == 6 ? 0 : 1;
  658. }
  659. {
  660. glm::ivec1 x(2);
  661. glm::ivec1 y(3);
  662. glm::ivec1 msb(0);
  663. glm::ivec1 lsb(0);
  664. glm::imulExtended(x, y, msb, lsb);
  665. Error += glm::all(glm::equal(msb, glm::ivec1(0))) ? 0 : 1;
  666. Error += glm::all(glm::equal(lsb, glm::ivec1(6))) ? 0 : 1;
  667. }
  668. {
  669. glm::ivec2 x(2);
  670. glm::ivec2 y(3);
  671. glm::ivec2 msb(0);
  672. glm::ivec2 lsb(0);
  673. glm::imulExtended(x, y, msb, lsb);
  674. Error += glm::all(glm::equal(msb, glm::ivec2(0))) ? 0 : 1;
  675. Error += glm::all(glm::equal(lsb, glm::ivec2(6))) ? 0 : 1;
  676. }
  677. {
  678. glm::ivec3 x(2);
  679. glm::ivec3 y(3);
  680. glm::ivec3 msb(0);
  681. glm::ivec3 lsb(0);
  682. glm::imulExtended(x, y, msb, lsb);
  683. Error += glm::all(glm::equal(msb, glm::ivec3(0))) ? 0 : 1;
  684. Error += glm::all(glm::equal(lsb, glm::ivec3(6))) ? 0 : 1;
  685. }
  686. {
  687. glm::ivec4 x(2);
  688. glm::ivec4 y(3);
  689. glm::ivec4 msb(0);
  690. glm::ivec4 lsb(0);
  691. glm::imulExtended(x, y, msb, lsb);
  692. Error += glm::all(glm::equal(msb, glm::ivec4(0))) ? 0 : 1;
  693. Error += glm::all(glm::equal(lsb, glm::ivec4(6))) ? 0 : 1;
  694. }
  695. return Error;
  696. }
  697. }//namespace imulExtended
  698. namespace bitCount
  699. {
  700. template <typename genType>
  701. struct type
  702. {
  703. genType Value;
  704. genType Return;
  705. };
  706. type<int> const DataI32[] =
  707. {
  708. {0x00000001, 1},
  709. {0x00000003, 2},
  710. {0x00000002, 1},
  711. {0x7fffffff, 31},
  712. {0x00000000, 0}
  713. };
  714. template <typename T>
  715. inline int bitCount_if(T v)
  716. {
  717. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
  718. int Count(0);
  719. for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
  720. {
  721. if(v & static_cast<T>(1 << i))
  722. ++Count;
  723. }
  724. return Count;
  725. }
  726. template <typename T>
  727. inline int bitCount_vec(T v)
  728. {
  729. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
  730. int Count(0);
  731. for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
  732. {
  733. Count += static_cast<int>((v >> i) & static_cast<T>(1));
  734. }
  735. return Count;
  736. }
  737. int perf()
  738. {
  739. int Error(0);
  740. std::size_t Size = 10000000;
  741. std::vector<int> v;
  742. v.resize(Size);
  743. std::vector<glm::ivec4> w;
  744. w.resize(Size);
  745. std::clock_t TimestampsA = std::clock();
  746. // bitCount - TimeIf
  747. {
  748. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  749. v[i] = bitCount_if(i);
  750. }
  751. std::clock_t TimestampsB = std::clock();
  752. // bitCount - TimeVec
  753. {
  754. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  755. v[i] = bitCount_vec(i);
  756. }
  757. std::clock_t TimestampsC = std::clock();
  758. // bitCount - TimeDefault
  759. {
  760. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  761. v[i] = glm::bitCount(i);
  762. }
  763. std::clock_t TimestampsD = std::clock();
  764. // bitCount - TimeVec4
  765. {
  766. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  767. w[i] = glm::bitCount(glm::ivec4(i));
  768. }
  769. std::clock_t TimestampsE = std::clock();
  770. std::clock_t TimeIf = TimestampsB - TimestampsA;
  771. std::clock_t TimeVec = TimestampsC - TimestampsB;
  772. std::clock_t TimeDefault = TimestampsD - TimestampsC;
  773. std::clock_t TimeVec4 = TimestampsE - TimestampsD;
  774. std::printf("bitCount - TimeIf %d\n", static_cast<unsigned int>(TimeIf));
  775. std::printf("bitCount - TimeVec %d\n", static_cast<unsigned int>(TimeVec));
  776. std::printf("bitCount - TimeDefault %d\n", static_cast<unsigned int>(TimeDefault));
  777. std::printf("bitCount - TimeVec4 %d\n", static_cast<unsigned int>(TimeVec4));
  778. return Error;
  779. }
  780. int test()
  781. {
  782. int Error(0);
  783. for(std::size_t i = 0, n = sizeof(DataI32) / sizeof(type<int>); i < n; ++i)
  784. {
  785. int Result = glm::bitCount(DataI32[i].Value);
  786. Error += DataI32[i].Return == Result ? 0 : 1;
  787. assert(!Error);
  788. }
  789. return Error;
  790. }
  791. }//bitCount
  792. int main()
  793. {
  794. int Error = 0;
  795. Error += ::findMSB::test();
  796. Error += ::findMSB::perf();
  797. Error += ::findLSB::test();
  798. Error += ::umulExtended::test();
  799. Error += ::imulExtended::test();
  800. Error += ::uaddCarry::test();
  801. Error += ::usubBorrow::test();
  802. Error += ::bitfieldInsert::test();
  803. Error += ::bitfieldExtract::test();
  804. Error += ::bitfieldReverse::test();
  805. Error += ::bitCount::test();
  806. Error += ::bitCount::perf();
  807. return Error;
  808. }