Inline ASM in .c file is specific to MS tool-chain. Other tool-chain (such as Intel compiler) may not support it. Add in .asm files to make these function to be built by Assembler so that they are avaliable too for other tool-chain.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5529 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qwang12 2008-07-21 01:49:04 +00:00
parent 22353b17c0
commit 478db76bbe
10 changed files with 1026 additions and 0 deletions

View File

@ -0,0 +1,82 @@
;---------------------------------------------------------------------------
;/*++
;
;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:
;
; DivU64x32.c
;
;Abstract:
;
; 64-bit division function for IA-32
;
;--*/
;---------------------------------------------------------------------------
.386
.model flat,C
.code
;---------------------------------------------------------------------------
;UINT64
;DivU64x32 (
; IN UINT64 Dividend,
; IN UINTN Divisor,
; OUT UINTN *Remainder OPTIONAL
; )
;/*++
;Routine Description:
; This routine allows a 64 bit value to be divided with a 32 bit value returns
; 64bit result and the Remainder.
;
;Arguments:
; Dividend - dividend
; Divisor - divisor
; Remainder - buffer for remainder
;
;Returns:
; Dividend / Divisor
; Remainder = Dividend mod Divisor
;
;N.B. only works for 31bit divisors!!
;
;--*/
;---------------------------------------------------------------------------
DivU64x32 PROC
xor edx, edx ; Clear EDX
mov eax, [esp + 8] ; Put high 32 bits of 64-bit dividend in EAX
mov ecx, [esp + 12] ; Put 32 bits divisor in ECX
div ecx ; Dividend Divisor Quoitent...Remainder
; 0:EAX / ECX = EAX EDX
push eax ; Push quoitent in stack
mov eax, [esp + 4] ; Put low 32 bits of 64-bit dividend in EAX
div ecx ; Leave the REMAINDER in EDX as High 32-bit of new dividend
; Dividend Divisor Quoitent...Remainder
; EDX:EAX / ECX = EAX EDX
mov ecx, [esp + 16] ; Put &REMAINDER to ecx
jecxz Label1 ; If ecx == 0, no remainder exist, return with quoitent in EDX directly
mov dword ptr [ecx], edx ; Put EDX through REMAINDER pointer in ECX
Label1:
pop edx ; Pop High 32-bit QUOITENT to EDX
DivU64x32 ENDP
END

View File

