core_func_integer.cpp 20 KB

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