math.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 153 行
C
153 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
math.c
Abstract:
64-bit Math worker functions for IA-32
--*/
#include "Efi.h"
#include "EfiDriverLib.h"
UINT64
DriverLibLShiftU64 (
IN UINT64 Operand,
IN UINTN Count
)
// Left shift 64bit by 32bit and get a 64bit result
{
UINT64 Result;
_asm {
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
mov ecx, Count
and ecx, 63
shld edx, eax, cl
shl eax, cl
cmp ecx, 32
jc short ls10
mov edx, eax
xor eax, eax
ls10:
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
}
return Result;
}
UINT64
DriverLibRShiftU64 (
IN UINT64 Operand,
IN UINTN Count
)
// Right shift 64bit by 32bit and get a 64bit result
{
UINT64 Result;
_asm {
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
mov ecx, Count
and ecx, 63
shrd eax, edx, cl
shr edx, cl
cmp ecx, 32
jc short rs10
mov eax, edx
xor edx, edx
rs10:
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
}
return Result;
}
UINT64
DriverLibMultU64x32 (
IN UINT64 Multiplicand,
IN UINTN Multiplier
)
// Multiple 64bit by 32bit and get a 64bit result
{
UINT64 Result;
_asm {
mov eax, dword ptr Multiplicand[0]
mul Multiplier
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
mov eax, dword ptr Multiplicand[4]
mul Multiplier
add dword ptr Result[4], eax
}
return Result;
}
UINT64
DriverLibDivU64x32 (
IN UINT64 Dividend,
IN UINTN Divisor,
OUT UINTN *Remainder OPTIONAL
)
// divide 64bit by 32bit and get a 64bit result
// N.B. only works for 31bit divisors!!
{
UINT32 Rem;
UINT32 Bit;
//
// For each bit in the dividend
//
Rem = 0;
for (Bit=0; Bit < 64; Bit++) {
_asm {
shl dword ptr Dividend[0], 1 ; shift rem:dividend left one
rcl dword ptr Dividend[4], 1
rcl dword ptr Rem, 1
mov eax, Rem
cmp eax, Divisor ; Is Rem >= Divisor?
cmc ; No - do nothing
sbb eax, eax ; Else,
sub dword ptr Dividend[0], eax ; set low bit in dividen
and eax, Divisor ; and
sub Rem, eax ; subtract divisor
}
}
if (Remainder) {
*Remainder = Rem;
}
return Dividend;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?