@ -0,0 +1,200 @@
;/*++
;
;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:
;
; EfiCopyMem.c
;
;Abstract:
;
; This is the code that supports IA32-optimized CopyMem service
;
;--*/
;---------------------------------------------------------------------------
.686
.model flat,C
.mmx
.code
;---------------------------------------------------------------------------
;VOID
;EfiCommonLibCopyMem (
; IN VOID *Destination,
; IN VOID *Source,
; IN UINTN Count
; )
;/*++
;
;Routine Description:
;
; Copy Length bytes from Source to Destination.
;
;Arguments:
;
; Destination - Target of copy
;
; Source - Place to copy from
;
; Length - Number of bytes to copy
;
;Returns:
;
; None
;
;--*/
EfiCommonLibCopyMem PROC
push ebp
mov ebp, esp
push ecx ; reserve space for Scratch Local variable UINT64 MmxSave
push ecx
push esi
push edi
mov ecx, [ebp + 10h] ; Count
mov esi, [ebp + 0Ch] ; Source
mov edi, [ebp + 8] ; Destination
; First off, make sure we have no overlap. That is to say,
; if (Source == Destination) => do nothing
; if (Source + Count <= Destination) => regular copy
; if (Destination + Count <= Source) => regular copy
; otherwise, do a reverse copy
mov eax, esi
add eax, ecx ; Source + Count
cmp eax, edi
jle _StartByteCopy
mov eax, edi
add eax, ecx ; Dest + Count
cmp eax, esi
jle _StartByteCopy
cmp esi, edi
je _CopyMemDone
jl _CopyOverlapped ; too bad -- overlaps
; Pick up misaligned start bytes to get destination pointer 4-byte aligned
_StartByteCopy:
cmp ecx, 0
je _CopyMemDone ; Count == 0, all done
mov edx, edi
and dl, 3 ; check lower 2 bits of address
test dl, dl
je SHORT _CopyBlocks ; already aligned?
; Copy a byte
mov al, BYTE PTR [esi] ; get byte from Source
mov BYTE PTR [edi], al ; write byte to Destination
dec ecx
inc edi
inc esi
jmp _StartByteCopy ; back to top of loop
_CopyBlocks:
; Compute how many 64-byte blocks we can clear
mov eax, ecx ; get Count in eax
shr eax, 6 ; convert to 64-byte count
shl eax, 6 ; convert back to bytes
sub ecx, eax ; subtract from the original count
shr eax, 6 ; and this is how many 64-byte blocks
; If no 64-byte blocks, then skip
cmp eax, 0
je _CopyRemainingDWords
; Save mm0 to UINT64 MmxSave
movq [ebp - 8], mm0
copymmx:
movq mm0, QWORD PTR ds:[esi]
movq QWORD PTR ds:[edi], mm0
movq mm0, QWORD PTR ds:[esi+8]
movq QWORD PTR ds:[edi+8], mm0
movq mm0, QWORD PTR ds:[esi+16]
movq QWORD PTR ds:[edi+16], mm0
movq mm0, QWORD PTR ds:[esi+24]
movq QWORD PTR ds:[edi+24], mm0
movq mm0, QWORD PTR ds:[esi+32]
movq QWORD PTR ds:[edi+32], mm0
movq mm0, QWORD PTR ds:[esi+40]
movq QWORD PTR ds:[edi+40], mm0
movq mm0, QWORD PTR ds:[esi+48]
movq QWORD PTR ds:[edi+48], mm0
movq mm0, QWORD PTR ds:[esi+56]
movq QWORD PTR ds:[edi+56], mm0
add edi, 64
add esi, 64
dec eax
jnz copymmx
; Restore mm0 from MmxSave
movq mm0, [ebp - 8]
emms ; Exit MMX Instruction
; Copy as many DWORDS as possible
_CopyRemainingDWords:
cmp ecx, 4
jb _CopyRemainingBytes
mov eax, DWORD PTR [esi] ; get data from Source
mov DWORD PTR [edi], eax ; write byte to Destination
sub ecx, 4 ; decrement Count
add esi, 4 ; advance Source pointer
add edi, 4 ; advance Destination pointer
jmp _CopyRemainingDWords ; back to top
_CopyRemainingBytes:
cmp ecx, 0
je _CopyMemDone
mov al, BYTE PTR [esi] ; get byte from Source
mov BYTE PTR [edi], al ; write byte to Destination
dec ecx
inc esi
inc edi ; advance Destination pointer
jmp SHORT _CopyRemainingBytes ; back to top of loop
;
; We do this block if the source and destination buffers overlap. To
; handle it, copy starting at the end of the source buffer and work
; your way back. Since this is the atypical case, this code has not
; been optimized, and thus simply copies bytes.
;
_CopyOverlapped:
; Move the source and destination pointers to the end of the range
add esi, ecx ; Source + Count
dec esi
add edi, ecx ; Dest + Count
dec edi
_CopyOverlappedLoop:
cmp ecx, 0
je _CopyMemDone
mov al, BYTE PTR [esi] ; get byte from Source
mov BYTE PTR [edi], al ; write byte to Destination
dec ecx
dec esi
dec edi
jmp _CopyOverlappedLoop ; back to top of loop
_CopyMemDone:
pop edi
pop esi
leave
ret
EfiCommonLibCopyMem ENDP
END

View File

