Ported the EBC driver to use the MDE Base Math lib functions. Removed math functions from EBC driver. Need to check to see if MDE Math lib ASSERT behavior will cause any issues with EBC driver?
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1814 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -1,303 +0,0 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006, Intel Corporation
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# Ia32math.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Generic math routines for EBC interpreter running on IA32 processor
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
.globl _LeftShiftU64
|
||||
_LeftShiftU64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ecx
|
||||
cmpl $0x0,0x14(%ebp)
|
||||
jne _LeftShiftU64+0x12
|
||||
mov 0x10(%ebp),%ecx
|
||||
cmp $0x3f,%ecx
|
||||
jbe _LeftShiftU64+0x18
|
||||
xor %eax,%eax
|
||||
xor %edx,%edx
|
||||
jmp _LeftShiftU64+0x2c
|
||||
mov 0x8(%ebp),%eax
|
||||
mov 0xc(%ebp),%edx
|
||||
shld %cl,%eax,%edx
|
||||
shl %cl,%eax
|
||||
cmp $0x20,%ecx
|
||||
jb _LeftShiftU64+0x2c
|
||||
mov %eax,%edx
|
||||
xor %eax,%eax
|
||||
pop %ecx
|
||||
leave
|
||||
ret
|
||||
|
||||
.globl _RightShiftU64
|
||||
_RightShiftU64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ecx
|
||||
cmpl $0x0,0x14(%ebp)
|
||||
jne _RightShiftU64+0x12
|
||||
mov 0x10(%ebp),%ecx
|
||||
cmp $0x3f,%ecx
|
||||
jbe _RightShiftU64+0x18
|
||||
xor %eax,%eax
|
||||
xor %edx,%edx
|
||||
jmp _RightShiftU64+0x2c
|
||||
mov 0x8(%ebp),%eax
|
||||
mov 0xc(%ebp),%edx
|
||||
shrd %cl,%edx,%eax
|
||||
shr %cl,%edx
|
||||
cmp $0x20,%ecx
|
||||
jb _RightShiftU64+0x2c
|
||||
mov %edx,%eax
|
||||
xor %edx,%edx
|
||||
pop %ecx
|
||||
leave
|
||||
ret
|
||||
|
||||
.globl _ARightShift64
|
||||
_ARightShift64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ecx
|
||||
cmpl $0x0,0x14(%ebp)
|
||||
jne _ARightShift64+0x12
|
||||
mov 0x10(%ebp),%ecx
|
||||
cmp $0x3f,%ecx
|
||||
jbe _ARightShift64+0x27
|
||||
btl $0x1f,0xc(%ebp)
|
||||
jae _ARightShift64+0x21
|
||||
or $0xffffffff,%eax
|
||||
or $0xffffffff,%edx
|
||||
jmp _ARightShift64+0x3c
|
||||
xor %eax,%eax
|
||||
xor %edx,%edx
|
||||
jmp _ARightShift64+0x3c
|
||||
mov 0x8(%ebp),%eax
|
||||
mov 0xc(%ebp),%edx
|
||||
shrd %cl,%edx,%eax
|
||||
sar %cl,%edx
|
||||
cmp $0x20,%ecx
|
||||
jb _ARightShift64+0x3c
|
||||
mov %edx,%eax
|
||||
sar $0x1f,%edx
|
||||
pop %ecx
|
||||
leave
|
||||
ret
|
||||
|
||||
.globl _MulU64x64
|
||||
_MulU64x64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
mov 0x18(%ebp),%ebx
|
||||
mov 0x8(%ebp),%eax
|
||||
mull 0x10(%ebp)
|
||||
push %eax
|
||||
mov %edx,%ecx
|
||||
mov 0xc(%ebp),%eax
|
||||
mull 0x10(%ebp)
|
||||
add %eax,%ecx
|
||||
adc $0x0,%edx
|
||||
mov %edx,(%ebx)
|
||||
mov 0x8(%ebp),%eax
|
||||
mull 0x14(%ebp)
|
||||
add %eax,%ecx
|
||||
push %ecx
|
||||
adc $0x0,%edx
|
||||
mov %edx,%ecx
|
||||
mov 0xc(%ebp),%eax
|
||||
mull 0x14(%ebp)
|
||||
add %eax,%ecx
|
||||
adc $0x0,%edx
|
||||
add %ecx,(%ebx)
|
||||
adc $0x0,%edx
|
||||
mov %edx,0x4(%ebx)
|
||||
pop %edx
|
||||
pop %eax
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
leave
|
||||
ret
|
||||
|
||||
.globl _MulS64x64
|
||||
_MulS64x64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
mov 0x18(%ebp),%ebx
|
||||
xor %ecx,%ecx
|
||||
mov 0xc(%ebp),%edx
|
||||
bt $0x1f,%edx
|
||||
jae _MulS64x64+0x2a
|
||||
mov 0x8(%ebp),%eax
|
||||
not %edx
|
||||
not %eax
|
||||
add $0x1,%eax
|
||||
adc $0x0,%edx
|
||||
mov %eax,0x8(%ebp)
|
||||
mov %edx,0xc(%ebp)
|
||||
btc $0x0,%ecx
|
||||
mov 0x14(%ebp),%edx
|
||||
bt $0x1f,%edx
|
||||
jae _MulS64x64+0x4a
|
||||
mov 0x10(%ebp),%eax
|
||||
not %edx
|
||||
not %eax
|
||||
add $0x1,%eax
|
||||
adc $0x0,%edx
|
||||
mov %eax,0x10(%ebp)
|
||||
mov %edx,0x14(%ebp)
|
||||
btc $0x0,%ecx
|
||||
pushl 0x18(%ebp)
|
||||
pushl 0x14(%ebp)
|
||||
pushl 0x10(%ebp)
|
||||
pushl 0xc(%ebp)
|
||||
pushl 0x8(%ebp)
|
||||
call _MulU64x64
|
||||
add $0x14,%esp
|
||||
bt $0x0,%ecx
|
||||
jae _MulS64x64+0x7d
|
||||
not %eax
|
||||
not %edx
|
||||
notl (%ebx)
|
||||
notl 0x4(%ebx)
|
||||
add $0x1,%eax
|
||||
adc $0x0,%edx
|
||||
adcl $0x0,(%ebx)
|
||||
adcl $0x0,0x4(%ebx)
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
leave
|
||||
ret
|
||||
|
||||
.globl _DivU64x64
|
||||
_DivU64x64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ecx
|
||||
mov 0x1c(%ebp),%eax
|
||||
movl $0x0,(%eax)
|
||||
cmpl $0x0,0x10(%ebp)
|
||||
jne _DivU64x64+0x3e
|
||||
cmpl $0x0,0x14(%ebp)
|
||||
jne _DivU64x64+0x3e
|
||||
movl $0x1,(%eax)
|
||||
cmpl $0x0,0x18(%ebp)
|
||||
je _DivU64x64+0x35
|
||||
mov 0x18(%ebp),%eax
|
||||
movl $0x0,(%eax)
|
||||
movl $0x80000000,0x4(%eax)
|
||||
xor %eax,%eax
|
||||
mov $0x80000000,%edx
|
||||
jmp _DivU64x64+0x7e
|
||||
xor %edx,%edx
|
||||
xor %eax,%eax
|
||||
mov $0x40,%ecx
|
||||
shll 0x8(%ebp)
|
||||
rcll 0xc(%ebp)
|
||||
rcl %eax
|
||||
rcl %edx
|
||||
cmp 0x14(%ebp),%edx
|
||||
ja _DivU64x64+0x5d
|
||||
jb _DivU64x64+0x68
|
||||
cmp 0x10(%ebp),%eax
|
||||
jb _DivU64x64+0x68
|
||||
btsl $0x0,0x8(%ebp)
|
||||
sub 0x10(%ebp),%eax
|
||||
sbb 0x14(%ebp),%edx
|
||||
loop _DivU64x64+0x47
|
||||
cmpl $0x0,0x18(%ebp)
|
||||
je _DivU64x64+0x78
|
||||
mov 0x18(%ebp),%ecx
|
||||
mov %eax,(%ecx)
|
||||
mov %edx,0x4(%ecx)
|
||||
mov 0x8(%ebp),%eax
|
||||
mov 0xc(%ebp),%edx
|
||||
pop %ecx
|
||||
leave
|
||||
ret
|
||||
|
||||
.globl _DivS64x64
|
||||
_DivS64x64:
|
||||
push %ebp
|
||||
mov %esp,%ebp
|
||||
push %ecx
|
||||
mov 0x1c(%ebp),%eax
|
||||
movl $0x0,(%eax)
|
||||
cmpl $0x0,0x10(%ebp)
|
||||
jne _DivS64x64+0x41
|
||||
cmpl $0x0,0x14(%ebp)
|
||||
jne _DivS64x64+0x41
|
||||
movl $0x1,(%eax)
|
||||
cmpl $0x0,0x18(%ebp)
|
||||
je _DivS64x64+0x35
|
||||
mov 0x18(%ebp),%eax
|
||||
movl $0x0,(%eax)
|
||||
movl $0x80000000,0x4(%eax)
|
||||
xor %eax,%eax
|
||||
mov $0x80000000,%edx
|
||||
jmp _DivS64x64+0xc6
|
||||
xor %ecx,%ecx
|
||||
mov 0xc(%ebp),%edx
|
||||
bt $0x1f,%edx
|
||||
jae _DivS64x64+0x67
|
||||
mov 0x8(%ebp),%eax
|
||||
not %edx
|
||||
not %eax
|
||||
add $0x1,%eax
|
||||
adc $0x0,%edx
|
||||
mov %eax,0x8(%ebp)
|
||||
mov %edx,0xc(%ebp)
|
||||
btc $0x0,%ecx
|
||||
btc $0x1,%ecx
|
||||
mov 0x14(%ebp),%edx
|
||||
bt $0x1f,%edx
|
||||
jae _DivS64x64+0x87
|
||||
mov 0x10(%ebp),%eax
|
||||
not %edx
|
||||
not %eax
|
||||
add $0x1,%eax
|
||||
adc $0x0,%edx
|
||||
mov %eax,0x10(%ebp)
|
||||
mov %edx,0x14(%ebp)
|
||||
btc $0x0,%ecx
|
||||
pushl 0x1c(%ebp)
|
||||
pushl 0x18(%ebp)
|
||||
pushl 0x14(%ebp)
|
||||
pushl 0x10(%ebp)
|
||||
pushl 0xc(%ebp)
|
||||
pushl 0x8(%ebp)
|
||||
call _DivU64x64
|
||||
add $0x18,%esp
|
||||
bt $0x0,%ecx
|
||||
jae _DivS64x64+0xb1
|
||||
not %eax
|
||||
not %edx
|
||||
add $0x1,%eax
|
||||
adc $0x0,%edx
|
||||
bt $0x1,%ecx
|
||||
jae _DivS64x64+0xc6
|
||||
mov 0x18(%ebp),%ecx
|
||||
notl (%ecx)
|
||||
notl 0x4(%ecx)
|
||||
addl $0x1,(%ecx)
|
||||
adcl $0x0,0x4(%ecx)
|
||||
pop %ecx
|
||||
leave
|
||||
ret
|
@@ -1,622 +0,0 @@
|
||||
TITLE Ia32math.asm: Generic math routines for EBC interpreter running on IA32 processor
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2006, Intel Corporation
|
||||
; All rights reserved. This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Module Name:
|
||||
;
|
||||
; Ia32math.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Generic math routines for EBC interpreter running on IA32 processor
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.686P
|
||||
.XMM
|
||||
.MODEL SMALL
|
||||
.CODE
|
||||
|
||||
LeftShiftU64 PROTO C Operand: QWORD, CountIn: QWORD
|
||||
RightShiftU64 PROTO C Operand: QWORD, CountIn: QWORD
|
||||
ARightShift64 PROTO C Operand: QWORD, CountIn: QWORD
|
||||
MulU64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
|
||||
MulS64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
|
||||
DivU64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD
|
||||
DivS64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD
|
||||
|
||||
|
||||
LeftShiftU64 PROC C Operand: QWORD, CountIn: QWORD
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT64
|
||||
; LeftShiftU64 (
|
||||
; IN UINT64 Operand,
|
||||
; IN UINT64 CountIn
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; Left-shift a 64-bit value.
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Operand - the value to shift
|
||||
; Count - shift count
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Operand << Count
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ecx
|
||||
;
|
||||
; if (CountIn > 63) return 0;
|
||||
;
|
||||
cmp dword ptr CountIn[4], 0
|
||||
jne _LeftShiftU64_Overflow
|
||||
mov ecx, dword ptr CountIn[0]
|
||||
cmp ecx, 63
|
||||
jbe _LeftShiftU64_Calc
|
||||
|
||||
_LeftShiftU64_Overflow:
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
jmp _LeftShiftU64_Done
|
||||
|
||||
_LeftShiftU64_Calc:
|
||||
mov eax, dword ptr Operand[0]
|
||||
mov edx, dword ptr Operand[4]
|
||||
|
||||
shld edx, eax, cl
|
||||
shl eax, cl
|
||||
cmp ecx, 32
|
||||
jc short _LeftShiftU64_Done
|
||||
|
||||
mov edx, eax
|
||||
xor eax, eax
|
||||
|
||||
_LeftShiftU64_Done:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
LeftShiftU64 ENDP
|
||||
|
||||
|
||||
RightShiftU64 PROC C Operand: QWORD, CountIn: QWORD
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT64
|
||||
; RightShiftU64 (
|
||||
; IN UINT64 Operand,
|
||||
; IN UINT64 CountIn
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; Right-shift an unsigned 64-bit value.
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Operand - the value to shift
|
||||
; Count - shift count
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Operand >> Count
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ecx
|
||||
;
|
||||
; if (CountIn > 63) return 0;
|
||||
;
|
||||
cmp dword ptr CountIn[4], 0
|
||||
jne _RightShiftU64_Overflow
|
||||
mov ecx, dword ptr CountIn[0]
|
||||
cmp ecx, 63
|
||||
jbe _RightShiftU64_Calc
|
||||
|
||||
_RightShiftU64_Overflow:
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
jmp _RightShiftU64_Done
|
||||
|
||||
_RightShiftU64_Calc:
|
||||
mov eax, dword ptr Operand[0]
|
||||
mov edx, dword ptr Operand[4]
|
||||
|
||||
shrd eax, edx, cl
|
||||
shr edx, cl
|
||||
cmp ecx, 32
|
||||
jc short _RightShiftU64_Done
|
||||
|
||||
mov eax, edx
|
||||
xor edx, edx
|
||||
|
||||
_RightShiftU64_Done:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
RightShiftU64 ENDP
|
||||
|
||||
|
||||
ARightShift64 PROC C Operand: QWORD, CountIn: QWORD
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; INT64
|
||||
; ARightShift64 (
|
||||
; IN INT64 Operand,
|
||||
; IN UINT64 CountIn
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; Arithmatic shift a 64 bit signed value.
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Operand - the value to shift
|
||||
; Count - shift count
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Operand >> Count
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ecx
|
||||
;
|
||||
; If they exceeded the max shift count, then return either 0 or all F's
|
||||
; depending on the sign bit.
|
||||
;
|
||||
cmp dword ptr CountIn[4], 0
|
||||
jne _ARightShiftU64_Overflow
|
||||
mov ecx, dword ptr CountIn[0]
|
||||
cmp ecx, 63
|
||||
jbe _ARightShiftU64_Calc
|
||||
|
||||
_ARightShiftU64_Overflow:
|
||||
;
|
||||
; Check the sign bit of Operand
|
||||
;
|
||||
bt dword ptr Operand[4], 31
|
||||
jnc _ARightShiftU64_Return_Zero
|
||||
;
|
||||
; return -1
|
||||
;
|
||||
or eax, 0FFFFFFFFh
|
||||
or edx, 0FFFFFFFFh
|
||||
jmp _ARightShiftU64_Done
|
||||
|
||||
_ARightShiftU64_Return_Zero:
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
jmp _ARightShiftU64_Done
|
||||
|
||||
_ARightShiftU64_Calc:
|
||||
mov eax, dword ptr Operand[0]
|
||||
mov edx, dword ptr Operand[4]
|
||||
|
||||
shrd eax, edx, cl
|
||||
sar edx, cl
|
||||
cmp ecx, 32
|
||||
jc short _ARightShiftU64_Done
|
||||
|
||||
;
|
||||
; if ecx >= 32, then eax = edx, and edx = sign bit
|
||||
;
|
||||
mov eax, edx
|
||||
sar edx, 31
|
||||
|
||||
_ARightShiftU64_Done:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
ARightShift64 ENDP
|
||||
|
||||
|
||||
MulU64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT64
|
||||
; MulU64x64 (
|
||||
; UINT64 Value1,
|
||||
; UINT64 Value2,
|
||||
; UINT64 *ResultHigh
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; Multiply two unsigned 64-bit values.
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Value1 - first value to multiply
|
||||
; Value2 - value to multiply by Value1
|
||||
; ResultHigh - result to flag overflows
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Value1 * Value2
|
||||
; The 128-bit result is the concatenation of *ResultHigh and the return value
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ebx
|
||||
push ecx
|
||||
mov ebx, ResultHigh ; ebx points to the high 4 words of result
|
||||
;
|
||||
; The result consists of four double-words.
|
||||
; Here we assume their names from low to high: dw0, dw1, dw2, dw3
|
||||
;
|
||||
mov eax, dword ptr Value1[0]
|
||||
mul dword ptr Value2[0]
|
||||
push eax ; eax contains final result of dw0, push it
|
||||
mov ecx, edx ; ecx contains partial result of dw1
|
||||
|
||||
mov eax, dword ptr Value1[4]
|
||||
mul dword ptr Value2[0]
|
||||
add ecx, eax ; add eax to partial result of dw1
|
||||
adc edx, 0
|
||||
mov dword ptr [ebx], edx ; lower double-word of ResultHigh contains partial result of dw2
|
||||
|
||||
mov eax, dword ptr Value1[0]
|
||||
mul dword ptr Value2[4]
|
||||
add ecx, eax ; add eax to partial result of dw1
|
||||
push ecx ; ecx contains final result of dw1, push it
|
||||
adc edx, 0
|
||||
mov ecx, edx ; ecx contains partial result of dw2, together with ResultHigh
|
||||
|
||||
mov eax, dword ptr Value1[4]
|
||||
mul dword ptr Value2[4]
|
||||
add ecx, eax ; add eax to partial result of dw2
|
||||
adc edx, 0
|
||||
add dword ptr [ebx], ecx ; lower double-word of ResultHigh contains final result of dw2
|
||||
adc edx, 0
|
||||
mov dword ptr [ebx + 4], edx ; high double-word of ResultHigh contains final result of dw3
|
||||
|
||||
pop edx ; edx contains the final result of dw1
|
||||
pop eax ; edx contains the final result of dw0
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
MulU64x64 ENDP
|
||||
|
||||
|
||||
MulS64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; INT64
|
||||
; MulS64x64 (
|
||||
; INT64 Value1,
|
||||
; INT64 Value2,
|
||||
; INT64 *ResultHigh
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; Multiply two signed 64-bit values.
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Value1 - first value to multiply
|
||||
; Value2 - value to multiply by Value1
|
||||
; ResultHigh - result to flag overflows
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Value1 * Value2
|
||||
; The 128-bit result is the concatenation of *ResultHigh and the return value
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ebx
|
||||
push ecx
|
||||
mov ebx, ResultHigh ; ebx points to the high 4 words of result
|
||||
xor ecx, ecx ; the lowest bit of ecx flags the sign
|
||||
|
||||
mov edx, dword ptr Value1[4]
|
||||
bt edx, 31
|
||||
jnc short _MulS64x64_A_Positive
|
||||
;
|
||||
; a is negative
|
||||
;
|
||||
mov eax, dword ptr Value1[0]
|
||||
not edx
|
||||
not eax
|
||||
add eax, 1
|
||||
adc edx, 0
|
||||
mov dword ptr Value1[0], eax
|
||||
mov dword ptr Value1[4], edx
|
||||
btc ecx, 0
|
||||
|
||||
_MulS64x64_A_Positive:
|
||||
mov edx, dword ptr Value2[4]
|
||||
bt edx, 31
|
||||
jnc short _MulS64x64_B_Positive
|
||||
;
|
||||
; b is negative
|
||||
;
|
||||
mov eax, dword ptr Value2[0]
|
||||
not edx
|
||||
not eax
|
||||
add eax, 1
|
||||
adc edx, 0
|
||||
mov dword ptr Value2[0], eax
|
||||
mov dword ptr Value2[4], edx
|
||||
btc ecx, 0
|
||||
|
||||
_MulS64x64_B_Positive:
|
||||
invoke MulU64x64, Value1, Value2, ResultHigh
|
||||
bt ecx, 0
|
||||
jnc short _MulS64x64_Done
|
||||
;
|
||||
;negate the result
|
||||
;
|
||||
not eax
|
||||
not edx
|
||||
not dword ptr [ebx]
|
||||
not dword ptr [ebx + 4]
|
||||
add eax, 1
|
||||
adc edx, 0
|
||||
adc dword ptr [ebx], 0
|
||||
adc dword ptr [ebx + 4], 0
|
||||
|
||||
_MulS64x64_Done:
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
MulS64x64 ENDP
|
||||
|
||||
|
||||
DivU64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD,
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT64
|
||||
; DivU64x64 (
|
||||
; IN UINT64 Dividend,
|
||||
; IN UINT64 Divisor,
|
||||
; OUT UINT64 *Remainder OPTIONAL,
|
||||
; OUT UINT32 *Error
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; This routine allows a 64 bit value to be divided with a 64 bit value returns
|
||||
; 64bit result and the Remainder
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Dividend - dividend
|
||||
; Divisor - divisor
|
||||
; ResultHigh - result to flag overflows
|
||||
; Error - flag for error
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Dividend / Divisor
|
||||
; Remainder = Dividend mod Divisor
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ecx
|
||||
|
||||
mov eax, Error
|
||||
mov dword ptr [eax], 0
|
||||
|
||||
cmp dword ptr Divisor[0], 0
|
||||
jne _DivU64x64_Valid
|
||||
cmp dword ptr Divisor[4], 0
|
||||
jne _DivU64x64_Valid
|
||||
;
|
||||
; the divisor is zero
|
||||
;
|
||||
mov dword ptr [eax], 1
|
||||
cmp Remainder, 0
|
||||
je _DivU64x64_Invalid_Return
|
||||
;
|
||||
; fill the remainder if the pointer is not null
|
||||
;
|
||||
mov eax, Remainder
|
||||
mov dword ptr [eax], 0
|
||||
mov dword ptr [eax + 4], 80000000h
|
||||
|
||||
_DivU64x64_Invalid_Return:
|
||||
xor eax, eax
|
||||
mov edx, 80000000h
|
||||
jmp _DivU64x64_Done
|
||||
|
||||
_DivU64x64_Valid:
|
||||
;
|
||||
; let edx and eax contain the intermediate result of remainder
|
||||
;
|
||||
xor edx, edx
|
||||
xor eax, eax
|
||||
mov ecx, 64
|
||||
|
||||
_DivU64x64_Wend:
|
||||
;
|
||||
; shift dividend left one
|
||||
;
|
||||
shl dword ptr Dividend[0], 1
|
||||
rcl dword ptr Dividend[4], 1
|
||||
;
|
||||
; rotate intermediate result of remainder left one
|
||||
;
|
||||
rcl eax, 1
|
||||
rcl edx, 1
|
||||
|
||||
cmp edx, dword ptr Divisor[4]
|
||||
ja _DivU64x64_Sub_Divisor
|
||||
jb _DivU64x64_Cont
|
||||
cmp eax, dword ptr Divisor[0]
|
||||
jb _DivU64x64_Cont
|
||||
|
||||
_DivU64x64_Sub_Divisor:
|
||||
;
|
||||
; If intermediate result of remainder is larger than
|
||||
; or equal to divisor, then set the lowest bit of dividend,
|
||||
; and subtract divisor from intermediate remainder
|
||||
;
|
||||
bts dword ptr Dividend[0], 0
|
||||
sub eax, dword ptr Divisor[0]
|
||||
sbb edx, dword ptr Divisor[4]
|
||||
|
||||
_DivU64x64_Cont:
|
||||
loop _DivU64x64_Wend
|
||||
|
||||
cmp Remainder, 0
|
||||
je _DivU64x64_Assign
|
||||
mov ecx, Remainder
|
||||
mov dword ptr [ecx], eax
|
||||
mov dword ptr [ecx + 4], edx
|
||||
|
||||
_DivU64x64_Assign:
|
||||
mov eax, dword ptr Dividend[0]
|
||||
mov edx, dword ptr Dividend[4]
|
||||
|
||||
_DivU64x64_Done:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
DivU64x64 ENDP
|
||||
|
||||
DivS64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD,
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; INT64
|
||||
; DivU64x64 (
|
||||
; IN INT64 Dividend,
|
||||
; IN INT64 Divisor,
|
||||
; OUT UINT64 *Remainder OPTIONAL,
|
||||
; OUT UINT32 *Error
|
||||
; )
|
||||
;
|
||||
; Routine Description:
|
||||
;
|
||||
; This routine allows a 64 bit signed value to be divided with a 64 bit
|
||||
; signed value returns 64bit result and the Remainder.
|
||||
;
|
||||
; Arguments:
|
||||
;
|
||||
; Dividend - dividend
|
||||
; Divisor - divisor
|
||||
; ResultHigh - result to flag overflows
|
||||
; Error - flag for error
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; Dividend / Divisor
|
||||
; Remainder = Dividend mod Divisor
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
push ecx
|
||||
|
||||
mov eax, Error
|
||||
mov dword ptr [eax], 0
|
||||
|
||||
cmp dword ptr Divisor[0], 0
|
||||
jne _DivS64x64_Valid
|
||||
cmp dword ptr Divisor[4], 0
|
||||
jne _DivS64x64_Valid
|
||||
;
|
||||
; the divisor is zero
|
||||
;
|
||||
mov dword ptr [eax], 1
|
||||
cmp Remainder, 0
|
||||
je _DivS64x64_Invalid_Return
|
||||
;
|
||||
; fill the remainder if the pointer is not null
|
||||
;
|
||||
mov eax, Remainder
|
||||
mov dword ptr [eax], 0
|
||||
mov dword ptr [eax + 4], 80000000h
|
||||
|
||||
_DivS64x64_Invalid_Return:
|
||||
xor eax, eax
|
||||
mov edx, 80000000h
|
||||
jmp _DivS64x64_Done
|
||||
|
||||
_DivS64x64_Valid:
|
||||
;
|
||||
; The lowest bit of ecx flags the sign of quotient,
|
||||
; The seconde lowest bit flags the sign of remainder
|
||||
;
|
||||
xor ecx, ecx
|
||||
|
||||
mov edx, dword ptr Dividend[4]
|
||||
bt edx, 31
|
||||
jnc short _DivS64x64_Dividend_Positive
|
||||
;
|
||||
; dividend is negative
|
||||
;
|
||||
mov eax, dword ptr Dividend[0]
|
||||
not edx
|
||||
not eax
|
||||
add eax, 1
|
||||
adc edx, 0
|
||||
mov dword ptr Dividend[0], eax
|
||||
mov dword ptr Dividend[4], edx
|
||||
;
|
||||
; set both the flags for signs of quotient and remainder
|
||||
;
|
||||
btc ecx, 0
|
||||
btc ecx, 1
|
||||
|
||||
_DivS64x64_Dividend_Positive:
|
||||
mov edx, dword ptr Divisor[4]
|
||||
bt edx, 31
|
||||
jnc short _DivS64x64_Divisor_Positive
|
||||
;
|
||||
; divisor is negative
|
||||
;
|
||||
mov eax, dword ptr Divisor[0]
|
||||
not edx
|
||||
not eax
|
||||
add eax, 1
|
||||
adc edx, 0
|
||||
mov dword ptr Divisor[0], eax
|
||||
mov dword ptr Divisor[4], edx
|
||||
;
|
||||
; just complement the flag for sign of quotient
|
||||
;
|
||||
btc ecx, 0
|
||||
|
||||
_DivS64x64_Divisor_Positive:
|
||||
invoke DivU64x64, Dividend, Divisor, Remainder, Error
|
||||
bt ecx, 0
|
||||
jnc short _DivS64x64_Remainder
|
||||
;
|
||||
; negate the quotient
|
||||
;
|
||||
not eax
|
||||
not edx
|
||||
add eax, 1
|
||||
adc edx, 0
|
||||
|
||||
_DivS64x64_Remainder:
|
||||
bt ecx, 1
|
||||
jnc short _DivS64x64_Done
|
||||
;
|
||||
; negate the remainder
|
||||
;
|
||||
mov ecx, remainder
|
||||
not dword ptr [ecx]
|
||||
not dword ptr [ecx + 4]
|
||||
add dword ptr [ecx], 1
|
||||
adc dword ptr [ecx + 4], 0
|
||||
|
||||
_DivS64x64_Done:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
DivS64x64 ENDP
|
||||
|
||||
END
|
Reference in New Issue
Block a user