+++ /dev/null
-;------------------------------------------------------------------------------\r
-;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; DivU64x64Remainder.asm\r
-;\r
-; Abstract:\r
-;\r
-; Calculate the quotient of a 64-bit integer by a 64-bit integer and returns\r
-; both the quotient and the remainder\r
-;\r
-;------------------------------------------------------------------------------\r
-\r
- .386\r
- .model flat,C\r
- .code\r
-\r
-EXTERN InternalMathDivRemU64x32:PROC\r
-\r
-;------------------------------------------------------------------------------\r
-; UINT64\r
-; EFIAPI\r
-; InternalMathDivRemU64x64 (\r
-; IN UINT64 Dividend,\r
-; IN UINT64 Divisor,\r
-; OUT UINT64 *Remainder OPTIONAL\r
-; );\r
-;------------------------------------------------------------------------------\r
-InternalMathDivRemU64x64 PROC\r
- mov ecx, [esp + 16] ; ecx <- divisor[32..63]\r
- test ecx, ecx\r
- jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32\r
- mov ecx, [esp + 20]\r
- jecxz @F\r
- and dword ptr [ecx + 4], 0 ; zero high dword of remainder\r
- mov [esp + 16], ecx ; set up stack frame to match DivRemU64x32\r
-@@:\r
- jmp InternalMathDivRemU64x32\r
-InternalMathDivRemU64x64 ENDP\r
-\r
-_@DivRemU64x64 PROC PRIVATE USES ebx esi edi\r
- mov edx, dword ptr [esp + 20]\r
- mov eax, dword ptr [esp + 16] ; edx:eax <- dividend\r
- mov edi, edx\r
- mov esi, eax ; edi:esi <- dividend\r
- mov ebx, dword ptr [esp + 24] ; ecx:ebx <- divisor\r
-@@:\r
- shr edx, 1\r
- rcr eax, 1\r
- shrd ebx, ecx, 1\r
- shr ecx, 1\r
- jnz @B\r
- div ebx\r
- mov ebx, eax ; ebx <- quotient\r
- mov ecx, [esp + 28] ; ecx <- high dword of divisor\r
- mul dword ptr [esp + 24] ; edx:eax <- quotient * divisor[0..31]\r
- imul ecx, ebx ; ecx <- quotient * divisor[32..63]\r
- add edx, ecx ; edx <- (quotient * divisor)[32..63]\r
- mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder\r
- jc @TooLarge ; product > 2^64\r
- cmp edi, edx ; compare high 32 bits\r
- ja @Correct\r
- jb @TooLarge ; product > dividend\r
- cmp esi, eax\r
- jae @Correct ; product <= dividend\r
-@TooLarge:\r
- dec ebx ; adjust quotient by -1\r
- jecxz @Return ; return if Remainder == NULL\r
- sub eax, dword ptr [esp + 24]\r
- sbb edx, dword ptr [esp + 28] ; edx:eax <- (quotient - 1) * divisor\r
-@Correct:\r
- jecxz @Return\r
- sub esi, eax\r
- sbb edi, edx ; edi:esi <- remainder\r
- mov [ecx], esi\r
- mov [ecx + 4], edi\r
-@Return:\r
- mov eax, ebx ; eax <- quotient\r
- xor edx, edx ; quotient is 32 bits long\r
- ret\r
-_@DivRemU64x64 ENDP\r
-\r
- END\r