/ src / Ryujinx.Common / Utilities / BitfieldExtensions.cs
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  }