--- /dev/null
+;---------------------------------------------------------------------------\r
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; DivU64x32.c\r
+;\r
+;Abstract:\r
+;\r
+; 64-bit division function for IA-32\r
+;\r
+;--*/\r
+\r
+;---------------------------------------------------------------------------\r
+ .386\r
+ .model flat,C\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+;UINT64\r
+;DivU64x32 (\r
+; IN UINT64 Dividend,\r
+; IN UINTN Divisor,\r
+; OUT UINTN *Remainder OPTIONAL\r
+; )\r
+;/*++\r
+\r
+;Routine Description:\r
+\r
+; This routine allows a 64 bit value to be divided with a 32 bit value returns \r
+; 64bit result and the Remainder.\r
+;\r
+;Arguments:\r
+\r
+; Dividend - dividend\r
+; Divisor - divisor\r
+; Remainder - buffer for remainder\r
+; \r
+;Returns:\r
+\r
+; Dividend / Divisor\r
+; Remainder = Dividend mod Divisor\r
+; \r
+;N.B. only works for 31bit divisors!!\r
+;\r
+;--*/\r
+;---------------------------------------------------------------------------\r
+\r
+DivU64x32 PROC\r
+ xor edx, edx ; Clear EDX\r
+\r
+ mov eax, [esp + 8] ; Put high 32 bits of 64-bit dividend in EAX\r
+ mov ecx, [esp + 12] ; Put 32 bits divisor in ECX\r
+ div ecx ; Dividend Divisor Quoitent...Remainder\r
+ ; 0:EAX / ECX = EAX EDX \r
+\r
+ push eax ; Push quoitent in stack\r
+\r
+ mov eax, [esp + 4] ; Put low 32 bits of 64-bit dividend in EAX \r
+ div ecx ; Leave the REMAINDER in EDX as High 32-bit of new dividend\r
+ ; Dividend Divisor Quoitent...Remainder \r
+ ; EDX:EAX / ECX = EAX EDX \r
+\r
+ mov ecx, [esp + 16] ; Put &REMAINDER to ecx\r
+\r
+ jecxz Label1 ; If ecx == 0, no remainder exist, return with quoitent in EDX directly \r
+ mov dword ptr [ecx], edx ; Put EDX through REMAINDER pointer in ECX \r
+\r
+Label1:\r
+ pop edx ; Pop High 32-bit QUOITENT to EDX\r
+\r
+DivU64x32 ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; EfiCopyMem.c\r
+;\r
+;Abstract:\r
+;\r
+; This is the code that supports IA32-optimized CopyMem service\r
+;\r
+;--*/\r
+\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .mmx\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+\r
+;VOID\r
+;EfiCommonLibCopyMem (\r
+; IN VOID *Destination,\r
+; IN VOID *Source,\r
+; IN UINTN Count\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+;\r
+; Copy Length bytes from Source to Destination.\r
+;\r
+;Arguments:\r
+;\r
+; Destination - Target of copy\r
+;\r
+; Source - Place to copy from\r
+;\r
+; Length - Number of bytes to copy\r
+;\r
+;Returns:\r
+;\r
+; None\r
+;\r
+;--*/\r
+EfiCommonLibCopyMem PROC\r
+\r
+ push ebp\r
+ mov ebp, esp\r
+ push ecx ; reserve space for Scratch Local variable UINT64 MmxSave\r
+ push ecx\r
+ push esi\r
+ push edi\r
+ \r
+ mov ecx, [ebp + 10h] ; Count\r
+ mov esi, [ebp + 0Ch] ; Source\r
+ mov edi, [ebp + 8] ; Destination\r
+\r
+ ; First off, make sure we have no overlap. That is to say,\r
+ ; if (Source == Destination) => do nothing\r
+ ; if (Source + Count <= Destination) => regular copy\r
+ ; if (Destination + Count <= Source) => regular copy\r
+ ; otherwise, do a reverse copy\r
+ mov eax, esi\r
+ add eax, ecx ; Source + Count\r
+ cmp eax, edi\r
+ jle _StartByteCopy\r
+\r
+ mov eax, edi\r
+ add eax, ecx ; Dest + Count\r
+ cmp eax, esi\r
+ jle _StartByteCopy\r
+\r
+ cmp esi, edi\r
+ je _CopyMemDone \r
+ jl _CopyOverlapped ; too bad -- overlaps\r
+\r
+ ; Pick up misaligned start bytes to get destination pointer 4-byte aligned\r
+_StartByteCopy:\r
+ cmp ecx, 0\r
+ je _CopyMemDone ; Count == 0, all done\r
+ mov edx, edi\r
+ and dl, 3 ; check lower 2 bits of address\r
+ test dl, dl \r
+ je SHORT _CopyBlocks ; already aligned?\r
+\r
+ ; Copy a byte\r
+ mov al, BYTE PTR [esi] ; get byte from Source\r
+ mov BYTE PTR [edi], al ; write byte to Destination\r
+ dec ecx\r
+ inc edi\r
+ inc esi\r
+ jmp _StartByteCopy ; back to top of loop\r
+\r
+_CopyBlocks:\r
+ ; Compute how many 64-byte blocks we can clear \r
+ mov eax, ecx ; get Count in eax\r
+ shr eax, 6 ; convert to 64-byte count\r
+ shl eax, 6 ; convert back to bytes\r
+ sub ecx, eax ; subtract from the original count\r
+ shr eax, 6 ; and this is how many 64-byte blocks\r
+\r
+ ; If no 64-byte blocks, then skip \r
+ cmp eax, 0\r
+ je _CopyRemainingDWords\r
+\r
+ ; Save mm0 to UINT64 MmxSave\r
+ movq [ebp - 8], mm0\r
+\r
+copymmx:\r
+ \r
+ movq mm0, QWORD PTR ds:[esi]\r
+ movq QWORD PTR ds:[edi], mm0\r
+ movq mm0, QWORD PTR ds:[esi+8]\r
+ movq QWORD PTR ds:[edi+8], mm0\r
+ movq mm0, QWORD PTR ds:[esi+16]\r
+ movq QWORD PTR ds:[edi+16], mm0\r
+ movq mm0, QWORD PTR ds:[esi+24]\r
+ movq QWORD PTR ds:[edi+24], mm0\r
+ movq mm0, QWORD PTR ds:[esi+32]\r
+ movq QWORD PTR ds:[edi+32], mm0\r
+ movq mm0, QWORD PTR ds:[esi+40]\r
+ movq QWORD PTR ds:[edi+40], mm0\r
+ movq mm0, QWORD PTR ds:[esi+48]\r
+ movq QWORD PTR ds:[edi+48], mm0\r
+ movq mm0, QWORD PTR ds:[esi+56]\r
+ movq QWORD PTR ds:[edi+56], mm0\r
+ \r
+ add edi, 64\r
+ add esi, 64\r
+ dec eax\r
+ jnz copymmx\r
+ \r
+; Restore mm0 from MmxSave\r
+ movq mm0, [ebp - 8]\r
+ emms ; Exit MMX Instruction\r
+\r
+ ; Copy as many DWORDS as possible\r
+_CopyRemainingDWords:\r
+ cmp ecx, 4\r
+ jb _CopyRemainingBytes\r
+\r
+ mov eax, DWORD PTR [esi] ; get data from Source\r
+ mov DWORD PTR [edi], eax ; write byte to Destination\r
+ sub ecx, 4 ; decrement Count\r
+ add esi, 4 ; advance Source pointer\r
+ add edi, 4 ; advance Destination pointer\r
+ jmp _CopyRemainingDWords ; back to top\r
+\r
+_CopyRemainingBytes:\r
+ cmp ecx, 0\r
+ je _CopyMemDone\r
+ mov al, BYTE PTR [esi] ; get byte from Source\r
+ mov BYTE PTR [edi], al ; write byte to Destination\r
+ dec ecx\r
+ inc esi\r
+ inc edi ; advance Destination pointer\r
+ jmp SHORT _CopyRemainingBytes ; back to top of loop\r
+\r
+ ;\r
+ ; We do this block if the source and destination buffers overlap. To\r
+ ; handle it, copy starting at the end of the source buffer and work\r
+ ; your way back. Since this is the atypical case, this code has not\r
+ ; been optimized, and thus simply copies bytes.\r
+ ;\r
+_CopyOverlapped:\r
+ \r
+ ; Move the source and destination pointers to the end of the range\r
+ add esi, ecx ; Source + Count\r
+ dec esi\r
+ add edi, ecx ; Dest + Count\r
+ dec edi\r
+\r
+_CopyOverlappedLoop:\r
+ cmp ecx, 0\r
+ je _CopyMemDone\r
+ mov al, BYTE PTR [esi] ; get byte from Source\r
+ mov BYTE PTR [edi], al ; write byte to Destination\r
+ dec ecx\r
+ dec esi\r
+ dec edi\r
+ jmp _CopyOverlappedLoop ; back to top of loop\r
+\r
+_CopyMemDone:\r
+\r
+ pop edi\r
+ pop esi\r
+ leave\r
+ ret\r
+EfiCommonLibCopyMem ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; EfiSetMem.asm\r
+;\r
+;Abstract:\r
+;\r
+; This is the code that supports IA32-optimized SetMem service\r
+;\r
+;--*/\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .mmx\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+;VOID\r
+;EfiCommonLibSetMem (\r
+; IN VOID *Buffer,\r
+; IN UINTN Count,\r
+; IN UINT8 Value\r
+; )\r
+;/*++\r
+;\r
+;Input: VOID *Buffer - Pointer to buffer to write\r
+; UINTN Count - Number of bytes to write\r
+; UINT8 Value - Value to write\r
+;\r
+;Output: None.\r
+;\r
+;Saves:\r
+;\r
+;Modifies:\r
+;\r
+;Description: This function is an optimized set-memory function.\r
+;\r
+;Notes: This function tries to set memory 8 bytes at a time. As a result, \r
+; it first picks up any misaligned bytes, then words, before getting \r
+; in the main loop that does the 8-byte clears.\r
+;\r
+;--*/\r
+EfiCommonLibSetMem PROC\r
+\r
+ push ebp\r
+ mov ebp, esp\r
+ sub esp, 10h; Reserve space for local variable UINT64 QWordValue @[ebp - 10H] & UINT64 MmxSave @[ebp - 18H]\r
+ push ebx\r
+ push edi\r
+\r
+ mov edx, [ebp + 0Ch] ; Count\r
+ test edx, edx\r
+ je _SetMemDone\r
+\r
+ push ebx\r
+ \r
+ mov eax, [ebp + 8] ; Buffer\r
+ mov bl, [ebp + 10h] ; Value\r
+ mov edi, eax\r
+ mov bh, bl\r
+ \r
+ cmp edx, 256\r
+ jb _SetRemindingByte\r
+ \r
+ and al, 07h\r
+ test al, al\r
+ je _SetBlock\r
+ \r
+ mov eax, edi\r
+ shr eax, 3\r
+ inc eax\r
+ shl eax, 3\r
+ sub eax, edi\r
+ cmp eax, edx\r
+ jnb _SetRemindingByte\r
+ \r
+ sub edx, eax\r
+ mov ecx, eax\r
+\r
+ mov al, bl\r
+ rep stosb\r
+\r
+_SetBlock:\r
+ mov eax, edx\r
+ shr eax, 6\r
+ test eax, eax\r
+ je _SetRemindingByte\r
+\r
+ shl eax, 6\r
+ sub edx, eax\r
+ shr eax, 6\r
+\r
+ mov WORD PTR [ebp - 10H], bx ; QWordValue[0]\r
+ mov WORD PTR [ebp - 10H + 2], bx ; QWordValue[2]\r
+ mov WORD PTR [ebp - 10H + 4], bx ; QWordValue[4]\r
+ mov WORD PTR [ebp - 10H + 6], bx ; QWordValue[6]\r
+ \r
+ \r
+ movq [ebp - 8], mm0 ; Save mm0 to MmxSave\r
+ movq mm0, [ebp - 10H] ; Load QWordValue to mm0\r
+\r
+_B:\r
+ movq QWORD PTR ds:[edi], mm0\r
+ movq QWORD PTR ds:[edi+8], mm0\r
+ movq QWORD PTR ds:[edi+16], mm0\r
+ movq QWORD PTR ds:[edi+24], mm0\r
+ movq QWORD PTR ds:[edi+32], mm0\r
+ movq QWORD PTR ds:[edi+40], mm0\r
+ movq QWORD PTR ds:[edi+48], mm0\r
+ movq QWORD PTR ds:[edi+56], mm0\r
+ add edi, 64\r
+ dec eax\r
+ jnz _B\r
+ \r
+; Restore mm0\r
+ movq mm0, [ebp - 8] ; Restore MmxSave to mm0\r
+ emms ; Exit MMX Instruction\r
+ \r
+_SetRemindingByte:\r
+ mov ecx, edx\r
+\r
+ mov eax, ebx\r
+ shl eax, 16\r
+ mov ax, bx\r
+ shr ecx, 2\r
+ rep stosd\r
+ \r
+ mov ecx, edx\r
+ and ecx, 3\r
+ rep stosb\r
+ \r
+ pop ebx\r
+\r
+_SetMemDone:\r
+\r
+ pop edi\r
+ pop ebx\r
+ leave\r
+ ret\r
+\r
+EfiCommonLibSetMem ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; EfiZeroMem.c\r
+;\r
+;Abstract:\r
+;\r
+; This is the code that supports IA32-optimized ZeroMem service\r
+;\r
+;--*/\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .mmx\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+;VOID\r
+;EfiCommonLibZeroMem (\r
+; IN VOID *Buffer,\r
+; IN UINTN Count\r
+; )\r
+;/*++\r
+;\r
+;Input: VOID *Buffer - Pointer to buffer to clear\r
+; UINTN Count - Number of bytes to clear\r
+;\r
+;Output: None.\r
+;\r
+;Saves:\r
+;\r
+;Modifies:\r
+;\r
+;Description: This function is an optimized zero-memory function.\r
+;\r
+;Notes: This function tries to zero memory 8 bytes at a time. As a result, \r
+; it first picks up any misaligned bytes, then words, before getting \r
+; in the main loop that does the 8-byte clears.\r
+;\r
+;--*/\r
+EfiCommonLibZeroMem PROC\r
+; UINT64 MmxSave;\r
+ push ebp\r
+ mov ebp, esp\r
+ push ecx ; Reserve space for local variable MmxSave\r
+ push ecx\r
+ push edi\r
+ \r
+ mov ecx, [ebp + 0Ch] ; Count\r
+ mov edi, [ebp + 8]; Buffer\r
+\r
+ ; Pick up misaligned start bytes (get pointer 4-byte aligned)\r
+_StartByteZero:\r
+ mov eax, edi \r
+ and al, 3 ; check lower 2 bits of address\r
+ test al, al\r
+ je _ZeroBlocks ; already aligned?\r
+ cmp ecx, 0\r
+ je _ZeroMemDone\r
+\r
+ ; Clear the byte memory location\r
+ mov BYTE PTR [edi], 0 \r
+ inc edi\r
+\r
+ ; Decrement our count\r
+ dec ecx\r
+ jmp _StartByteZero ; back to top of loop\r
+\r
+_ZeroBlocks:\r
+\r
+ ; Compute how many 64-byte blocks we can clear \r
+ mov edx, ecx\r
+ shr ecx, 6 ; convert to 64-byte count\r
+ shl ecx, 6 ; convert back to bytes\r
+ sub edx, ecx ; subtract from the original count\r
+ shr ecx, 6 ; and this is how many 64-byte blocks\r
+\r
+ ; If no 64-byte blocks, then skip \r
+ cmp ecx, 0\r
+ je _ZeroRemaining\r
+\r
+ ; Save mm0\r
+ movq [ebp - 8], mm0 ; Save mm0 to MmxSave\r
+\r
+ pxor mm0, mm0 ; Clear mm0\r
+\r
+_B:\r
+ movq QWORD PTR ds:[edi], mm0\r
+ movq QWORD PTR ds:[edi+8], mm0\r
+ movq QWORD PTR ds:[edi+16], mm0\r
+ movq QWORD PTR ds:[edi+24], mm0\r
+ movq QWORD PTR ds:[edi+32], mm0\r
+ movq QWORD PTR ds:[edi+40], mm0\r
+ movq QWORD PTR ds:[edi+48], mm0\r
+ movq QWORD PTR ds:[edi+56], mm0\r
+ \r
+ add edi, 64\r
+ dec ecx\r
+ jnz _B\r
+ \r
+; Restore mm0\r
+ movq mm0, [ebp - 8] ; Restore mm0 from MmxSave\r
+ emms ; Exit MMX Instruction\r
+\r
+_ZeroRemaining:\r
+ ; Zero out as many DWORDS as possible\r
+ mov ecx, edx\r
+ shr ecx, 2\r
+ xor eax, eax\r
+\r
+ rep stosd\r
+\r
+ ; Zero out remaining as bytes\r
+ mov ecx, edx\r
+ and ecx, 03\r
+\r
+ rep stosb\r
+ \r
+_ZeroMemDone:\r
+\r
+ pop edi\r
+ leave\r
+ ret\r
+EfiCommonLibZeroMem ENDP \r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; GetPowerOfTwo.c\r
+;\r
+;Abstract:\r
+;\r
+; Calculates the largest integer that is both \r
+; a power of two and less than Input\r
+;\r
+;--*/\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+\r
+;UINT64\r
+;GetPowerOfTwo (\r
+; IN UINT64 Input\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+;\r
+; Calculates the largest integer that is both \r
+; a power of two and less than Input\r
+;\r
+;Arguments:\r
+;\r
+; Input - value to calculate power of two\r
+;\r
+;Returns:\r
+;\r
+; the largest integer that is both a power of \r
+; two and less than Input\r
+;\r
+;--*/\r
+GetPowerOfTow PROC\r
+ xor eax, eax\r
+ mov edx, eax\r
+ mov ecx, [esp + 8] ; dword ptr Input[4]\r
+ jecxz _F\r
+ bsr ecx, ecx\r
+ bts edx, ecx\r
+ jmp _Exit\r
+_F:\r
+ mov ecx, [esp + 4] ; dword ptr Input[0]\r
+ jecxz _Exit\r
+ bsr ecx, ecx\r
+ bts eax, ecx\r
+_Exit:\r
+\r
+ ret\r
+GetPowerOfTow ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; LShiftU64.c\r
+;\r
+;Abstract:\r
+;\r
+; 64-bit left shift function for IA-32\r
+;\r
+;--*/\r
+;\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+;\r
+;UINT64\r
+;LShiftU64 (\r
+; IN UINT64 Operand,\r
+; IN UINTN Count\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+; \r
+; This routine allows a 64 bit value to be left shifted by 32 bits and \r
+; returns the shifted value.\r
+; Count is valid up 63. (Only Bits 0-5 is valid for Count)\r
+;\r
+;Arguments:\r
+;\r
+; Operand - Value to be shifted\r
+; Count - Number of times to shift left.\r
+; \r
+;Returns:\r
+;\r
+; Value shifted left identified by the Count.\r
+;\r
+;--*/\r
+LShiftU64 PROC\r
+ \r
+ mov eax, [esp + 4]; dword ptr Operand[0]\r
+ mov edx, [esp + 8]; dword ptr Operand[4]\r
+ \r
+ ;\r
+ ; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EAX is not touched\r
+ ; For CL of 32 - 63, it will be shifted 0 - 31 so we will move eax to edx later. \r
+ ;\r
+ mov ecx, [esp + 0Ch]; Count\r
+ and ecx, 63\r
+ shld edx, eax, cl\r
+ shl eax, cl\r
+ \r
+ ;\r
+ ; Since Count is 32 - 63, eax will have been shifted by 0 - 31 \r
+ ; If shifted by 32 or more, set lower 32 bits to zero.\r
+ ;\r
+ cmp ecx, 32\r
+ jc short _LShiftU64_Done\r
+ \r
+ mov edx, eax\r
+ xor eax, eax\r
+\r
+_LShiftU64_Done:\r
+\r
+ ret\r
+LShiftU64 ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; Log2.c\r
+;\r
+;Abstract:\r
+;\r
+; 64-bit integer logarithm function for IA-32\r
+;\r
+;--*/\r
+;\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+\r
+;UINT8\r
+;Log2 (\r
+; IN UINT64 Operand\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+; \r
+; Calculates and floors logarithms based on 2\r
+;\r
+;Arguments:\r
+;\r
+; Operand - value to calculate logarithm\r
+; \r
+;Returns:\r
+;\r
+; The largest integer that is less than or equal\r
+; to the logarithm of Operand based on 2 \r
+;\r
+;--*/\r
+Log2 PROC\r
+ mov ecx, 64\r
+ \r
+ cmp dword ptr [esp + 4], 0 ; (UINT32 *(&Operand))\r
+ jne _Log2_Wend \r
+ cmp dword ptr [esp + 8], 0 ; (UINT32 *(&Operand)) + 1\r
+ jne _Log2_Wend \r
+ mov cl, 0FFH\r
+ jmp _Log2_Done\r
+ \r
+_Log2_Wend:\r
+ dec ecx\r
+ cmp ecx, 32\r
+ jae _Log2_Higher\r
+ bt [esp + 4], ecx ; (UINT32 *(&Operand))\r
+ jmp _Log2_Bit\r
+ \r
+_Log2_Higher:\r
+ mov eax, ecx\r
+ sub eax, 32\r
+ bt [esp + 8], eax ; (UINT32 *(&Operand)) + 1\r
+ \r
+_Log2_Bit:\r
+ jc _Log2_Done\r
+ jmp _Log2_Wend\r
+ \r
+_Log2_Done:\r
+ mov al, cl\r
+\r
+ ret\r
+\r
+ Log2 ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; MultU64x32.c\r
+;\r
+;Abstract:\r
+;\r
+; 64-bit Multiplication function for IA-32\r
+;\r
+;--*/\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+\r
+;UINT64\r
+;MultU64x32 (\r
+; IN UINT64 Multiplicand,\r
+; IN UINTN Multiplier\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+;\r
+; This routine allows a 64 bit value to be multiplied with a 32 bit \r
+; value returns 64bit result.\r
+; No checking if the result is greater than 64bits\r
+;\r
+;Arguments:\r
+;\r
+; Multiplicand - multiplicand\r
+; Multiplier - multiplier\r
+;\r
+;Returns:\r
+;\r
+; Multiplicand * Multiplier\r
+;\r
+;--*/\r
+MultU64x32 PROC\r
+\r
+ mov eax, [esp + 4]; dword ptr Multiplicand[0]\r
+ mul dword ptr [esp + 0Ch] ; Multiplier\r
+ push eax\r
+ push edx\r
+ mov eax, [esp + 10h]; dword ptr Multiplicand[4]\r
+ mul dword ptr [esp + 14h]; Multiplier\r
+ ;\r
+ ; The value in edx stored by second multiplication overflows\r
+ ; the output and should be discarded. So here we overwrite it\r
+ ; with the edx value of first multiplication.\r
+ ;\r
+ pop edx\r
+ add edx, eax\r
+ pop eax\r
+\r
+ ret\r
+MultU64x32 ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; Power10U64.c\r
+;\r
+;Abstract:\r
+;\r
+; Calculates Operand * 10 ^ Power\r
+;\r
+;--*/\r
+;\r
+;#include "Tiano.h"\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .code\r
+\r
+MultU64x32 PROTO C\r
+;---------------------------------------------------------------------------\r
+;\r
+;UINT64\r
+;MultU64x32 (\r
+; IN UINT64 Multiplicand,\r
+; IN UINTN Multiplier\r
+; );\r
+;\r
+;UINT64\r
+;Power10U64 (\r
+; IN UINT64 Operand,\r
+; IN UINTN Power\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+;\r
+; Raise 10 to the power of Power, and multiply the result with Operand\r
+;\r
+;Arguments:\r
+;\r
+; Operand - multiplicand\r
+; Power - power\r
+;\r
+;Returns:\r
+;\r
+; Operand * 10 ^ Power\r
+;\r
+;--*/\r
+Power10U64 PROC\r
+ push ebp\r
+ mov ebp, esp\r
+ mov eax, dword ptr [ebp + 8]; dword ptr Operand[0]\r
+ mov edx, dword ptr [ebp + 0Ch]; dword ptr Operand[4]\r
+ mov ecx, dword ptr [ebp + 10h] ;Power\r
+ jcxz _Power10U64_Done\r
+ \r
+_Power10U64_Wend:\r
+ push 10\r
+ push [ebp + 0Ch]; dword ptr Operand[4]\r
+ push [ebp + 8]; dword ptr Operand[0]\r
+ call MultU64x32\r
+ add esp, 0cH\r
+ mov [ebp + 8] , eax; dword ptr Operand[0]\r
+ mov [ebp + 0Ch] , edx; dword ptr Operand[4]\r
+ loop _Power10U64_Wend\r
+\r
+_Power10U64_Done:\r
+\r
+ pop ebp\r
+ ret\r
+Power10U64 ENDP\r
+ END\r
--- /dev/null
+;/*++\r
+;\r
+;Copyright (c) 2006, 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
+;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
+; RShiftU64.c\r
+;\r
+;Abstract:\r
+;\r
+; 64-bit right shift function for IA-32\r
+;\r
+;--*/\r
+;\r
+;#include "Tiano.h"\r
+;\r
+;---------------------------------------------------------------------------\r
+ .686\r
+ .model flat,C\r
+ .code\r
+\r
+;---------------------------------------------------------------------------\r
+;UINT64\r
+;RShiftU64 (\r
+; IN UINT64 Operand,\r
+; IN UINTN Count\r
+; )\r
+;/*++\r
+;\r
+;Routine Description:\r
+; This routine allows a 64 bit value to be right shifted by 32 bits and returns the \r
+; shifted value.\r
+; Count is valid up 63. (Only Bits 0-5 is valid for Count)\r
+;Arguments:\r
+; Operand - Value to be shifted\r
+; Count - Number of times to shift right.\r
+; \r
+;Returns:\r
+;\r
+; Value shifted right identified by the Count.\r
+;\r
+;--*/\r
+RShiftU64 PROC\r
+ \r
+ mov eax, [esp + 4]; dword ptr Operand[0]\r
+ mov edx, [esp + 8]; dword ptr Operand[4]\r
+ \r
+ ;\r
+ ; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EDX is not touched\r
+ ; For CL of 32 - 63, it will be shifted 0 - 31 so we will move edx to eax later. \r
+ ;\r
+ mov ecx, [esp + 0Ch] ; Count\r
+ and ecx, 63\r
+ shrd eax, edx, cl\r
+ shr edx, cl\r
+\r
+ cmp ecx, 32\r
+ jc short _RShiftU64_Done\r
+\r
+ ;\r
+ ; Since Count is 32 - 63, edx will have been shifted by 0 - 31 \r
+ ; If shifted by 32 or more, set upper 32 bits to zero.\r
+ ;\r
+ mov eax, edx\r
+ xor edx, edx\r
+\r
+_RShiftU64_Done:\r
+\r
+ ret\r
+RShiftU64 ENDP \r
+ END\r