public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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