/** @file | |
Leaf math worker functions that require 64-bit arithmetic support from the | |
compiler. | |
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> | |
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. | |
**/ | |
#include "BaseLibInternals.h" | |
/** | |
Shifts a 64-bit integer left between 0 and 63 bits. The low bits | |
are filled with zeros. The shifted value is returned. | |
This function shifts the 64-bit value Operand to the left by Count bits. The | |
low Count bits are set to zero. The shifted value is returned. | |
@param Operand The 64-bit operand to shift left. | |
@param Count The number of bits to shift left. | |
@return Operand << Count. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathLShiftU64 ( | |
IN UINT64 Operand, | |
IN UINTN Count | |
) | |
{ | |
return Operand << Count; | |
} | |
/** | |
Shifts a 64-bit integer right between 0 and 63 bits. This high bits | |
are filled with zeros. The shifted value is returned. | |
This function shifts the 64-bit value Operand to the right by Count bits. The | |
high Count bits are set to zero. The shifted value is returned. | |
@param Operand The 64-bit operand to shift right. | |
@param Count The number of bits to shift right. | |
@return Operand >> Count. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathRShiftU64 ( | |
IN UINT64 Operand, | |
IN UINTN Count | |
) | |
{ | |
return Operand >> Count; | |
} | |
/** | |
Shifts a 64-bit integer right between 0 and 63 bits. The high bits | |
are filled with original integer's bit 63. The shifted value is returned. | |
This function shifts the 64-bit value Operand to the right by Count bits. The | |
high Count bits are set to bit 63 of Operand. The shifted value is returned. | |
@param Operand The 64-bit operand to shift right. | |
@param Count The number of bits to shift right. | |
@return Operand arithmetically shifted right by Count. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathARShiftU64 ( | |
IN UINT64 Operand, | |
IN UINTN Count | |
) | |
{ | |
INTN TestValue; | |
// | |
// Test if this compiler supports arithmetic shift | |
// | |
TestValue = (((-1) << (sizeof (-1) * 8 - 1)) >> (sizeof (-1) * 8 - 1)); | |
if (TestValue == -1) { | |
// | |
// Arithmetic shift is supported | |
// | |
return (UINT64)((INT64)Operand >> Count); | |
} | |
// | |
// Arithmetic is not supported | |
// | |
return (Operand >> Count) | | |
((INTN)Operand < 0 ? ~((UINTN)-1 >> Count) : 0); | |
} | |
/** | |
Rotates a 64-bit integer left between 0 and 63 bits, filling | |
the low bits with the high bits that were rotated. | |
This function rotates the 64-bit value Operand to the left by Count bits. The | |
low Count bits are fill with the high Count bits of Operand. The rotated | |
value is returned. | |
@param Operand The 64-bit operand to rotate left. | |
@param Count The number of bits to rotate left. | |
@return Operand <<< Count. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathLRotU64 ( | |
IN UINT64 Operand, | |
IN UINTN Count | |
) | |
{ | |
return (Operand << Count) | (Operand >> (64 - Count)); | |
} | |
/** | |
Rotates a 64-bit integer right between 0 and 63 bits, filling | |
the high bits with the high low bits that were rotated. | |
This function rotates the 64-bit value Operand to the right by Count bits. | |
The high Count bits are fill with the low Count bits of Operand. The rotated | |
value is returned. | |
@param Operand The 64-bit operand to rotate right. | |
@param Count The number of bits to rotate right. | |
@return Operand >>> Count. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathRRotU64 ( | |
IN UINT64 Operand, | |
IN UINTN Count | |
) | |
{ | |
return (Operand >> Count) | (Operand << (64 - Count)); | |
} | |
/** | |
Switches the endianess of a 64-bit integer. | |
This function swaps the bytes in a 64-bit unsigned value to switch the value | |
from little endian to big endian or vice versa. The byte swapped value is | |
returned. | |
@param Operand A 64-bit unsigned value. | |
@return The byte swapped Operand. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathSwapBytes64 ( | |
IN UINT64 Operand | |
) | |
{ | |
UINT64 LowerBytes; | |
UINT64 HigherBytes; | |
LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand); | |
HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32)); | |
return (LowerBytes << 32 | HigherBytes); | |
} | |
/** | |
Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer | |
and generates a 64-bit unsigned result. | |
This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit | |
unsigned value Multiplier and generates a 64-bit unsigned result. This 64- | |
bit unsigned result is returned. | |
@param Multiplicand A 64-bit unsigned value. | |
@param Multiplier A 32-bit unsigned value. | |
@return Multiplicand * Multiplier | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathMultU64x32 ( | |
IN UINT64 Multiplicand, | |
IN UINT32 Multiplier | |
) | |
{ | |
return Multiplicand * Multiplier; | |
} | |
/** | |
Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer | |
and generates a 64-bit unsigned result. | |
This function multiplies the 64-bit unsigned value Multiplicand by the 64-bit | |
unsigned value Multiplier and generates a 64-bit unsigned result. This 64- | |
bit unsigned result is returned. | |
@param Multiplicand A 64-bit unsigned value. | |
@param Multiplier A 64-bit unsigned value. | |
@return Multiplicand * Multiplier. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathMultU64x64 ( | |
IN UINT64 Multiplicand, | |
IN UINT64 Multiplier | |
) | |
{ | |
return Multiplicand * Multiplier; | |
} | |
/** | |
Divides a 64-bit unsigned integer by a 32-bit unsigned integer and | |
generates a 64-bit unsigned result. | |
This function divides the 64-bit unsigned value Dividend by the 32-bit | |
unsigned value Divisor and generates a 64-bit unsigned quotient. This | |
function returns the 64-bit unsigned quotient. | |
@param Dividend A 64-bit unsigned value. | |
@param Divisor A 32-bit unsigned value. | |
@return Dividend / Divisor. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathDivU64x32 ( | |
IN UINT64 Dividend, | |
IN UINT32 Divisor | |
) | |
{ | |
return Dividend / Divisor; | |
} | |
/** | |
Divides a 64-bit unsigned integer by a 32-bit unsigned integer and | |
generates a 32-bit unsigned remainder. | |
This function divides the 64-bit unsigned value Dividend by the 32-bit | |
unsigned value Divisor and generates a 32-bit remainder. This function | |
returns the 32-bit unsigned remainder. | |
@param Dividend A 64-bit unsigned value. | |
@param Divisor A 32-bit unsigned value. | |
@return Dividend % Divisor. | |
**/ | |
UINT32 | |
EFIAPI | |
InternalMathModU64x32 ( | |
IN UINT64 Dividend, | |
IN UINT32 Divisor | |
) | |
{ | |
return (UINT32)(Dividend % Divisor); | |
} | |
/** | |
Divides a 64-bit unsigned integer by a 32-bit unsigned integer and | |
generates a 64-bit unsigned result and an optional 32-bit unsigned remainder. | |
This function divides the 64-bit unsigned value Dividend by the 32-bit | |
unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder | |
is not NULL, then the 32-bit unsigned remainder is returned in Remainder. | |
This function returns the 64-bit unsigned quotient. | |
@param Dividend A 64-bit unsigned value. | |
@param Divisor A 32-bit unsigned value. | |
@param Remainder A pointer to a 32-bit unsigned value. This parameter is | |
optional and may be NULL. | |
@return Dividend / Divisor. | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathDivRemU64x32 ( | |
IN UINT64 Dividend, | |
IN UINT32 Divisor, | |
OUT UINT32 *Remainder OPTIONAL | |
) | |
{ | |
if (Remainder != NULL) { | |
*Remainder = (UINT32)(Dividend % Divisor); | |
} | |
return Dividend / Divisor; | |
} | |
/** | |
Divides a 64-bit unsigned integer by a 64-bit unsigned integer and | |
generates a 64-bit unsigned result and an optional 64-bit unsigned remainder. | |
This function divides the 64-bit unsigned value Dividend by the 64-bit | |
unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder | |
is not NULL, then the 64-bit unsigned remainder is returned in Remainder. | |
This function returns the 64-bit unsigned quotient. | |
@param Dividend A 64-bit unsigned value. | |
@param Divisor A 64-bit unsigned value. | |
@param Remainder A pointer to a 64-bit unsigned value. This parameter is | |
optional and may be NULL. | |
@return Dividend / Divisor | |
**/ | |
UINT64 | |
EFIAPI | |
InternalMathDivRemU64x64 ( | |
IN UINT64 Dividend, | |
IN UINT64 Divisor, | |
OUT UINT64 *Remainder OPTIONAL | |
) | |
{ | |
if (Remainder != NULL) { | |
*Remainder = Dividend % Divisor; | |
} | |
return Dividend / Divisor; | |
} | |
/** | |
Divides a 64-bit signed integer by a 64-bit signed integer and | |
generates a 64-bit signed result and an optional 64-bit signed remainder. | |
This function divides the 64-bit signed value Dividend by the 64-bit | |
signed value Divisor and generates a 64-bit signed quotient. If Remainder | |
is not NULL, then the 64-bit signed remainder is returned in Remainder. | |
This function returns the 64-bit signed quotient. | |
@param Dividend A 64-bit signed value. | |
@param Divisor A 64-bit signed value. | |
@param Remainder A pointer to a 64-bit signed value. This parameter is | |
optional and may be NULL. | |
@return Dividend / Divisor. | |
**/ | |
INT64 | |
EFIAPI | |
InternalMathDivRemS64x64 ( | |
IN INT64 Dividend, | |
IN INT64 Divisor, | |
OUT INT64 *Remainder OPTIONAL | |
) | |
{ | |
if (Remainder != NULL) { | |
*Remainder = Dividend % Divisor; | |
} | |
return Dividend / Divisor; | |
} |