BitUtils.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. namespace Ryujinx.Common
  2. {
  3. public static class BitUtils
  4. {
  5. public static int AlignUp(int Value, int Size)
  6. {
  7. return (Value + (Size - 1)) & -Size;
  8. }
  9. public static ulong AlignUp(ulong Value, int Size)
  10. {
  11. return (ulong)AlignUp((long)Value, Size);
  12. }
  13. public static long AlignUp(long Value, int Size)
  14. {
  15. return (Value + (Size - 1)) & -(long)Size;
  16. }
  17. public static int AlignDown(int Value, int Size)
  18. {
  19. return Value & -Size;
  20. }
  21. public static ulong AlignDown(ulong Value, int Size)
  22. {
  23. return (ulong)AlignDown((long)Value, Size);
  24. }
  25. public static long AlignDown(long Value, int Size)
  26. {
  27. return Value & -(long)Size;
  28. }
  29. public static ulong DivRoundUp(ulong Value, uint Dividend)
  30. {
  31. return (Value + Dividend - 1) / Dividend;
  32. }
  33. public static long DivRoundUp(long Value, int Dividend)
  34. {
  35. return (Value + Dividend - 1) / Dividend;
  36. }
  37. public static bool IsPowerOfTwo32(int Value)
  38. {
  39. return Value != 0 && (Value & (Value - 1)) == 0;
  40. }
  41. public static bool IsPowerOfTwo64(long Value)
  42. {
  43. return Value != 0 && (Value & (Value - 1)) == 0;
  44. }
  45. public static int CountLeadingZeros32(int Value)
  46. {
  47. return (int)CountLeadingZeros((ulong)Value, 32);
  48. }
  49. public static int CountLeadingZeros64(long Value)
  50. {
  51. return (int)CountLeadingZeros((ulong)Value, 64);
  52. }
  53. private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
  54. private static ulong CountLeadingZeros(ulong Value, int Size) // Size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
  55. {
  56. if (Value == 0ul)
  57. {
  58. return (ulong)Size;
  59. }
  60. int NibbleIdx = Size;
  61. int PreCount, Count = 0;
  62. do
  63. {
  64. NibbleIdx -= 4;
  65. PreCount = ClzNibbleTbl[(Value >> NibbleIdx) & 0b1111];
  66. Count += PreCount;
  67. }
  68. while (PreCount == 4);
  69. return (ulong)Count;
  70. }
  71. public static long ReverseBits64(long Value)
  72. {
  73. return (long)ReverseBits64((ulong)Value);
  74. }
  75. private static ulong ReverseBits64(ulong Value)
  76. {
  77. Value = ((Value & 0xaaaaaaaaaaaaaaaa) >> 1 ) | ((Value & 0x5555555555555555) << 1 );
  78. Value = ((Value & 0xcccccccccccccccc) >> 2 ) | ((Value & 0x3333333333333333) << 2 );
  79. Value = ((Value & 0xf0f0f0f0f0f0f0f0) >> 4 ) | ((Value & 0x0f0f0f0f0f0f0f0f) << 4 );
  80. Value = ((Value & 0xff00ff00ff00ff00) >> 8 ) | ((Value & 0x00ff00ff00ff00ff) << 8 );
  81. Value = ((Value & 0xffff0000ffff0000) >> 16) | ((Value & 0x0000ffff0000ffff) << 16);
  82. return (Value >> 32) | (Value << 32);
  83. }
  84. }
  85. }