#------------------------------------------------------------------------------\r
#\r
-# Copyright (c) 2006, Intel Corporation\r
+# Copyright (c) 2006 - 2008, Intel Corporation\r
# All rights reserved. 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
#\r
# Module Name:\r
#\r
-# DivU64x64Remainder.asm\r
+# DivU64x64Remainder.S\r
#\r
# Abstract:\r
#\r
#\r
#------------------------------------------------------------------------------\r
\r
+ASM_GLOBAL ASM_PFX(InternalMathDivRemU64x32), ASM_PFX(InternalMathDivRemU64x64)\r
\r
-\r
- \r
-\r
-.extern _InternalMathDivRemU64x32\r
-\r
-.global _InternalMathDivRemU64x64\r
-_InternalMathDivRemU64x64: \r
- movl 16(%esp),%ecx\r
- testl %ecx,%ecx\r
- jnz _DivRemU64x64\r
- movl 20(%esp),%ecx\r
+#------------------------------------------------------------------------------\r
+# UINT64\r
+# EFIAPI\r
+# InternalMathDivRemU64x64 (\r
+# IN UINT64 Dividend,\r
+# IN UINT64 Divisor,\r
+# OUT UINT64 *Remainder OPTIONAL\r
+# );\r
+#------------------------------------------------------------------------------\r
+ASM_PFX(InternalMathDivRemU64x64):\r
+ movl 16(%esp), %ecx # ecx <- divisor[32..63]\r
+ testl %ecx, %ecx\r
+ jnz Hard # call _@DivRemU64x64 if Divisor > 2^32\r
+ movl 20(%esp), %ecx\r
jecxz L1\r
- and $0,4(%ecx)\r
- movl %ecx,16(%esp)\r
-L1: \r
- jmp _InternalMathDivRemU64x32\r
-\r
-\r
-.global DivRemU64x64\r
-DivRemU64x64:\r
-# MISMATCH: "DivRemU64x64: USES ebx esi edi"\r
- push %ebx \r
- push %esi \r
- push %edi \r
+ and $0, 4(%ecx) # zero high dword of remainder\r
+ movl %ecx, 16(%esp) # set up stack frame to match DivRemU64x32\r
+L1:\r
+ jmp ASM_PFX(InternalMathDivRemU64x32)\r
+Hard:\r
+ push %ebx\r
+ push %esi\r
+ push %edi\r
mov 20(%esp), %edx\r
- mov 16(%esp), %eax\r
- movl %edx,%edi\r
- movl %eax,%esi\r
- mov 24(%esp), %ebx\r
-L2: \r
+ mov 16(%esp), %eax # edx:eax <- dividend\r
+ movl %edx, %edi\r
+ movl %eax, %esi # edi:esi <- dividend\r
+ mov 24(%esp), %ebx # ecx:ebx <- divisor\r
+L2:\r
shrl %edx\r
- rcrl $1,%eax\r
- shrdl $1,%ecx,%ebx\r
+ rcrl $1, %eax\r
+ shrdl $1, %ecx, %ebx\r
shrl %ecx\r
jnz L2\r
divl %ebx\r
- movl %eax,%ebx\r
- movl 28(%esp),%ecx\r
- mull 24(%esp)\r
- imull %ebx,%ecx\r
- addl %ecx,%edx\r
- mov 32(%esp), %ecx\r
- jc TooLarge\r
- cmpl %edx,%edi\r
- ja Correct\r
- jb TooLarge\r
- cmpl %eax,%esi\r
- jae Correct\r
-TooLarge: \r
- decl %ebx\r
- jecxz Return\r
- sub 24(%esp), %eax\r
- sbb 28(%esp), %edx\r
-Correct: \r
+ movl %eax, %ebx # ebx <- quotient \r
+ movl 28(%esp), %ecx # ecx <- high dword of divisor \r
+ mull 24(%esp) # edx:eax <- quotient * divisor[0..31]\r
+ imull %ebx, %ecx # ecx <- quotient * divisor[32..63] \r
+ addl %ecx, %edx # edx <- (quotient * divisor)[32..63] \r
+ mov 32(%esp), %ecx # ecx <- addr for Remainder \r
+ jc TooLarge # product > 2^64 \r
+ cmpl %edx, %edi # compare high 32 bits \r
+ ja Correct \r
+ jb TooLarge # product > dividend \r
+ cmpl %eax, %esi \r
+ jae Correct # product <= dividend \r
+TooLarge:\r
+ decl %ebx # adjust quotient by -1 \r
+ jecxz Return # return if Remainder == NULL \r
+ sub 24(%esp), %eax \r
+ sbb 28(%esp), %edx # edx:eax <- (quotient - 1) * divisor\r
+Correct:\r
jecxz Return\r
- subl %eax,%esi\r
- sbbl %edx,%edi\r
- movl %esi,(%ecx)\r
- movl %edi,4(%ecx)\r
-Return: \r
- movl %ebx,%eax\r
- xorl %edx,%edx\r
- push %edi \r
- push %esi \r
- push %ebx \r
+ subl %eax, %esi\r
+ sbbl %edx, %edi # edi:esi <- remainder\r
+ movl %esi, (%ecx)\r
+ movl %edi, 4(%ecx)\r
+Return:\r
+ movl %ebx, %eax # eax <- quotient \r
+ xorl %edx, %edx # quotient is 32 bits long\r
+ pop %edi\r
+ pop %esi\r
+ pop %ebx\r
ret\r