]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.c
Optimized HighBitSetXX() functions
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / DivU64x64Remainder.c
CommitLineData
23086ba8 1/** @file\r
2 Calculate the quotient of a 64-bit integer by a 64-bit integer and returns\r
3 both the quotient and the remainderSet error flag for all division functions\r
4\r
5 Copyright (c) 2006, Intel Corporation<BR>\r
6 All rights reserved. This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#if _MSC_EXTENSIONS\r
17\r
18UINT64\r
19EFIAPI\r
20InternalMathDivRemU64x64 (\r
21 IN UINT64 Dividend,\r
22 IN UINT64 Divisor,\r
23 OUT UINT64 *Remainder OPTIONAL\r
24 )\r
25{\r
26 _asm {\r
27 mov edx, dword ptr [Dividend + 4]\r
28 mov eax, dword ptr [Dividend + 0] // edx:eax <- dividend\r
29 mov edi, edx\r
30 mov esi, eax // edi:esi <- dividend\r
31 mov ebx, dword ptr [Divisor + 0] // ecx:ebx <- divisor\r
32BitLoop:\r
33 shr edx, 1\r
34 rcr eax, 1\r
35 shrd ebx, ecx, 1\r
36 shr ecx, 1\r
37 jnz BitLoop\r
38 div ebx\r
39 mov ebx, eax // ebx <- quotient\r
40 mov ecx, dword ptr [Divisor + 4]\r
41 mul dword ptr [Divisor]\r
42 imul ecx, ebx\r
43 add edx, ecx\r
44 mov ecx, Remainder\r
45 jc TooLarge // product > 2^64\r
46 cmp edi, edx // compare high 32 bits\r
47 ja Correct\r
48 jb TooLarge // product > dividend\r
49 cmp esi, eax\r
50 jae Correct // product <= dividend\r
51TooLarge:\r
52 dec ebx // adjust quotient by -1\r
53 jecxz Return // return if Remainder == NULL\r
54 sub eax, dword ptr [Divisor + 0]\r
55 sbb edx, dword ptr [Divisor + 4]\r
56Correct:\r
57 jecxz Return\r
58 sub esi, eax\r
59 sbb edi, edx // edi:esi <- remainder\r
60 mov [ecx], esi\r
61 mov [ecx + 4], edi\r
62Return:\r
63 mov eax, ebx // eax <- quotient\r
64 xor edx, edx\r
65 }\r
66}\r
67\r
68#endif\r