math.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. math.c
  5. Abstract:
  6. This module implements math support routines needed by the kernel.
  7. Author:
  8. Evan Green 24-Jul-2012
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "rtlp.h"
  16. //
  17. // ---------------------------------------------------------------- Definitions
  18. //
  19. #define LONG_BITS (sizeof(LONG) * BITS_PER_BYTE)
  20. #define ULONG_BITS (sizeof(ULONG) * BITS_PER_BYTE)
  21. #define LONGLONG_BITS (sizeof(LONGLONG) * BITS_PER_BYTE)
  22. #define ULONGLONG_BITS (sizeof(ULONGLONG) * BITS_PER_BYTE)
  23. //
  24. // ----------------------------------------------- Internal Function Prototypes
  25. //
  26. //
  27. // ------------------------------------------------------ Data Type Definitions
  28. //
  29. //
  30. // -------------------------------------------------------------------- Globals
  31. //
  32. //
  33. // Use a small table for determining how many bits are set in a nibble.
  34. //
  35. CHAR RtlSetBitCounts[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  36. //
  37. // ------------------------------------------------------------------ Functions
  38. //
  39. RTL_API
  40. BOOL
  41. RtlAreUuidsEqual (
  42. PUUID Uuid1,
  43. PUUID Uuid2
  44. )
  45. /*++
  46. Routine Description:
  47. This routine compares two UUIDs.
  48. Arguments:
  49. Uuid1 - Supplies the first UUID.
  50. Uuid2 - Supplies the second UUID.
  51. Return Value:
  52. TRUE if the UUIDs are equal.
  53. FALSE if the UUIDs are not equal.
  54. --*/
  55. {
  56. if ((Uuid1->Data[0] == Uuid2->Data[0]) &&
  57. (Uuid1->Data[1] == Uuid2->Data[1]) &&
  58. (Uuid1->Data[2] == Uuid2->Data[2]) &&
  59. (Uuid1->Data[3] == Uuid2->Data[3])) {
  60. return TRUE;
  61. }
  62. return FALSE;
  63. }
  64. RTL_API
  65. ULONGLONG
  66. RtlDivideUnsigned64 (
  67. ULONGLONG Dividend,
  68. ULONGLONG Divisor,
  69. PULONGLONG Remainder
  70. )
  71. /*++
  72. Routine Description:
  73. This routine performs a 64-bit divide of two unsigned numbers.
  74. Arguments:
  75. Dividend - Supplies the number that is going to be divided (the numerator).
  76. Divisor - Supplies the number to divide into (the denominator).
  77. Remainder - Supplies a pointer that receives the remainder of the
  78. divide. This parameter may be NULL.
  79. Return Value:
  80. Returns the quotient.
  81. --*/
  82. {
  83. ULONG Carry;
  84. ULONGLONG_PARTS Denominator;
  85. LONGLONG Difference;
  86. ULONGLONG_PARTS Numerator;
  87. ULONGLONG_PARTS QuotientParts;
  88. ULONGLONG_PARTS RemainderParts;
  89. ULONGLONG ShiftRight;
  90. Numerator.Ulonglong = Dividend;
  91. Denominator.Ulonglong = Divisor;
  92. ASSERT(Divisor != 0);
  93. //
  94. // Handle the numerator being zero.
  95. //
  96. if (Numerator.Ulong.High == 0) {
  97. //
  98. // If the denominator is 0 too, this just a 32 bit divide.
  99. //
  100. if (Denominator.Ulong.High == 0) {
  101. if (Remainder != NULL) {
  102. *Remainder = Numerator.Ulong.Low % Denominator.Ulong.Low;
  103. }
  104. return Numerator.Ulong.Low / Denominator.Ulong.Low;
  105. }
  106. //
  107. // This is a 32-bit value divided by a large 64-bit value. It will
  108. // be zero, remainder the value.
  109. //
  110. if (Remainder != NULL) {
  111. *Remainder = Numerator.Ulong.Low;
  112. }
  113. return 0;
  114. }
  115. //
  116. // The numerator is fully 64 bits. Check to see if the denominator has a
  117. // low part.
  118. //
  119. if (Denominator.Ulong.Low == 0) {
  120. //
  121. // Handle divide by zero.
  122. //
  123. if (Denominator.Ulong.High == 0) {
  124. if (Remainder != NULL) {
  125. *Remainder = Numerator.Ulong.High % Denominator.Ulong.Low;
  126. }
  127. return Numerator.Ulong.High / Denominator.Ulong.Low;
  128. }
  129. //
  130. // The denominator has a high part, but no low part. If the numerator
  131. // has no low part then this is n00000000 / d00000000.
  132. //
  133. if (Numerator.Ulong.Low == 0) {
  134. if (Remainder != NULL) {
  135. RemainderParts.Ulong.High = Numerator.Ulong.High %
  136. Denominator.Ulong.High;
  137. RemainderParts.Ulong.Low = 0;
  138. *Remainder = RemainderParts.Ulonglong;
  139. }
  140. return Numerator.Ulong.High / Denominator.Ulong.High;
  141. }
  142. //
  143. // The numerator is a full 64 bit value, but the denominator has 8
  144. // zeros at the end. Check to see if the denominator is a power of 2.
  145. //
  146. if ((Denominator.Ulong.High & (Denominator.Ulong.High - 1)) == 0) {
  147. if (Remainder != NULL) {
  148. RemainderParts.Ulong.Low = Numerator.Ulong.Low;
  149. RemainderParts.Ulong.High = Numerator.Ulong.High &
  150. (Denominator.Ulong.High - 1);
  151. *Remainder = RemainderParts.Ulonglong;
  152. }
  153. QuotientParts.Ulonglong = Numerator.Ulong.High >>
  154. __builtin_ctz(Denominator.Ulong.High);
  155. return QuotientParts.Ulonglong;
  156. }
  157. //
  158. // The denominator is not a power of 2 (but does have 8 trailing
  159. // zeros). Do the full divide.
  160. //
  161. ShiftRight = __builtin_clz(Denominator.Ulong.High) -
  162. __builtin_clz(Numerator.Ulong.High);
  163. if (ShiftRight > (ULONG_BITS - 2)) {
  164. if (Remainder != NULL) {
  165. *Remainder = Numerator.Ulonglong;
  166. }
  167. return 0;
  168. }
  169. ShiftRight += 1;
  170. QuotientParts.Ulong.Low = 0;
  171. QuotientParts.Ulong.High =
  172. Numerator.Ulong.Low << (ULONG_BITS - ShiftRight);
  173. RemainderParts.Ulong.High = Numerator.Ulong.High >> ShiftRight;
  174. RemainderParts.Ulong.Low =
  175. (Numerator.Ulong.High <<
  176. (ULONG_BITS - ShiftRight)) |
  177. (Numerator.Ulong.Low >> ShiftRight);
  178. //
  179. // The denominator has a non-zero low part.
  180. //
  181. } else {
  182. //
  183. // Handle the high part of the denominator being zero, 64 / 32.
  184. //
  185. if (Denominator.Ulong.High == 0) {
  186. //
  187. // Check for a power of 2.
  188. //
  189. if ((Denominator.Ulong.Low & (Denominator.Ulong.Low - 1)) == 0) {
  190. if (Remainder != NULL) {
  191. *Remainder = Numerator.Ulong.Low &
  192. (Denominator.Ulong.Low - 1);
  193. }
  194. if (Denominator.Ulong.Low == 1) {
  195. return Numerator.Ulonglong;
  196. }
  197. ShiftRight = __builtin_ctz(Denominator.Ulong.Low);
  198. QuotientParts.Ulong.High = Numerator.Ulong.High >> ShiftRight;
  199. QuotientParts.Ulong.Low =
  200. (Numerator.Ulong.High <<
  201. (ULONG_BITS - ShiftRight)) |
  202. (Numerator.Ulong.Low >> ShiftRight);
  203. return QuotientParts.Ulonglong;
  204. }
  205. //
  206. // This is a full 64 / 32. The remainder is Numerator >> ShiftRight,
  207. // and the quotient is the numerator << (64 - ShiftRight).
  208. //
  209. ShiftRight = ULONG_BITS + 1 + __builtin_clz(Denominator.Ulong.Low) -
  210. __builtin_clz(Numerator.Ulong.High);
  211. if (ShiftRight == ULONG_BITS) {
  212. QuotientParts.Ulong.Low = 0;
  213. QuotientParts.Ulong.High = Numerator.Ulong.Low;
  214. RemainderParts.Ulong.Low = Numerator.Ulong.High;
  215. RemainderParts.Ulong.High = 0;
  216. //
  217. // The shift right is at least 2, but less than a full rotation.
  218. //
  219. } else if (ShiftRight < ULONG_BITS) {
  220. QuotientParts.Ulong.Low = 0;
  221. QuotientParts.Ulong.High =
  222. Numerator.Ulong.Low << (ULONG_BITS - ShiftRight);
  223. RemainderParts.Ulong.Low =
  224. (Numerator.Ulong.High << (ULONG_BITS - ShiftRight)) |
  225. (Numerator.Ulong.Low >> ShiftRight);
  226. RemainderParts.Ulong.High = Numerator.Ulong.High >> ShiftRight;
  227. //
  228. // The shift right is somewhere between 32 and 64.
  229. //
  230. } else {
  231. QuotientParts.Ulong.Low =
  232. Numerator.Ulong.Low << (ULONGLONG_BITS - ShiftRight);
  233. QuotientParts.Ulong.High =
  234. (Numerator.Ulong.High << (ULONGLONG_BITS - ShiftRight)) |
  235. (Numerator.Ulong.Low >> (ShiftRight - ULONG_BITS));
  236. RemainderParts.Ulong.Low =
  237. Numerator.Ulong.High >> (ShiftRight - ULONG_BITS);
  238. RemainderParts.Ulong.High = 0;
  239. }
  240. //
  241. // The denominator is the full 64 bits long, and the numerator has
  242. // stuff in the high bits.
  243. //
  244. } else {
  245. ShiftRight = __builtin_clz(Denominator.Ulong.High) -
  246. __builtin_clz(Numerator.Ulong.High);
  247. if (ShiftRight > ULONG_BITS - 1) {
  248. if (Remainder != NULL) {
  249. *Remainder = Numerator.Ulonglong;
  250. }
  251. return 0;
  252. }
  253. ShiftRight += 1;
  254. //
  255. // The shift is somewhere between 1 and 32, inclusive. The quotient
  256. // is Numerator << (64 - ShiftCount).
  257. //
  258. QuotientParts.Ulong.Low = 0;
  259. if (ShiftRight == ULONG_BITS) {
  260. QuotientParts.Ulong.High = Numerator.Ulong.Low;
  261. RemainderParts.Ulong.Low = Numerator.Ulong.High;
  262. RemainderParts.Ulong.High = 0;
  263. } else {
  264. QuotientParts.Ulong.High =
  265. Numerator.Ulong.Low << (ULONG_BITS - ShiftRight);
  266. RemainderParts.Ulong.Low =
  267. (Numerator.Ulong.High << (ULONG_BITS - ShiftRight)) |
  268. (Numerator.Ulong.Low >> ShiftRight);
  269. RemainderParts.Ulong.High =
  270. Numerator.Ulong.High >> ShiftRight;
  271. }
  272. }
  273. }
  274. //
  275. // Enough weaseling, just do the divide. The quotient is currently
  276. // initialized with Numerator << (64 - ShiftRight), and the remainder is
  277. // Numerator >> ShiftRight. ShiftRight is somewhere between 1 and 63,
  278. // inclusive.
  279. //
  280. Carry = 0;
  281. while (ShiftRight > 0) {
  282. RemainderParts.Ulong.High =
  283. (RemainderParts.Ulong.High << 1) |
  284. (RemainderParts.Ulong.Low >> (ULONG_BITS - 1));
  285. RemainderParts.Ulong.Low =
  286. (RemainderParts.Ulong.Low << 1) |
  287. (QuotientParts.Ulong.High >> (ULONG_BITS - 1));
  288. QuotientParts.Ulong.High =
  289. (QuotientParts.Ulong.High << 1) |
  290. (QuotientParts.Ulong.Low >> (ULONG_BITS - 1));
  291. QuotientParts.Ulong.Low = (QuotientParts.Ulong.Low << 1) | Carry;
  292. //
  293. // If the remainder is greater than or equal to the denominator, set
  294. // the carry and subtract the denominator to get it back in proper
  295. // remainder range.
  296. //
  297. Difference =
  298. (LONGLONG)(Denominator.Ulonglong -
  299. RemainderParts.Ulonglong - 1) >>
  300. (ULONGLONG_BITS - 1);
  301. Carry = Difference & 0x1;
  302. RemainderParts.Ulonglong -= Denominator.Ulonglong & Difference;
  303. ShiftRight -= 1;
  304. }
  305. QuotientParts.Ulonglong = (QuotientParts.Ulonglong << 1) | Carry;
  306. if (Remainder != NULL) {
  307. *Remainder = RemainderParts.Ulonglong;
  308. }
  309. return QuotientParts.Ulonglong;
  310. }
  311. RTL_API
  312. LONGLONG
  313. RtlDivide64 (
  314. LONGLONG Dividend,
  315. LONGLONG Divisor
  316. )
  317. /*++
  318. Routine Description:
  319. This routine performs a 64-bit divide of two signed numbers.
  320. Arguments:
  321. Dividend - Supplies the number that is going to be divided (the numerator).
  322. Divisor - Supplies the number to divide into (the denominator).
  323. Return Value:
  324. Returns the quotient.
  325. --*/
  326. {
  327. LONGLONG DenominatorSign;
  328. LONGLONG NumeratorSign;
  329. LONGLONG Quotient;
  330. //
  331. // Negate the numerator and denominator if they're less than zero.
  332. //
  333. NumeratorSign = Dividend >> (LONGLONG_BITS - 1);
  334. DenominatorSign = Divisor >> (LONGLONG_BITS - 1);
  335. Dividend = (Dividend ^ NumeratorSign) - NumeratorSign;
  336. Divisor = (Divisor ^ DenominatorSign) - DenominatorSign;
  337. //
  338. // Get the sign of the quotient.
  339. //
  340. NumeratorSign ^= DenominatorSign;
  341. Quotient = (RtlDivideUnsigned64(Dividend, Divisor, NULL) ^ NumeratorSign) -
  342. NumeratorSign;
  343. return Quotient;
  344. }
  345. RTL_API
  346. LONGLONG
  347. RtlDivideModulo64 (
  348. LONGLONG Dividend,
  349. LONGLONG Divisor,
  350. PLONGLONG Remainder
  351. )
  352. /*++
  353. Routine Description:
  354. This routine performs a 64-bit divide and modulo of two signed numbers.
  355. Arguments:
  356. Dividend - Supplies the number that is going to be divided (the numerator).
  357. Divisor - Supplies the number to divide into (the denominator).
  358. Remainder - Supplies a pointer where the remainder will be returned.
  359. Return Value:
  360. Returns the quotient.
  361. --*/
  362. {
  363. LONGLONG Quotient;
  364. Quotient = RtlDivide64(Dividend, Divisor);
  365. *Remainder = Dividend - (Quotient * Divisor);
  366. return Quotient;
  367. }
  368. RTL_API
  369. ULONG
  370. RtlDivideUnsigned32 (
  371. ULONG Dividend,
  372. ULONG Divisor,
  373. PULONG Remainder
  374. )
  375. /*++
  376. Routine Description:
  377. This routine performs a 32-bit divide of two unsigned numbers.
  378. Arguments:
  379. Dividend - Supplies the number that is going to be divided (the numerator).
  380. Divisor - Supplies the number to divide into (the denominator).
  381. Remainder - Supplies an optional pointer where the remainder will be
  382. returned.
  383. Return Value:
  384. Returns the quotient.
  385. --*/
  386. {
  387. ULONG Carry;
  388. LONG Difference;
  389. ULONG Quotient;
  390. ULONG RemainderValue;
  391. ULONG ShiftRight;
  392. //
  393. // Handle divide by zero.
  394. //
  395. if (Divisor == 0) {
  396. ASSERT(Divisor != 0);
  397. if (Remainder != NULL) {
  398. *Remainder = 0;
  399. }
  400. return 0;
  401. }
  402. if (Dividend == 0) {
  403. if (Remainder != NULL) {
  404. *Remainder = 0;
  405. }
  406. return 0;
  407. }
  408. ShiftRight = __builtin_clz(Divisor) - __builtin_clz(Dividend);
  409. if (ShiftRight > (ULONG_BITS - 1)) {
  410. if (Remainder != NULL) {
  411. *Remainder = Dividend;
  412. }
  413. return 0;
  414. }
  415. if (ShiftRight == (ULONG_BITS - 1)) {
  416. if (Remainder != NULL) {
  417. *Remainder = 0;
  418. }
  419. return Dividend;
  420. }
  421. ShiftRight += 1;
  422. Quotient = Dividend << (ULONG_BITS - ShiftRight);
  423. RemainderValue = Dividend >> ShiftRight;
  424. Carry = 0;
  425. while (ShiftRight > 0) {
  426. RemainderValue = (RemainderValue << 1) | (Quotient >> (ULONG_BITS - 1));
  427. Quotient = (Quotient << 1) | Carry;
  428. //
  429. // If the remainder is greater than the divisor, set the carry and
  430. // subtract a divisor from the remainder to get it back in range.
  431. //
  432. Difference = (LONG)(Divisor - RemainderValue - 1) >> (ULONG_BITS - 1);
  433. Carry = Difference & 0x1;
  434. RemainderValue -= Divisor & Difference;
  435. ShiftRight -= 1;
  436. }
  437. Quotient = (Quotient << 1) | Carry;
  438. if (Remainder != NULL) {
  439. *Remainder = RemainderValue;
  440. }
  441. return Quotient;
  442. }
  443. RTL_API
  444. LONG
  445. RtlDivide32 (
  446. LONG Dividend,
  447. LONG Divisor
  448. )
  449. /*++
  450. Routine Description:
  451. This routine performs a 32-bit divide of two signed numbers.
  452. Arguments:
  453. Dividend - Supplies the number that is going to be divided (the numerator).
  454. Divisor - Supplies the number to divide into (the denominator).
  455. Return Value:
  456. Returns the quotient.
  457. --*/
  458. {
  459. LONG DenominatorSign;
  460. LONG NumeratorSign;
  461. //
  462. // Negate the numerator and denominator if they are negative.
  463. //
  464. NumeratorSign = Dividend >> (LONG_BITS - 1);
  465. DenominatorSign = Divisor >> (LONG_BITS - 1);
  466. Dividend = (Dividend ^ NumeratorSign) - NumeratorSign;
  467. Divisor = (Divisor ^ DenominatorSign) - DenominatorSign;
  468. //
  469. // Compute the sign of the quotient.
  470. //
  471. NumeratorSign ^= DenominatorSign;
  472. //
  473. // Perform an unsigned divide. The hope is that the architecture has an
  474. // unsigned divide instruction. If not, then the soft divide unsigned
  475. // gets called.
  476. //
  477. return (((ULONG)Dividend / (ULONG)Divisor) ^ NumeratorSign) - NumeratorSign;
  478. }
  479. RTL_API
  480. LONG
  481. RtlDivideModulo32 (
  482. LONG Dividend,
  483. LONG Divisor,
  484. PLONG Remainder
  485. )
  486. /*++
  487. Routine Description:
  488. This routine performs a 32-bit divide and modulo of two signed numbers.
  489. Arguments:
  490. Dividend - Supplies the number that is going to be divided (the numerator).
  491. Divisor - Supplies the number to divide into (the denominator).
  492. Remainder - Supplies a pointer where the remainder will be returned.
  493. Return Value:
  494. Returns the quotient.
  495. --*/
  496. {
  497. LONG Quotient;
  498. Quotient = RtlDivide32(Dividend, Divisor);
  499. *Remainder = Dividend - (Quotient * Divisor);
  500. return Quotient;
  501. }
  502. RTL_API
  503. ULONGLONG
  504. RtlByteSwapUlonglong (
  505. ULONGLONG Input
  506. )
  507. /*++
  508. Routine Description:
  509. This routine performs a byte-swap of a 64-bit integer, effectively changing
  510. its endianness.
  511. Arguments:
  512. Input - Supplies the integer to byte swap.
  513. Return Value:
  514. Returns the byte-swapped integer.
  515. --*/
  516. {
  517. ULONGLONG Result;
  518. Result = (Input >> 32) | (Input << 32);
  519. Result = ((Result & 0xFF00FF00FF00FF00ULL) >> 8) |
  520. ((Result & 0x00FF00FF00FF00FFULL) << 8);
  521. Result = ((Result & 0xFFFF0000FFFF0000ULL) >> 16) |
  522. ((Result & 0x0000FFFF0000FFFFULL) << 16);
  523. return Result;
  524. }
  525. RTL_API
  526. ULONG
  527. RtlByteSwapUlong (
  528. ULONG Input
  529. )
  530. /*++
  531. Routine Description:
  532. This routine performs a byte-swap of a 32-bit integer, effectively changing
  533. its endianness.
  534. Arguments:
  535. Input - Supplies the integer to byte swap.
  536. Return Value:
  537. Returns the byte-swapped integer.
  538. --*/
  539. {
  540. ULONG Result;
  541. Result = (Input >> 16) | (Input << 16);
  542. Result = ((Result & 0xFF00FF00UL) >> 8) |
  543. ((Result & 0x00FF00FFUL) << 8);
  544. return Result;
  545. }
  546. RTL_API
  547. USHORT
  548. RtlByteSwapUshort (
  549. USHORT Input
  550. )
  551. /*++
  552. Routine Description:
  553. This routine performs a byte-swap of a 16-bit integer, effectively changing
  554. its endianness.
  555. Arguments:
  556. Input - Supplies the integer to byte swap.
  557. Return Value:
  558. Returns the byte-swapped integer.
  559. --*/
  560. {
  561. ULONG Result;
  562. Result = ((Input & 0x00FF) << 8) | (Input >> 8);
  563. return Result;
  564. }
  565. RTL_API
  566. INT
  567. RtlCountTrailingZeros64 (
  568. ULONGLONG Value
  569. )
  570. /*++
  571. Routine Description:
  572. This routine determines the number of trailing zero bits in the given
  573. 64-bit value.
  574. Arguments:
  575. Value - Supplies the value to get the number of trailing zeros for. This
  576. must not be zero.
  577. Return Value:
  578. Returns the number of trailing zero bits in the given value.
  579. --*/
  580. {
  581. LONG Extra;
  582. ULONGLONG_PARTS Parts;
  583. LONG Portion;
  584. Extra = 0;
  585. Parts.Ulonglong = Value;
  586. if (Parts.Ulong.Low != 0) {
  587. Portion = Parts.Ulong.Low;
  588. } else {
  589. Portion = Parts.Ulong.High;
  590. Extra = sizeof(ULONG) * BITS_PER_BYTE;
  591. }
  592. return RtlCountTrailingZeros32(Portion) + Extra;
  593. }
  594. RTL_API
  595. INT
  596. RtlCountTrailingZeros32 (
  597. ULONG Value
  598. )
  599. /*++
  600. Routine Description:
  601. This routine determines the number of trailing zero bits in the given
  602. 32-bit value.
  603. Arguments:
  604. Value - Supplies the value to get the number of trailing zeros for. This
  605. must not be zero.
  606. Return Value:
  607. Returns the number of trailing zero bits in the given value.
  608. --*/
  609. {
  610. return __builtin_ctzl(Value);
  611. }
  612. RTL_API
  613. INT
  614. RtlCountLeadingZeros64 (
  615. ULONGLONG Value
  616. )
  617. /*++
  618. Routine Description:
  619. This routine determines the number of leading zero bits in the given 64-bit
  620. value.
  621. Arguments:
  622. Value - Supplies the value to get the number of leading zeros for. This
  623. must not be zero.
  624. Return Value:
  625. Returns the number of leading zero bits in the given value.
  626. --*/
  627. {
  628. return __builtin_clzll(Value);
  629. }
  630. RTL_API
  631. INT
  632. RtlCountLeadingZeros32 (
  633. ULONG Value
  634. )
  635. /*++
  636. Routine Description:
  637. This routine determines the number of leading zero bits in the given 32-bit
  638. value.
  639. Arguments:
  640. Value - Supplies the value to get the number of leading zeros for. This
  641. must not be zero.
  642. Return Value:
  643. Returns the number of leading zero bits in the given value.
  644. --*/
  645. {
  646. return __builtin_clzl(Value);
  647. }
  648. RTL_API
  649. INT
  650. RtlCountSetBits64 (
  651. ULONGLONG Value
  652. )
  653. /*++
  654. Routine Description:
  655. This routine determines the number of bits set to one in the given 64-bit
  656. value.
  657. Arguments:
  658. Value - Supplies the value to count set bits for.
  659. Return Value:
  660. Returns the number of bits set to one.
  661. --*/
  662. {
  663. INT Count;
  664. ULONGLONG_PARTS Parts;
  665. Count = 0;
  666. Parts.Ulonglong = Value;
  667. if (Parts.Ulong.High != 0) {
  668. Count = RtlCountSetBits32(Parts.Ulong.High);
  669. }
  670. Count += RtlCountSetBits32(Parts.Ulong.Low);
  671. return Count;
  672. }
  673. RTL_API
  674. INT
  675. RtlCountSetBits32 (
  676. ULONG Value
  677. )
  678. /*++
  679. Routine Description:
  680. This routine determines the number of bits set to one in the given 32-bit
  681. value.
  682. Arguments:
  683. Value - Supplies the value to count set bits for.
  684. Return Value:
  685. Returns the number of bits set to one.
  686. --*/
  687. {
  688. INT Count;
  689. Count = 0;
  690. while (Value != 0) {
  691. Count += RtlSetBitCounts[Value & 0x0F];
  692. Value = Value >> 4;
  693. }
  694. return Count;
  695. }
  696. //
  697. // --------------------------------------------------------- Internal Functions
  698. //