| /** @file | |
| Bit field functions of BaseLib. | |
| Copyright (c) 2006 - 2013, 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" | |
| /** | |
| Worker function that returns a bit field from Operand. | |
| Returns the bitfield specified by the StartBit and the EndBit from Operand. | |
| @param Operand Operand on which to perform the bitfield operation. | |
| @param StartBit The ordinal of the least significant bit in the bit field. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| @return The bit field read. | |
| **/ | |
| UINTN | |
| EFIAPI | |
| InternalBaseLibBitFieldReadUint ( | |
| IN UINTN Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit | |
| ) | |
| { | |
| // | |
| // ~((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 & ~((UINTN)-2 << EndBit)) >> StartBit; | |
| } | |
| /** | |
| Worker function that reads a bit field from Operand, performs a bitwise OR, | |
| and returns the result. | |
| Performs a bitwise OR between the bit field specified by StartBit and EndBit | |
| in Operand and the value specified by AndData. All other bits in Operand are | |
| preserved. The new value is returned. | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| @param OrData The value to OR with the read value from the value. | |
| @return The new value. | |
| **/ | |
| UINTN | |
| EFIAPI | |
| InternalBaseLibBitFieldOrUint ( | |
| IN UINTN Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINTN OrData | |
| ) | |
| { | |
| // | |
| // 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)) == ((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)); | |
| } | |
| /** | |
| Worker function that reads a bit field from Operand, performs a bitwise AND, | |
| 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. All other bits in Operand are | |
| preserved. The new value is returned. | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| @param AndData The value to And with the read value from the value. | |
| @return The new value. | |
| **/ | |
| UINTN | |
| EFIAPI | |
| InternalBaseLibBitFieldAndUint ( | |
| IN UINTN Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINTN AndData | |
| ) | |
| { | |
| // | |
| // 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)) == ((AndData >> (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 & ~((~AndData << StartBit) & ~((UINTN)-2 << EndBit)); | |
| } | |
| /** | |
| Returns a bit field from an 8-bit value. | |
| Returns the bitfield specified by the StartBit and the EndBit from Operand. | |
| If 8-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 7, then ASSERT(). | |
| If EndBit is greater than 7, 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..7. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..7. | |
| @return The bit field read. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| BitFieldRead8 ( | |
| IN UINT8 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit | |
| ) | |
| { | |
| ASSERT (EndBit < 8); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT8)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit); | |
| } | |
| /** | |
| Writes a bit field to an 8-bit value, and returns the result. | |
| Writes Value to the bit field specified by the StartBit and the EndBit in | |
| Operand. All other bits in Operand are preserved. The new 8-bit value is | |
| returned. | |
| If 8-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 7, then ASSERT(). | |
| If EndBit is greater than 7, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If Value is larger than the bitmask value range specified by StartBit and EndBit, 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..7. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..7. | |
| @param Value The new value of the bit field. | |
| @return The new 8-bit value. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| BitFieldWrite8 ( | |
| IN UINT8 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT8 Value | |
| ) | |
| { | |
| ASSERT (EndBit < 8); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value); | |
| } | |
| /** | |
| Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the | |
| result. | |
| Performs a bitwise OR between the bit field specified by StartBit | |
| and EndBit in Operand and the value specified by OrData. All other bits in | |
| Operand are preserved. The new 8-bit value is returned. | |
| If 8-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 7, then ASSERT(). | |
| If EndBit is greater than 7, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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..7. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..7. | |
| @param OrData The value to OR with the read value from the value. | |
| @return The new 8-bit value. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| BitFieldOr8 ( | |
| IN UINT8 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT8 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 8); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT8)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData); | |
| } | |
| /** | |
| Reads a bit field from an 8-bit value, performs a bitwise AND, 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. All other bits in Operand are | |
| preserved. The new 8-bit value is returned. | |
| If 8-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 7, then ASSERT(). | |
| If EndBit is greater than 7, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, 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..7. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..7. | |
| @param AndData The value to AND with the read value from the value. | |
| @return The new 8-bit value. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| BitFieldAnd8 ( | |
| IN UINT8 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT8 AndData | |
| ) | |
| { | |
| ASSERT (EndBit < 8); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT8)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData); | |
| } | |
| /** | |
| Reads a bit field from an 8-bit value, performs a bitwise AND followed by a | |
| 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 | |
| OR with value specified by OrData. All other bits in Operand are | |
| preserved. The new 8-bit value is returned. | |
| If 8-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 7, then ASSERT(). | |
| If EndBit is greater than 7, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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..7. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..7. | |
| @param AndData The value to AND with the read value from the value. | |
| @param OrData The value to OR with the result of the AND operation. | |
| @return The new 8-bit value. | |
| **/ | |
| UINT8 | |
| EFIAPI | |
| BitFieldAndThenOr8 ( | |
| IN UINT8 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT8 AndData, | |
| IN UINT8 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 8); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldOr8 ( | |
| BitFieldAnd8 (Operand, StartBit, EndBit, AndData), | |
| StartBit, | |
| EndBit, | |
| OrData | |
| ); | |
| } | |
| /** | |
| Returns a bit field from a 16-bit value. | |
| Returns the bitfield specified by the StartBit and the EndBit from Operand. | |
| If 16-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 15, then ASSERT(). | |
| If EndBit is greater than 15, 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..15. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..15. | |
| @return The bit field read. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| BitFieldRead16 ( | |
| IN UINT16 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit | |
| ) | |
| { | |
| ASSERT (EndBit < 16); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT16)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit); | |
| } | |
| /** | |
| Writes a bit field to a 16-bit value, and returns the result. | |
| Writes Value to the bit field specified by the StartBit and the EndBit in | |
| Operand. All other bits in Operand are preserved. The new 16-bit value is | |
| returned. | |
| If 16-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 15, then ASSERT(). | |
| If EndBit is greater than 15, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If Value is larger than the bitmask value range specified by StartBit and EndBit, 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..15. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..15. | |
| @param Value The new value of the bit field. | |
| @return The new 16-bit value. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| BitFieldWrite16 ( | |
| IN UINT16 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT16 Value | |
| ) | |
| { | |
| ASSERT (EndBit < 16); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value); | |
| } | |
| /** | |
| Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the | |
| result. | |
| Performs a bitwise OR between the bit field specified by StartBit | |
| and EndBit in Operand and the value specified by OrData. All other bits in | |
| Operand are preserved. The new 16-bit value is returned. | |
| If 16-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 15, then ASSERT(). | |
| If EndBit is greater than 15, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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..15. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..15. | |
| @param OrData The value to OR with the read value from the value. | |
| @return The new 16-bit value. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| BitFieldOr16 ( | |
| IN UINT16 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT16 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 16); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT16)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData); | |
| } | |
| /** | |
| Reads a bit field from a 16-bit value, performs a bitwise AND, 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. All other bits in Operand are | |
| preserved. The new 16-bit value is returned. | |
| If 16-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 15, then ASSERT(). | |
| If EndBit is greater than 15, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, 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..15. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..15. | |
| @param AndData The value to AND with the read value from the value. | |
| @return The new 16-bit value. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| BitFieldAnd16 ( | |
| IN UINT16 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT16 AndData | |
| ) | |
| { | |
| ASSERT (EndBit < 16); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT16)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData); | |
| } | |
| /** | |
| Reads a bit field from a 16-bit value, performs a bitwise AND followed by a | |
| 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 | |
| OR with value specified by OrData. All other bits in Operand are | |
| preserved. The new 16-bit value is returned. | |
| If 16-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 15, then ASSERT(). | |
| If EndBit is greater than 15, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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..15. | |
| @param EndBit The ordinal of the most significant bit in the bit field. | |
| Range 0..15. | |
| @param AndData The value to AND with the read value from the value. | |
| @param OrData The value to OR with the result of the AND operation. | |
| @return The new 16-bit value. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| BitFieldAndThenOr16 ( | |
| IN UINT16 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT16 AndData, | |
| IN UINT16 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 16); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldOr16 ( | |
| BitFieldAnd16 (Operand, StartBit, EndBit, AndData), | |
| StartBit, | |
| EndBit, | |
| OrData | |
| ); | |
| } | |
| /** | |
| Returns a bit field from a 32-bit value. | |
| Returns the bitfield specified by the StartBit and the EndBit from Operand. | |
| If 32-bit operations are not supported, then ASSERT(). | |
| 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 bit field read. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| BitFieldRead32 ( | |
| IN UINT32 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit | |
| ) | |
| { | |
| ASSERT (EndBit < 32); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT32)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit); | |
| } | |
| /** | |
| Writes a bit field to a 32-bit value, and returns the result. | |
| Writes Value to the bit field specified by the StartBit and the EndBit in | |
| Operand. All other bits in Operand are preserved. The new 32-bit value is | |
| returned. | |
| If 32-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 31, then ASSERT(). | |
| If EndBit is greater than 31, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If Value is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param Value The new value of the bit field. | |
| @return The new 32-bit value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| BitFieldWrite32 ( | |
| IN UINT32 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT32 Value | |
| ) | |
| { | |
| ASSERT (EndBit < 32); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value); | |
| } | |
| /** | |
| Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the | |
| result. | |
| Performs a bitwise OR between the bit field specified by StartBit | |
| and EndBit in Operand and the value specified by OrData. All other bits in | |
| Operand are preserved. The new 32-bit value is returned. | |
| If 32-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 31, then ASSERT(). | |
| If EndBit is greater than 31, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param OrData The value to OR with the read value from the value. | |
| @return The new 32-bit value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| BitFieldOr32 ( | |
| IN UINT32 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT32 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 32); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT32)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData); | |
| } | |
| /** | |
| Reads a bit field from a 32-bit value, performs a bitwise AND, 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. All other bits in Operand are | |
| preserved. The new 32-bit value is returned. | |
| If 32-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 31, then ASSERT(). | |
| If EndBit is greater than 31, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param AndData The value to AND with the read value from the value. | |
| @return The new 32-bit value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| BitFieldAnd32 ( | |
| IN UINT32 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT32 AndData | |
| ) | |
| { | |
| ASSERT (EndBit < 32); | |
| ASSERT (StartBit <= EndBit); | |
| return (UINT32)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData); | |
| } | |
| /** | |
| Reads a bit field from a 32-bit value, performs a bitwise AND followed by a | |
| 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 | |
| OR with value specified by OrData. All other bits in Operand are | |
| preserved. The new 32-bit value is returned. | |
| If 32-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 31, then ASSERT(). | |
| If EndBit is greater than 31, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param AndData The value to AND with the read value from the value. | |
| @param OrData The value to OR with the result of the AND operation. | |
| @return The new 32-bit value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| BitFieldAndThenOr32 ( | |
| IN UINT32 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT32 AndData, | |
| IN UINT32 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 32); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldOr32 ( | |
| BitFieldAnd32 (Operand, StartBit, EndBit, AndData), | |
| StartBit, | |
| EndBit, | |
| OrData | |
| ); | |
| } | |
| /** | |
| Returns a bit field from a 64-bit value. | |
| Returns the bitfield specified by the StartBit and the EndBit from Operand. | |
| If 64-bit operations are not supported, then ASSERT(). | |
| 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 bit field read. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| BitFieldRead64 ( | |
| IN UINT64 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit | |
| ) | |
| { | |
| ASSERT (EndBit < 64); | |
| ASSERT (StartBit <= EndBit); | |
| return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit); | |
| } | |
| /** | |
| Writes a bit field to a 64-bit value, and returns the result. | |
| Writes Value to the bit field specified by the StartBit and the EndBit in | |
| Operand. All other bits in Operand are preserved. The new 64-bit value is | |
| returned. | |
| If 64-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 63, then ASSERT(). | |
| If EndBit is greater than 63, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If Value is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param Value The new value of the bit field. | |
| @return The new 64-bit value. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| BitFieldWrite64 ( | |
| IN UINT64 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT64 Value | |
| ) | |
| { | |
| ASSERT (EndBit < 64); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value); | |
| } | |
| /** | |
| Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the | |
| result. | |
| Performs a bitwise OR between the bit field specified by StartBit | |
| and EndBit in Operand and the value specified by OrData. All other bits in | |
| Operand are preserved. The new 64-bit value is returned. | |
| If 64-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 63, then ASSERT(). | |
| If EndBit is greater than 63, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param OrData The value to OR with the read value from the value | |
| @return The new 64-bit value. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| BitFieldOr64 ( | |
| IN UINT64 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT64 OrData | |
| ) | |
| { | |
| UINT64 Value1; | |
| UINT64 Value2; | |
| ASSERT (EndBit < 64); | |
| ASSERT (StartBit <= EndBit); | |
| // | |
| // 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); | |
| return Operand | (Value1 & ~Value2); | |
| } | |
| /** | |
| Reads a bit field from a 64-bit value, performs a bitwise AND, 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. All other bits in Operand are | |
| preserved. The new 64-bit value is returned. | |
| If 64-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 63, then ASSERT(). | |
| If EndBit is greater than 63, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param AndData The value to AND with the read value from the value. | |
| @return The new 64-bit value. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| BitFieldAnd64 ( | |
| IN UINT64 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT64 AndData | |
| ) | |
| { | |
| UINT64 Value1; | |
| UINT64 Value2; | |
| ASSERT (EndBit < 64); | |
| ASSERT (StartBit <= EndBit); | |
| // | |
| // 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); | |
| return Operand & ~(Value1 & ~Value2); | |
| } | |
| /** | |
| Reads a bit field from a 64-bit value, performs a bitwise AND followed by a | |
| 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 | |
| OR with value specified by OrData. All other bits in Operand are | |
| preserved. The new 64-bit value is returned. | |
| If 64-bit operations are not supported, then ASSERT(). | |
| If StartBit is greater than 63, then ASSERT(). | |
| If EndBit is greater than 63, then ASSERT(). | |
| If EndBit is less than StartBit, then ASSERT(). | |
| If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). | |
| If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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. | |
| @param AndData The value to AND with the read value from the value. | |
| @param OrData The value to OR with the result of the AND operation. | |
| @return The new 64-bit value. | |
| **/ | |
| UINT64 | |
| EFIAPI | |
| BitFieldAndThenOr64 ( | |
| IN UINT64 Operand, | |
| IN UINTN StartBit, | |
| IN UINTN EndBit, | |
| IN UINT64 AndData, | |
| IN UINT64 OrData | |
| ) | |
| { | |
| ASSERT (EndBit < 64); | |
| ASSERT (StartBit <= EndBit); | |
| return BitFieldOr64 ( | |
| BitFieldAnd64 (Operand, StartBit, EndBit, AndData), | |
| StartBit, | |
| EndBit, | |
| OrData | |
| ); | |
| } |