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