* [PATCH v2] MdePkg/BaseLib: Add bit field population calculating methods
@ 2018-07-03 14:50 Tomas Pilar (tpilar)
2018-07-04 2:58 ` Gao, Liming
0 siblings, 1 reply; 2+ messages in thread
From: Tomas Pilar (tpilar) @ 2018-07-03 14:50 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael D Kinney, Liming Gao
Add 32-bit and 64-bit functions that count number of set bits in a bit field
using a divide-and-count method.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Tomas Pilar <tpilar@solarflare.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
MdePkg/Include/Library/BaseLib.h | 56 +++++++++++++++++++++++++++
MdePkg/Library/BaseLib/BitField.c | 79 +++++++++++++++++++++++++++++++++++++++
2 files changed, 135 insertions(+)
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 1db3a04..123ae19 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -4609,6 +4609,62 @@ BitFieldAndThenOr64 (
IN UINT64 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
+ );
+
+/**
+ 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
+ );
+
//
// Base Library Checksum Functions
//
diff --git a/MdePkg/Library/BaseLib/BitField.c b/MdePkg/Library/BaseLib/BitField.c
index d2d3150..56b8eb2 100644
--- a/MdePkg/Library/BaseLib/BitField.c
+++ b/MdePkg/Library/BaseLib/BitField.c
@@ -920,3 +920,82 @@ 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
+ )
+{
+ ASSERT (EndBit < 32);
+ ASSERT (StartBit <= EndBit);
+
+ UINT32 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
+ )
+{
+ ASSERT (EndBit < 64);
+ ASSERT (StartBit <= EndBit);
+
+ UINT64 BitField = BitFieldRead64 (Operand, StartBit, EndBit);
+ UINT8 Count = BitFieldHammingWeight32 (BitField, 0, 31);
+ return Count + BitFieldHammingWeight32 (RShiftU64(BitField, 32), 0, 31);
+}
+
--
2.9.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2] MdePkg/BaseLib: Add bit field population calculating methods
2018-07-03 14:50 [PATCH v2] MdePkg/BaseLib: Add bit field population calculating methods Tomas Pilar (tpilar)
@ 2018-07-04 2:58 ` Gao, Liming
0 siblings, 0 replies; 2+ messages in thread
From: Gao, Liming @ 2018-07-04 2:58 UTC (permalink / raw)
To: Tomas Pilar (tpilar), edk2-devel@lists.01.org; +Cc: Kinney, Michael D
Tom:
There are two issues here.
1) BitFieldHammingWeight32 should be replaced by BitFieldCountOnes32.
2) edk2 coding style requires the local variable is declared first, then assign the value to it. Don't assign the value in its declaration.
Thanks
Liming
>-----Original Message-----
>From: Tomas Pilar (tpilar) [mailto:tpilar@solarflare.com]
>Sent: Tuesday, July 03, 2018 10:50 PM
>To: edk2-devel@lists.01.org
>Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
><liming.gao@intel.com>
>Subject: [PATCH v2] MdePkg/BaseLib: Add bit field population calculating
>methods
>
>Add 32-bit and 64-bit functions that count number of set bits in a bit field
>using a divide-and-count method.
>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Tomas Pilar <tpilar@solarflare.com>
>Cc: Liming Gao <liming.gao@intel.com>
>Cc: Michael D Kinney <michael.d.kinney@intel.com>
>---
> MdePkg/Include/Library/BaseLib.h | 56 +++++++++++++++++++++++++++
> MdePkg/Library/BaseLib/BitField.c | 79
>+++++++++++++++++++++++++++++++++++++++
> 2 files changed, 135 insertions(+)
>
>diff --git a/MdePkg/Include/Library/BaseLib.h
>b/MdePkg/Include/Library/BaseLib.h
>index 1db3a04..123ae19 100644
>--- a/MdePkg/Include/Library/BaseLib.h
>+++ b/MdePkg/Include/Library/BaseLib.h
>@@ -4609,6 +4609,62 @@ BitFieldAndThenOr64 (
> IN UINT64 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
>+ );
>+
>+/**
>+ 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
>+ );
>+
> //
> // Base Library Checksum Functions
> //
>diff --git a/MdePkg/Library/BaseLib/BitField.c
>b/MdePkg/Library/BaseLib/BitField.c
>index d2d3150..56b8eb2 100644
>--- a/MdePkg/Library/BaseLib/BitField.c
>+++ b/MdePkg/Library/BaseLib/BitField.c
>@@ -920,3 +920,82 @@ 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
>+ )
>+{
>+ ASSERT (EndBit < 32);
>+ ASSERT (StartBit <= EndBit);
>+
>+ UINT32 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
>+ )
>+{
>+ ASSERT (EndBit < 64);
>+ ASSERT (StartBit <= EndBit);
>+
>+ UINT64 BitField = BitFieldRead64 (Operand, StartBit, EndBit);
>+ UINT8 Count = BitFieldHammingWeight32 (BitField, 0, 31);
>+ return Count + BitFieldHammingWeight32 (RShiftU64(BitField, 32), 0, 31);
>+}
>+
>--
>2.9.5
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-07-04 2:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-03 14:50 [PATCH v2] MdePkg/BaseLib: Add bit field population calculating methods Tomas Pilar (tpilar)
2018-07-04 2:58 ` Gao, Liming
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox