You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
2.8 KiB

  1. /*
  2. Copyright 2011 Jun Wako <wakojun@gmail.com>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "util.h"
  15. // bit population - return number of on-bit
  16. __attribute__((noinline)) uint8_t bitpop(uint8_t bits) {
  17. uint8_t c;
  18. for (c = 0; bits; c++) bits &= bits - 1;
  19. return c;
  20. /*
  21. const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
  22. return bit_count[bits>>4] + bit_count[bits&0x0F]
  23. */
  24. }
  25. uint8_t bitpop16(uint16_t bits) {
  26. uint8_t c;
  27. for (c = 0; bits; c++) bits &= bits - 1;
  28. return c;
  29. }
  30. uint8_t bitpop32(uint32_t bits) {
  31. uint8_t c;
  32. for (c = 0; bits; c++) bits &= bits - 1;
  33. return c;
  34. }
  35. // most significant on-bit - return highest location of on-bit
  36. // NOTE: return 0 when bit0 is on or all bits are off
  37. __attribute__((noinline)) uint8_t biton(uint8_t bits) {
  38. uint8_t n = 0;
  39. if (bits >> 4) {
  40. bits >>= 4;
  41. n += 4;
  42. }
  43. if (bits >> 2) {
  44. bits >>= 2;
  45. n += 2;
  46. }
  47. if (bits >> 1) {
  48. bits >>= 1;
  49. n += 1;
  50. }
  51. return n;
  52. }
  53. uint8_t biton16(uint16_t bits) {
  54. uint8_t n = 0;
  55. if (bits >> 8) {
  56. bits >>= 8;
  57. n += 8;
  58. }
  59. if (bits >> 4) {
  60. bits >>= 4;
  61. n += 4;
  62. }
  63. if (bits >> 2) {
  64. bits >>= 2;
  65. n += 2;
  66. }
  67. if (bits >> 1) {
  68. bits >>= 1;
  69. n += 1;
  70. }
  71. return n;
  72. }
  73. uint8_t biton32(uint32_t bits) {
  74. uint8_t n = 0;
  75. if (bits >> 16) {
  76. bits >>= 16;
  77. n += 16;
  78. }
  79. if (bits >> 8) {
  80. bits >>= 8;
  81. n += 8;
  82. }
  83. if (bits >> 4) {
  84. bits >>= 4;
  85. n += 4;
  86. }
  87. if (bits >> 2) {
  88. bits >>= 2;
  89. n += 2;
  90. }
  91. if (bits >> 1) {
  92. bits >>= 1;
  93. n += 1;
  94. }
  95. return n;
  96. }
  97. __attribute__((noinline)) uint8_t bitrev(uint8_t bits) {
  98. bits = (bits & 0x0f) << 4 | (bits & 0xf0) >> 4;
  99. bits = (bits & 0b00110011) << 2 | (bits & 0b11001100) >> 2;
  100. bits = (bits & 0b01010101) << 1 | (bits & 0b10101010) >> 1;
  101. return bits;
  102. }
  103. uint16_t bitrev16(uint16_t bits) {
  104. bits = bitrev(bits & 0x00ff) << 8 | bitrev((bits & 0xff00) >> 8);
  105. return bits;
  106. }
  107. uint32_t bitrev32(uint32_t bits) {
  108. bits = (uint32_t)bitrev16(bits & 0x0000ffff) << 16 | bitrev16((bits & 0xffff0000) >> 16);
  109. return bits;
  110. }