BitfieldExtensions.cs
1 using System.Numerics; 2 using System.Runtime.CompilerServices; 3 4 namespace Ryujinx.Common.Utilities 5 { 6 public static class BitfieldExtensions 7 { 8 [MethodImpl(MethodImplOptions.AggressiveInlining)] 9 public static bool Extract<T>(this T value, int lsb) where T : IBinaryInteger<T> 10 { 11 int bitSize = Unsafe.SizeOf<T>() * 8; 12 lsb &= bitSize - 1; 13 14 return !T.IsZero((value >>> lsb) & T.One); 15 } 16 17 [MethodImpl(MethodImplOptions.AggressiveInlining)] 18 public static T Extract<T>(this T value, int lsb, int length) where T : IBinaryInteger<T> 19 { 20 int bitSize = Unsafe.SizeOf<T>() * 8; 21 lsb &= bitSize - 1; 22 23 return (value >>> lsb) & (~T.Zero >>> (bitSize - length)); 24 } 25 26 [MethodImpl(MethodImplOptions.AggressiveInlining)] 27 public static T ExtractSx<T>(this T value, int lsb, int length) where T : IBinaryInteger<T> 28 { 29 int bitSize = Unsafe.SizeOf<T>() * 8; 30 int shift = lsb & (bitSize - 1); 31 32 return (value << (bitSize - (shift + length))) >> (bitSize - length); 33 } 34 35 [MethodImpl(MethodImplOptions.AggressiveInlining)] 36 public static T Insert<T>(this T value, int lsb, bool toInsert) where T : IBinaryInteger<T> 37 { 38 int bitSize = Unsafe.SizeOf<T>() * 8; 39 lsb &= bitSize - 1; 40 41 T mask = T.One << lsb; 42 43 return (value & ~mask) | (toInsert ? mask : T.Zero); 44 } 45 46 [MethodImpl(MethodImplOptions.AggressiveInlining)] 47 public static T Insert<T>(this T value, int lsb, int length, T toInsert) where T : IBinaryInteger<T> 48 { 49 int bitSize = Unsafe.SizeOf<T>() * 8; 50 lsb &= bitSize - 1; 51 52 T mask = (~T.Zero >>> (bitSize - length)) << lsb; 53 54 return (value & ~mask) | ((toInsert << lsb) & mask); 55 } 56 } 57 }