@ -0,0 +1,152 @@
;/*++
;
;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:
;
; EfiSetMem.asm
;
;Abstract:
;
; This is the code that supports IA32-optimized SetMem service
;
;--*/
;---------------------------------------------------------------------------
.686
.model flat,C
.mmx
.code
;---------------------------------------------------------------------------
;VOID
;EfiCommonLibSetMem (
; IN VOID *Buffer,
; IN UINTN Count,
; IN UINT8 Value
; )
;/*++
;
;Input: VOID *Buffer - Pointer to buffer to write
; UINTN Count - Number of bytes to write
; UINT8 Value - Value to write
;
;Output: None.
;
;Saves:
;
;Modifies:
;
;Description: This function is an optimized set-memory function.
;
;Notes: This function tries to set memory 8 bytes at a time. As a result,
; it first picks up any misaligned bytes, then words, before getting
; in the main loop that does the 8-byte clears.
;
;--*/
EfiCommonLibSetMem PROC
push ebp
mov ebp, esp
sub esp, 10h; Reserve space for local variable UINT64 QWordValue @[ebp - 10H] & UINT64 MmxSave @[ebp - 18H]
push ebx
push edi
mov edx, [ebp + 0Ch] ; Count
test edx, edx
je _SetMemDone
push ebx
mov eax, [ebp + 8] ; Buffer
mov bl, [ebp + 10h] ; Value
mov edi, eax
mov bh, bl
cmp edx, 256
jb _SetRemindingByte
and al, 07h
test al, al
je _SetBlock
mov eax, edi
shr eax, 3
inc eax
shl eax, 3
sub eax, edi
cmp eax, edx
jnb _SetRemindingByte
sub edx, eax
mov ecx, eax
mov al, bl
rep stosb
_SetBlock:
mov eax, edx
shr eax, 6
test eax, eax
je _SetRemindingByte
shl eax, 6
sub edx, eax
shr eax, 6
mov WORD PTR [ebp - 10H], bx ; QWordValue[0]
mov WORD PTR [ebp - 10H + 2], bx ; QWordValue[2]
mov WORD PTR [ebp - 10H + 4], bx ; QWordValue[4]
mov WORD PTR [ebp - 10H + 6], bx ; QWordValue[6]
movq [ebp - 8], mm0 ; Save mm0 to MmxSave
movq mm0, [ebp - 10H] ; Load QWordValue to mm0
_B:
movq QWORD PTR ds:[edi], mm0
movq QWORD PTR ds:[edi+8], mm0
movq QWORD PTR ds:[edi+16], mm0
movq QWORD PTR ds:[edi+24], mm0
movq QWORD PTR ds:[edi+32], mm0
movq QWORD PTR ds:[edi+40], mm0
movq QWORD PTR ds:[edi+48], mm0
movq QWORD PTR ds:[edi+56], mm0
add edi, 64
dec eax
jnz _B
; Restore mm0
movq mm0, [ebp - 8] ; Restore MmxSave to mm0
emms ; Exit MMX Instruction
_SetRemindingByte:
mov ecx, edx
mov eax, ebx
shl eax, 16
mov ax, bx
shr ecx, 2
rep stosd
mov ecx, edx
and ecx, 3
rep stosb
pop ebx
_SetMemDone:
pop edi
pop ebx
leave
ret
EfiCommonLibSetMem ENDP
END

View File

@ -0,0 +1,135 @@
;/*++
;
;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:
;
; EfiZeroMem.c
;
;Abstract:
;
; This is the code that supports IA32-optimized ZeroMem service
;
;--*/
;---------------------------------------------------------------------------
.686
.model flat,C
.mmx
.code
;---------------------------------------------------------------------------
;VOID
;EfiCommonLibZeroMem (
; IN VOID *Buffer,
; IN UINTN Count
; )
;/*++
;
;Input: VOID *Buffer - Pointer to buffer to clear
; UINTN Count - Number of bytes to clear
;
;Output: None.
;
;Saves:
;
;Modifies:
;
;Description: This function is an optimized zero-memory function.
;
;Notes: This function tries to zero memory 8 bytes at a time. As a result,
; it first picks up any misaligned bytes, then words, before getting
; in the main loop that does the 8-byte clears.
;
;--*/
EfiCommonLibZeroMem PROC
; UINT64 MmxSave;
push ebp
mov ebp, esp
push ecx ; Reserve space for local variable MmxSave
push ecx
push edi
mov ecx, [ebp + 0Ch] ; Count
mov edi, [ebp + 8]; Buffer
; Pick up misaligned start bytes (get pointer 4-byte aligned)
_StartByteZero:
mov eax, edi
and al, 3 ; check lower 2 bits of address
test al, al
je _ZeroBlocks ; already aligned?
cmp ecx, 0
je _ZeroMemDone
; Clear the byte memory location
mov BYTE PTR [edi], 0
inc edi
; Decrement our count
dec ecx
jmp _StartByteZero ; back to top of loop
_ZeroBlocks:
; Compute how many 64-byte blocks we can clear
mov edx, ecx
shr ecx, 6 ; convert to 64-byte count
shl ecx, 6 ; convert back to bytes
sub edx, ecx ; subtract from the original count
shr ecx, 6 ; and this is how many 64-byte blocks
; If no 64-byte blocks, then skip
cmp ecx, 0
je _ZeroRemaining
; Save mm0
movq [ebp - 8], mm0 ; Save mm0 to MmxSave
pxor mm0, mm0 ; Clear mm0
_B:
movq QWORD PTR ds:[edi], mm0
movq QWORD PTR ds:[edi+8], mm0
movq QWORD PTR ds:[edi+16], mm0
movq QWORD PTR ds:[edi+24], mm0
movq QWORD PTR ds:[edi+32], mm0
movq QWORD PTR ds:[edi+40], mm0
movq QWORD PTR ds:[edi+48], mm0
movq QWORD PTR ds:[edi+56], mm0
add edi, 64
dec ecx
jnz _B
; Restore mm0
movq mm0, [ebp - 8] ; Restore mm0 from MmxSave
emms ; Exit MMX Instruction
_ZeroRemaining:
; Zero out as many DWORDS as possible
mov ecx, edx
shr ecx, 2
xor eax, eax
rep stosd
; Zero out remaining as bytes
mov ecx, edx
and ecx, 03
rep stosb
_ZeroMemDone:
pop edi
leave
ret
EfiCommonLibZeroMem ENDP
END

