1 #------------------------------------------------------------------------------ 2 # 3 # Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR> 4 # This program and the accompanying materials 5 # are licensed and made available under the terms and conditions of the BSD License 6 # which accompanies this distribution. The full text of the license may be found at 7 # http://opensource.org/licenses/bsd-license.php. 8 # 9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 # 12 # Module Name: 13 # 14 # DivU64x64Remainder.S 15 # 16 # Abstract: 17 # 18 # Calculate the quotient of a 64-bit integer by a 64-bit integer and returns 19 # both the quotient and the remainder 20 # 21 #------------------------------------------------------------------------------ 22 23 ASM_GLOBAL ASM_PFX(InternalMathDivRemU64x32), ASM_PFX(InternalMathDivRemU64x64) 24 25 #------------------------------------------------------------------------------ 26 # UINT64 27 # EFIAPI 28 # InternalMathDivRemU64x64 ( 29 # IN UINT64 Dividend, 30 # IN UINT64 Divisor, 31 # OUT UINT64 *Remainder OPTIONAL 32 # ); 33 #------------------------------------------------------------------------------ 34 ASM_PFX(InternalMathDivRemU64x64): 35 movl 16(%esp), %ecx # ecx <- divisor[32..63] 36 testl %ecx, %ecx 37 jnz Hard # call _@DivRemU64x64 if Divisor > 2^32 38 movl 20(%esp), %ecx 39 jecxz L1 40 andl $0, 4(%ecx) # zero high dword of remainder 41 movl %ecx, 16(%esp) # set up stack frame to match DivRemU64x32 42 L1: 43 jmp ASM_PFX(InternalMathDivRemU64x32) 44 Hard: 45 push %ebx 46 push %esi 47 push %edi 48 mov 20(%esp), %edx 49 mov 16(%esp), %eax # edx:eax <- dividend 50 movl %edx, %edi 51 movl %eax, %esi # edi:esi <- dividend 52 mov 24(%esp), %ebx # ecx:ebx <- divisor 53 L2: 54 shrl %edx 55 rcrl $1, %eax 56 shrdl $1, %ecx, %ebx 57 shrl %ecx 58 jnz L2 59 divl %ebx 60 movl %eax, %ebx # ebx <- quotient 61 movl 28(%esp), %ecx # ecx <- high dword of divisor 62 mull 24(%esp) # edx:eax <- quotient * divisor[0..31] 63 imull %ebx, %ecx # ecx <- quotient * divisor[32..63] 64 addl %ecx, %edx # edx <- (quotient * divisor)[32..63] 65 mov 32(%esp), %ecx # ecx <- addr for Remainder 66 jc TooLarge # product > 2^64 67 cmpl %edx, %edi # compare high 32 bits 68 ja Correct 69 jb TooLarge # product > dividend 70 cmpl %eax, %esi 71 jae Correct # product <= dividend 72 TooLarge: 73 decl %ebx # adjust quotient by -1 74 jecxz Return # return if Remainder == NULL 75 sub 24(%esp), %eax 76 sbb 28(%esp), %edx # edx:eax <- (quotient - 1) * divisor 77 Correct: 78 jecxz Return 79 subl %eax, %esi 80 sbbl %edx, %edi # edi:esi <- remainder 81 movl %esi, (%ecx) 82 movl %edi, 4(%ecx) 83 Return: 84 movl %ebx, %eax # eax <- quotient 85 xorl %edx, %edx # quotient is 32 bits long 86 pop %edi 87 pop %esi 88 pop %ebx 89 ret 90