X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdePkg%2FLibrary%2FBaseLib%2FBitField.c;h=862af53e9c3f5e26115bf912b0ea394f98148dfa;hb=2f88bd3a1296c522317f1c21377876de63de5be7;hp=eb5fcd938c9a6ed9a3e00e4a3d59623e3c1dd73f;hpb=94952554cc604750f3df3d4e8ae068703481d258;p=mirror_edk2.git
diff --git a/MdePkg/Library/BaseLib/BitField.c b/MdePkg/Library/BaseLib/BitField.c
index eb5fcd938c..862af53e9c 100644
--- a/MdePkg/Library/BaseLib/BitField.c
+++ b/MdePkg/Library/BaseLib/BitField.c
@@ -1,14 +1,8 @@
/** @file
Bit field functions of BaseLib.
- Copyright (c) 2006 - 2012, 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.
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -29,9 +23,9 @@
UINTN
EFIAPI
InternalBaseLibBitFieldReadUint (
- IN UINTN Operand,
- IN UINTN StartBit,
- IN UINTN EndBit
+ IN UINTN Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
)
{
//
@@ -62,22 +56,25 @@ InternalBaseLibBitFieldReadUint (
UINTN
EFIAPI
InternalBaseLibBitFieldOrUint (
- IN UINTN Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINTN OrData
+ IN UINTN Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINTN OrData
)
{
//
- // Higher bits in OrData those are not used must be zero.
+ // Higher bits in OrData those are not used must be zero.
+ //
+ // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
//
- ASSERT ((OrData >> (EndBit - StartBit + 1)) == 0);
-
+ ASSERT ((OrData >> (EndBit - StartBit)) == ((OrData >> (EndBit - StartBit)) & 1));
+
//
// ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
// are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
//
- return Operand | ((OrData << StartBit) & ~((UINTN) -2 << EndBit));
+ return Operand | ((OrData << StartBit) & ~((UINTN)-2 << EndBit));
}
/**
@@ -101,16 +98,19 @@ InternalBaseLibBitFieldOrUint (
UINTN
EFIAPI
InternalBaseLibBitFieldAndUint (
- IN UINTN Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINTN AndData
+ IN UINTN Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINTN AndData
)
{
//
- // Higher bits in AndData those are not used must be zero.
+ // Higher bits in AndData those are not used must be zero.
+ //
+ // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
//
- ASSERT ((AndData >> (EndBit - StartBit + 1)) == 0);
+ ASSERT ((AndData >> (EndBit - StartBit)) == ((AndData >> (EndBit - StartBit)) & 1));
//
// ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
@@ -141,9 +141,9 @@ InternalBaseLibBitFieldAndUint (
UINT8
EFIAPI
BitFieldRead8 (
- IN UINT8 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit
+ IN UINT8 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
)
{
ASSERT (EndBit < 8);
@@ -177,10 +177,10 @@ BitFieldRead8 (
UINT8
EFIAPI
BitFieldWrite8 (
- IN UINT8 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT8 Value
+ IN UINT8 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
)
{
ASSERT (EndBit < 8);
@@ -215,10 +215,10 @@ BitFieldWrite8 (
UINT8
EFIAPI
BitFieldOr8 (
- IN UINT8 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT8 OrData
+ IN UINT8 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
)
{
ASSERT (EndBit < 8);
@@ -253,10 +253,10 @@ BitFieldOr8 (
UINT8
EFIAPI
BitFieldAnd8 (
- IN UINT8 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT8 AndData
+ IN UINT8 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
)
{
ASSERT (EndBit < 8);
@@ -269,7 +269,7 @@ BitFieldAnd8 (
bitwise OR, and returns the result.
Performs a bitwise AND between the bit field specified by StartBit and EndBit
- in Operand and the value specified by AndData, followed by a bitwise
+ in Operand and the value specified by AndData, followed by a bitwise
OR with value specified by OrData. All other bits in Operand are
preserved. The new 8-bit value is returned.
@@ -294,11 +294,11 @@ BitFieldAnd8 (
UINT8
EFIAPI
BitFieldAndThenOr8 (
- IN UINT8 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT8 AndData,
- IN UINT8 OrData
+ IN UINT8 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
)
{
ASSERT (EndBit < 8);
@@ -333,9 +333,9 @@ BitFieldAndThenOr8 (
UINT16
EFIAPI
BitFieldRead16 (
- IN UINT16 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit
+ IN UINT16 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
)
{
ASSERT (EndBit < 16);
@@ -369,10 +369,10 @@ BitFieldRead16 (
UINT16
EFIAPI
BitFieldWrite16 (
- IN UINT16 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT16 Value
+ IN UINT16 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
)
{
ASSERT (EndBit < 16);
@@ -407,10 +407,10 @@ BitFieldWrite16 (
UINT16
EFIAPI
BitFieldOr16 (
- IN UINT16 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT16 OrData
+ IN UINT16 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
)
{
ASSERT (EndBit < 16);
@@ -445,10 +445,10 @@ BitFieldOr16 (
UINT16
EFIAPI
BitFieldAnd16 (
- IN UINT16 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT16 AndData
+ IN UINT16 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
)
{
ASSERT (EndBit < 16);
@@ -461,7 +461,7 @@ BitFieldAnd16 (
bitwise OR, and returns the result.
Performs a bitwise AND between the bit field specified by StartBit and EndBit
- in Operand and the value specified by AndData, followed by a bitwise
+ in Operand and the value specified by AndData, followed by a bitwise
OR with value specified by OrData. All other bits in Operand are
preserved. The new 16-bit value is returned.
@@ -486,11 +486,11 @@ BitFieldAnd16 (
UINT16
EFIAPI
BitFieldAndThenOr16 (
- IN UINT16 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT16 AndData,
- IN UINT16 OrData
+ IN UINT16 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
)
{
ASSERT (EndBit < 16);
@@ -525,9 +525,9 @@ BitFieldAndThenOr16 (
UINT32
EFIAPI
BitFieldRead32 (
- IN UINT32 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit
+ IN UINT32 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
)
{
ASSERT (EndBit < 32);
@@ -561,10 +561,10 @@ BitFieldRead32 (
UINT32
EFIAPI
BitFieldWrite32 (
- IN UINT32 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT32 Value
+ IN UINT32 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
)
{
ASSERT (EndBit < 32);
@@ -599,10 +599,10 @@ BitFieldWrite32 (
UINT32
EFIAPI
BitFieldOr32 (
- IN UINT32 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT32 OrData
+ IN UINT32 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
)
{
ASSERT (EndBit < 32);
@@ -637,10 +637,10 @@ BitFieldOr32 (
UINT32
EFIAPI
BitFieldAnd32 (
- IN UINT32 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT32 AndData
+ IN UINT32 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
)
{
ASSERT (EndBit < 32);
@@ -653,7 +653,7 @@ BitFieldAnd32 (
bitwise OR, and returns the result.
Performs a bitwise AND between the bit field specified by StartBit and EndBit
- in Operand and the value specified by AndData, followed by a bitwise
+ in Operand and the value specified by AndData, followed by a bitwise
OR with value specified by OrData. All other bits in Operand are
preserved. The new 32-bit value is returned.
@@ -678,11 +678,11 @@ BitFieldAnd32 (
UINT32
EFIAPI
BitFieldAndThenOr32 (
- IN UINT32 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT32 AndData,
- IN UINT32 OrData
+ IN UINT32 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
)
{
ASSERT (EndBit < 32);
@@ -717,9 +717,9 @@ BitFieldAndThenOr32 (
UINT64
EFIAPI
BitFieldRead64 (
- IN UINT64 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit
+ IN UINT64 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
)
{
ASSERT (EndBit < 64);
@@ -753,10 +753,10 @@ BitFieldRead64 (
UINT64
EFIAPI
BitFieldWrite64 (
- IN UINT64 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT64 Value
+ IN UINT64 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT64 Value
)
{
ASSERT (EndBit < 64);
@@ -791,10 +791,10 @@ BitFieldWrite64 (
UINT64
EFIAPI
BitFieldOr64 (
- IN UINT64 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT64 OrData
+ IN UINT64 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT64 OrData
)
{
UINT64 Value1;
@@ -802,10 +802,16 @@ BitFieldOr64 (
ASSERT (EndBit < 64);
ASSERT (StartBit <= EndBit);
- ASSERT (RShiftU64 (OrData, EndBit - StartBit + 1) == 0);
+ //
+ // Higher bits in OrData those are not used must be zero.
+ //
+ // EndBit - StartBit + 1 might be 64 while the result right shifting 64 on RShiftU64() API is invalid,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
+ //
+ ASSERT (RShiftU64 (OrData, EndBit - StartBit) == (RShiftU64 (OrData, EndBit - StartBit) & 1));
Value1 = LShiftU64 (OrData, StartBit);
- Value2 = LShiftU64 ((UINT64) - 2, EndBit);
+ Value2 = LShiftU64 ((UINT64)-2, EndBit);
return Operand | (Value1 & ~Value2);
}
@@ -837,18 +843,24 @@ BitFieldOr64 (
UINT64
EFIAPI
BitFieldAnd64 (
- IN UINT64 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT64 AndData
+ IN UINT64 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT64 AndData
)
{
UINT64 Value1;
UINT64 Value2;
-
+
ASSERT (EndBit < 64);
ASSERT (StartBit <= EndBit);
- ASSERT (RShiftU64 (AndData, EndBit - StartBit + 1) == 0);
+ //
+ // Higher bits in AndData those are not used must be zero.
+ //
+ // EndBit - StartBit + 1 might be 64 while the right shifting 64 on RShiftU64() API is invalid,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
+ //
+ ASSERT (RShiftU64 (AndData, EndBit - StartBit) == (RShiftU64 (AndData, EndBit - StartBit) & 1));
Value1 = LShiftU64 (~AndData, StartBit);
Value2 = LShiftU64 ((UINT64)-2, EndBit);
@@ -861,7 +873,7 @@ BitFieldAnd64 (
bitwise OR, and returns the result.
Performs a bitwise AND between the bit field specified by StartBit and EndBit
- in Operand and the value specified by AndData, followed by a bitwise
+ in Operand and the value specified by AndData, followed by a bitwise
OR with value specified by OrData. All other bits in Operand are
preserved. The new 64-bit value is returned.
@@ -886,11 +898,11 @@ BitFieldAnd64 (
UINT64
EFIAPI
BitFieldAndThenOr64 (
- IN UINT64 Operand,
- IN UINTN StartBit,
- IN UINTN EndBit,
- IN UINT64 AndData,
- IN UINT64 OrData
+ IN UINT64 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT64 AndData,
+ IN UINT64 OrData
)
{
ASSERT (EndBit < 64);
@@ -902,3 +914,88 @@ BitFieldAndThenOr64 (
OrData
);
}
+
+/**
+ Reads a bit field from a 32-bit value, counts and returns
+ the number of set bits.
+
+ Counts the number of set bits in the bit field specified by
+ StartBit and EndBit in Operand. The count is returned.
+
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Operand Operand on which to perform the bitfield operation.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+
+ @return The number of bits set between StartBit and EndBit.
+
+**/
+UINT8
+EFIAPI
+BitFieldCountOnes32 (
+ IN UINT32 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ UINT32 Count;
+
+ ASSERT (EndBit < 32);
+ ASSERT (StartBit <= EndBit);
+
+ Count = BitFieldRead32 (Operand, StartBit, EndBit);
+ Count -= ((Count >> 1) & 0x55555555);
+ Count = (Count & 0x33333333) + ((Count >> 2) & 0x33333333);
+ Count += Count >> 4;
+ Count &= 0x0F0F0F0F;
+ Count += Count >> 8;
+ Count += Count >> 16;
+
+ return (UINT8)Count & 0x3F;
+}
+
+/**
+ Reads a bit field from a 64-bit value, counts and returns
+ the number of set bits.
+
+ Counts the number of set bits in the bit field specified by
+ StartBit and EndBit in Operand. The count is returned.
+
+ If StartBit is greater than 63, then ASSERT().
+ If EndBit is greater than 63, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Operand Operand on which to perform the bitfield operation.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..63.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..63.
+
+ @return The number of bits set between StartBit and EndBit.
+
+**/
+UINT8
+EFIAPI
+BitFieldCountOnes64 (
+ IN UINT64 Operand,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ UINT64 BitField;
+ UINT8 Count;
+
+ ASSERT (EndBit < 64);
+ ASSERT (StartBit <= EndBit);
+
+ BitField = BitFieldRead64 (Operand, StartBit, EndBit);
+ Count = BitFieldCountOnes32 ((UINT32)BitField, 0, 31);
+ Count += BitFieldCountOnes32 ((UINT32)RShiftU64 (BitField, 32), 0, 31);
+
+ return Count;
+}