View File

@ -0,0 +1,67 @@
;/*++
;
;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:
;
; GetPowerOfTwo.c
;
;Abstract:
;
; Calculates the largest integer that is both
; a power of two and less than Input
;
;--*/
;---------------------------------------------------------------------------
.686
.model flat,C
.code
;---------------------------------------------------------------------------
;UINT64
;GetPowerOfTwo (
; IN UINT64 Input
; )
;/*++
;
;Routine Description:
;
; Calculates the largest integer that is both
; a power of two and less than Input
;
;Arguments:
;
; Input - value to calculate power of two
;
;Returns:
;
; the largest integer that is both a power of
; two and less than Input
;
;--*/
GetPowerOfTow PROC
xor eax, eax
mov edx, eax
mov ecx, [esp + 8] ; dword ptr Input[4]
jecxz _F
bsr ecx, ecx
bts edx, ecx
jmp _Exit
_F:
mov ecx, [esp + 4] ; dword ptr Input[0]
jecxz _Exit
bsr ecx, ecx
bts eax, ecx
_Exit:
ret
GetPowerOfTow ENDP
END

View File

@ -0,0 +1,80 @@
;/*++
;
;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:
;
; LShiftU64.c
;
;Abstract:
;
; 64-bit left shift function for IA-32
;
;--*/
;
;---------------------------------------------------------------------------
.686
.model flat,C
.code
;---------------------------------------------------------------------------
;
;UINT64
;LShiftU64 (
; IN UINT64 Operand,
; IN UINTN Count
; )
;/*++
;
;Routine Description:
;
; This routine allows a 64 bit value to be left shifted by 32 bits and
; returns the shifted value.
; Count is valid up 63. (Only Bits 0-5 is valid for Count)
;
;Arguments:
;
; Operand - Value to be shifted
; Count - Number of times to shift left.
;
;Returns:
;
; Value shifted left identified by the Count.
;
;--*/
LShiftU64 PROC
mov eax, [esp + 4]; dword ptr Operand[0]
mov edx, [esp + 8]; dword ptr Operand[4]
;
; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EAX is not touched
; For CL of 32 - 63, it will be shifted 0 - 31 so we will move eax to edx later.
;
mov ecx, [esp + 0Ch]; Count
and ecx, 63
shld edx, eax, cl
shl eax, cl
;
; Since Count is 32 - 63, eax will have been shifted by 0 - 31
; If shifted by 32 or more, set lower 32 bits to zero.
;
cmp ecx, 32
jc short _LShiftU64_Done
mov edx, eax
xor eax, eax
_LShiftU64_Done:
ret
LShiftU64 ENDP
END

View File

@ -0,0 +1,81 @@
;/*++
;
;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:
;
; Log2.c
;
;Abstract:
;
; 64-bit integer logarithm function for IA-32
;
;--*/
;
;---------------------------------------------------------------------------
.686
.model flat,C
.code
;---------------------------------------------------------------------------
;UINT8
;Log2 (
; IN UINT64 Operand
; )
;/*++
;
;Routine Description:
;
; Calculates and floors logarithms based on 2
;
;Arguments:
;
; Operand - value to calculate logarithm
;
;Returns:
;
; The largest integer that is less than or equal
; to the logarithm of Operand based on 2
;
;--*/
Log2 PROC
mov ecx, 64
cmp dword ptr [esp + 4], 0 ; (UINT32 *(&Operand))
jne _Log2_Wend
cmp dword ptr [esp + 8], 0 ; (UINT32 *(&Operand)) + 1
jne _Log2_Wend
mov cl, 0FFH
jmp _Log2_Done
_Log2_Wend:
dec ecx
cmp ecx, 32
jae _Log2_Higher
bt [esp + 4], ecx ; (UINT32 *(&Operand))
jmp _Log2_Bit
_Log2_Higher:
mov eax, ecx
sub eax, 32
bt [esp + 8], eax ; (UINT32 *(&Operand)) + 1
_Log2_Bit:
jc _Log2_Done
jmp _Log2_Wend
_Log2_Done:
mov al, cl
ret
Log2 ENDP
END

