MdePkg/BaseLib: Add bit field population calculating methods
[mirror_edk2.git] / MdePkg / Library / BaseLib / BitField.c
index d2d3150..645a662 100644 (file)
@@ -920,3 +920,89 @@ BitFieldAndThenOr64 (
            OrData\r
            );\r
 }\r
+\r
+/**\r
+  Reads a bit field from a 32-bit value, counts and returns\r
+  the number of set bits.\r
+\r
+  Counts the number of set bits in the  bit field specified by\r
+  StartBit and EndBit in Operand. The count is returned.\r
+\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Operand   Operand on which to perform the bitfield operation.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+\r
+  @return The number of bits set between StartBit and EndBit.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+BitFieldCountOnes32 (\r
+  IN       UINT32                   Operand,\r
+  IN       UINTN                    StartBit,\r
+  IN       UINTN                    EndBit\r
+  )\r
+{\r
+  UINT32 Count;\r
+\r
+  ASSERT (EndBit < 32);\r
+  ASSERT (StartBit <= EndBit);\r
+\r
+  Count = BitFieldRead32 (Operand, StartBit, EndBit);\r
+  Count -= ((Count >> 1) & 0x55555555);\r
+  Count = (Count & 0x33333333) + ((Count >> 2) & 0x33333333);\r
+  Count += Count >> 4;\r
+  Count &= 0x0F0F0F0F;\r
+  Count += Count >> 8;\r
+  Count += Count >> 16;\r
+\r
+  return (UINT8) Count & 0x3F;\r
+}\r
+\r
+/**\r
+   Reads a bit field from a 64-bit value, counts and returns\r
+   the number of set bits.\r
+\r
+   Counts the number of set bits in the  bit field specified by\r
+   StartBit and EndBit in Operand. The count is returned.\r
+\r
+   If StartBit is greater than 63, then ASSERT().\r
+   If EndBit is greater than 63, then ASSERT().\r
+   If EndBit is less than StartBit, then ASSERT().\r
+\r
+   @param  Operand   Operand on which to perform the bitfield operation.\r
+   @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+   Range 0..63.\r
+   @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+   Range 0..63.\r
+\r
+   @return The number of bits set between StartBit and EndBit.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+BitFieldCountOnes64 (\r
+  IN       UINT64                   Operand,\r
+  IN       UINTN                    StartBit,\r
+  IN       UINTN                    EndBit\r
+  )\r
+{\r
+  UINT64 BitField;\r
+  UINT8 Count;\r
+\r
+  ASSERT (EndBit < 64);\r
+  ASSERT (StartBit <= EndBit);\r
+\r
+  BitField = BitFieldRead64 (Operand, StartBit, EndBit);\r
+  Count = BitFieldCountOnes32 ((UINT32) BitField, 0, 31);\r
+  Count += BitFieldCountOnes32 ((UINT32) RShiftU64(BitField, 32), 0, 31);\r
+\r
+  return Count;\r
+}\r
+\r