div.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. div.c
  5. Abstract:
  6. This module implements support for division in EFI.
  7. Author:
  8. Evan Green 7-Apr-2014
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "ueficore.h"
  16. //
  17. // ---------------------------------------------------------------- Definitions
  18. //
  19. //
  20. // ------------------------------------------------------ Data Type Definitions
  21. //
  22. //
  23. // ----------------------------------------------- Internal Function Prototypes
  24. //
  25. //
  26. // -------------------------------------------------------------------- Globals
  27. //
  28. //
  29. // ------------------------------------------------------------------ Functions
  30. //
  31. BOOLEAN
  32. EfiDivideUnsigned64 (
  33. UINT64 Dividend,
  34. UINT64 Divisor,
  35. UINT64 *QuotientOut,
  36. UINT64 *RemainderOut
  37. )
  38. /*++
  39. Routine Description:
  40. This routine performs a 64-bit divide of two unsigned numbers.
  41. Arguments:
  42. Dividend - Supplies the number that is going to be divided (the numerator).
  43. Divisor - Supplies the number to divide into (the denominator).
  44. QuotientOut - Supplies a pointer that receives the result of the divide.
  45. This parameter may be NULL.
  46. RemainderOut - Supplies a pointer that receives the remainder of the
  47. divide. This parameter may be NULL.
  48. Return Value:
  49. Returns TRUE if the operation was successful, or FALSE if there was an
  50. error (like divide by 0).
  51. --*/
  52. {
  53. UINT32 BitCount;
  54. UINT32 BitIndex;
  55. UINT64 LastDividend;
  56. UINT32 MostSignificantBit;
  57. UINT64 Quotient;
  58. UINT64 Remainder;
  59. UINT64 Subtraction;
  60. UINT32 SubtractionTopBitNot;
  61. BitCount = 64;
  62. Quotient = 0;
  63. Remainder = 0;
  64. //
  65. // Check easy cases.
  66. //
  67. if (Divisor == 0) {
  68. return FALSE;
  69. }
  70. if (Divisor > Dividend) {
  71. Remainder = Dividend;
  72. goto DivideUnsigned64End;
  73. }
  74. if (Divisor == Dividend) {
  75. Quotient = 1;
  76. goto DivideUnsigned64End;
  77. }
  78. LastDividend = 0;
  79. while (Remainder < Divisor) {
  80. MostSignificantBit = (Dividend & 0x8000000000000000ULL) >> 63;
  81. Remainder = (Remainder << 1) | MostSignificantBit;
  82. LastDividend = Dividend;
  83. Dividend = Dividend << 1;
  84. BitCount -= 1;
  85. }
  86. //
  87. // Undo the last iteration of the loop (instead of adding an if into the
  88. // loop.
  89. //
  90. Dividend = LastDividend;
  91. Remainder = Remainder >> 1;
  92. BitCount += 1;
  93. for (BitIndex = 0; BitIndex < BitCount; BitIndex += 1) {
  94. MostSignificantBit = (Dividend & 0x8000000000000000ULL) >> 63;
  95. Remainder = (Remainder << 1) | MostSignificantBit;
  96. Subtraction = Remainder - Divisor;
  97. SubtractionTopBitNot = !(Subtraction & 0x8000000000000000ULL);
  98. Dividend = Dividend << 1;
  99. Quotient = (Quotient << 1) | SubtractionTopBitNot;
  100. if (SubtractionTopBitNot != 0) {
  101. Remainder = Subtraction;
  102. }
  103. }
  104. DivideUnsigned64End:
  105. if (QuotientOut != NULL) {
  106. *QuotientOut = Quotient;
  107. }
  108. if (RemainderOut != NULL) {
  109. *RemainderOut = Remainder;
  110. }
  111. return TRUE;
  112. }
  113. BOOLEAN
  114. EfiDivide64 (
  115. INT64 Dividend,
  116. INT64 Divisor,
  117. INT64 *QuotientOut,
  118. INT64 *RemainderOut
  119. )
  120. /*++
  121. Routine Description:
  122. This routine performs a 64-bit divide of two signed numbers.
  123. Arguments:
  124. Dividend - Supplies the number that is going to be divided (the numerator).
  125. Divisor - Supplies the number to divide into (the denominator).
  126. QuotientOut - Supplies a pointer that receives the result of the divide.
  127. This parameter may be NULL.
  128. RemainderOut - Supplies a pointer that receives the remainder of the
  129. divide. This parameter may be NULL.
  130. Return Value:
  131. Returns TRUE if the operation was successful, or FALSE if there was an
  132. error (like divide by 0).
  133. --*/
  134. {
  135. UINT64 AbsoluteDividend;
  136. UINT64 AbsoluteDivisor;
  137. BOOLEAN Result;
  138. UINT64 UnsignedQuotient;
  139. UINT64 UnsignedRemainder;
  140. //
  141. // Get the unsigned versions and do an unsigned division.
  142. //
  143. AbsoluteDividend = Dividend;
  144. AbsoluteDivisor = Divisor;
  145. if (Dividend < 0) {
  146. AbsoluteDividend = -AbsoluteDividend;
  147. }
  148. if (Divisor < 0) {
  149. AbsoluteDivisor = -AbsoluteDivisor;
  150. }
  151. Result = EfiDivideUnsigned64(AbsoluteDividend,
  152. AbsoluteDivisor,
  153. &UnsignedQuotient,
  154. &UnsignedRemainder);
  155. if (Result == FALSE) {
  156. return FALSE;
  157. }
  158. //
  159. // The quotient is negative if the signs of the operands are different.
  160. //
  161. if (QuotientOut != NULL) {
  162. *QuotientOut = UnsignedQuotient;
  163. if (((Divisor > 0) && (Dividend < 0)) ||
  164. ((Divisor < 0) && (Dividend >= 0)) ) {
  165. *QuotientOut = -UnsignedQuotient;
  166. }
  167. }
  168. //
  169. // The sign of the remainder is the same as the sign of the dividend.
  170. //
  171. if (RemainderOut != NULL) {
  172. *RemainderOut = UnsignedRemainder;
  173. if (Dividend < 0) {
  174. *RemainderOut = -UnsignedRemainder;
  175. }
  176. }
  177. return TRUE;
  178. }
  179. //
  180. // --------------------------------------------------------- Internal Functions
  181. //