View File

@ -0,0 +1,70 @@
;/*++
;
;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:
;
; MultU64x32.c
;
;Abstract:
;
; 64-bit Multiplication function for IA-32
;
;--*/
;---------------------------------------------------------------------------
.686
.model flat,C
.code
;---------------------------------------------------------------------------
;UINT64
;MultU64x32 (
; IN UINT64 Multiplicand,
; IN UINTN Multiplier
; )
;/*++
;
;Routine Description:
;
; This routine allows a 64 bit value to be multiplied with a 32 bit
; value returns 64bit result.
; No checking if the result is greater than 64bits
;
;Arguments:
;
; Multiplicand - multiplicand
; Multiplier - multiplier
;
;Returns:
;
; Multiplicand * Multiplier
;
;--*/
MultU64x32 PROC
mov eax, [esp + 4]; dword ptr Multiplicand[0]
mul dword ptr [esp + 0Ch] ; Multiplier
push eax
push edx
mov eax, [esp + 10h]; dword ptr Multiplicand[4]
mul dword ptr [esp + 14h]; Multiplier
;
; The value in edx stored by second multiplication overflows
; the output and should be discarded. So here we overwrite it
; with the edx value of first multiplication.
;
pop edx
add edx, eax
pop eax
ret
MultU64x32 ENDP
END

View File

@ -0,0 +1,81 @@
;/*++
;
;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:
;
; Power10U64.c
;
;Abstract:
;
; Calculates Operand * 10 ^ Power
;
;--*/
;
;#include "Tiano.h"
;---------------------------------------------------------------------------
.686
.model flat,C
.code
MultU64x32 PROTO C
;---------------------------------------------------------------------------
;
;UINT64
;MultU64x32 (
; IN UINT64 Multiplicand,
; IN UINTN Multiplier
; );
;
;UINT64
;Power10U64 (
; IN UINT64 Operand,
; IN UINTN Power
; )
;/*++
;
;Routine Description:
;
; Raise 10 to the power of Power, and multiply the result with Operand
;
;Arguments:
;
; Operand - multiplicand
; Power - power
;
;Returns:
;
; Operand * 10 ^ Power
;
;--*/
Power10U64 PROC
push ebp
mov ebp, esp
mov eax, dword ptr [ebp + 8]; dword ptr Operand[0]
mov edx, dword ptr [ebp + 0Ch]; dword ptr Operand[4]
mov ecx, dword ptr [ebp + 10h] ;Power
jcxz _Power10U64_Done
_Power10U64_Wend:
push 10
push [ebp + 0Ch]; dword ptr Operand[4]
push [ebp + 8]; dword ptr Operand[0]
call MultU64x32
add esp, 0cH
mov [ebp + 8] , eax; dword ptr Operand[0]
mov [ebp + 0Ch] , edx; dword ptr Operand[4]
loop _Power10U64_Wend
_Power10U64_Done:
pop ebp
ret
Power10U64 ENDP
END

View File

@ -0,0 +1,78 @@
;/*++
;
;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:
;
; RShiftU64.c
;
;Abstract:
;
; 64-bit right shift function for IA-32
;
;--*/
;
;#include "Tiano.h"
;
;---------------------------------------------------------------------------
.686
.model flat,C
.code
;---------------------------------------------------------------------------
;UINT64
;RShiftU64 (
; IN UINT64 Operand,
; IN UINTN Count
; )
;/*++
;
;Routine Description:
; This routine allows a 64 bit value to be right shifted by 32 bits and returns the
; shifted value.
; Count is valid up 63. (Only Bits 0-5 is valid for Count)
;Arguments:
; Operand - Value to be shifted
; Count - Number of times to shift right.
;
;Returns:
;
; Value shifted right identified by the Count.
;
;--*/
RShiftU64 PROC
mov eax, [esp + 4]; dword ptr Operand[0]
mov edx, [esp + 8]; dword ptr Operand[4]
;
; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EDX is not touched
; For CL of 32 - 63, it will be shifted 0 - 31 so we will move edx to eax later.
;
mov ecx, [esp + 0Ch] ; Count
and ecx, 63
shrd eax, edx, cl
shr edx, cl
cmp ecx, 32
jc short _RShiftU64_Done
;
; Since Count is 32 - 63, edx will have been shifted by 0 - 31
; If shifted by 32 or more, set upper 32 bits to zero.
;
mov eax, edx
xor edx, edx
_RShiftU64_Done:
ret
RShiftU64 ENDP
END