bits.odin 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. package math_bits
  2. import "core:runtime"
  3. U8_MIN :: 0;
  4. U16_MIN :: 0;
  5. U32_MIN :: 0;
  6. U64_MIN :: 0;
  7. U8_MAX :: 1 << 8 - 1;
  8. U16_MAX :: 1 << 16 - 1;
  9. U32_MAX :: 1 << 32 - 1;
  10. U64_MAX :: 1 << 64 - 1;
  11. I8_MIN :: - 1 << 7;
  12. I16_MIN :: - 1 << 15;
  13. I32_MIN :: - 1 << 31;
  14. I64_MIN :: - 1 << 63;
  15. I8_MAX :: 1 << 7 - 1;
  16. I16_MAX :: 1 << 15 - 1;
  17. I32_MAX :: 1 << 31 - 1;
  18. I64_MAX :: 1 << 63 - 1;
  19. @(default_calling_convention="none")
  20. foreign {
  21. @(link_name="llvm.ctpop.i8") count_ones8 :: proc(i: u8) -> u8 ---
  22. @(link_name="llvm.ctpop.i16") count_ones16 :: proc(i: u16) -> u16 ---
  23. @(link_name="llvm.ctpop.i32") count_ones32 :: proc(i: u32) -> u32 ---
  24. @(link_name="llvm.ctpop.i64") count_ones64 :: proc(i: u64) -> u64 ---
  25. @(link_name="llvm.cttz.i8") trailing_zeros8 :: proc(i: u8, is_zero_undef := false) -> u8 ---
  26. @(link_name="llvm.cttz.i16") trailing_zeros16 :: proc(i: u16, is_zero_undef := false) -> u16 ---
  27. @(link_name="llvm.cttz.i32") trailing_zeros32 :: proc(i: u32, is_zero_undef := false) -> u32 ---
  28. @(link_name="llvm.cttz.i64") trailing_zeros64 :: proc(i: u64, is_zero_undef := false) -> u64 ---
  29. @(link_name="llvm.bitreverse.i8") reverse_bits8 :: proc(i: u8) -> u8 ---
  30. @(link_name="llvm.bitreverse.i16") reverse_bits16 :: proc(i: u16) -> u16 ---
  31. @(link_name="llvm.bitreverse.i32") reverse_bits32 :: proc(i: u32) -> u32 ---
  32. @(link_name="llvm.bitreverse.i64") reverse_bits64 :: proc(i: u64) -> u64 ---
  33. }
  34. trailing_zeros_uint :: proc(i: uint) -> uint {
  35. when size_of(uint) == size_of(u64) {
  36. return uint(trailing_zeros64(u64(i)));
  37. } else {
  38. return uint(trailing_zeros32(u32(i)));
  39. }
  40. }
  41. leading_zeros_u8 :: proc(i: u8) -> int {
  42. return 8*size_of(i) - len_u8(i);
  43. }
  44. leading_zeros_u16 :: proc(i: u16) -> int {
  45. return 8*size_of(i) - len_u16(i);
  46. }
  47. leading_zeros_u32 :: proc(i: u32) -> int {
  48. return 8*size_of(i) - len_u32(i);
  49. }
  50. leading_zeros_u64 :: proc(i: u64) -> int {
  51. return 8*size_of(i) - len_u64(i);
  52. }
  53. byte_swap_u16 :: proc(x: u16) -> u16 {
  54. return runtime.bswap_16(x);
  55. }
  56. byte_swap_u32 :: proc(x: u32) -> u32 {
  57. return runtime.bswap_32(x);
  58. }
  59. byte_swap_u64 :: proc(x: u64) -> u64 {
  60. return runtime.bswap_64(x);
  61. }
  62. byte_swap_i16 :: proc(x: i16) -> i16 {
  63. return i16(runtime.bswap_16(u16(x)));
  64. }
  65. byte_swap_i32 :: proc(x: i32) -> i32 {
  66. return i32(runtime.bswap_32(u32(x)));
  67. }
  68. byte_swap_i64 :: proc(x: i64) -> i64 {
  69. return i64(runtime.bswap_64(u64(x)));
  70. }
  71. byte_swap_u128 :: proc(x: u128) -> u128 {
  72. return runtime.bswap_128(x);
  73. }
  74. byte_swap_i128 :: proc(x: i128) -> i128 {
  75. return i128(runtime.bswap_128(u128(x)));
  76. }
  77. byte_swap_uint :: proc(i: uint) -> uint {
  78. when size_of(uint) == size_of(u32) {
  79. return uint(byte_swap_u32(u32(i)));
  80. } else {
  81. return uint(byte_swap_u64(u64(i)));
  82. }
  83. }
  84. byte_swap_int :: proc(i: int) -> int {
  85. when size_of(int) == size_of(i32) {
  86. return int(byte_swap_i32(i32(i)));
  87. } else {
  88. return int(byte_swap_i64(i64(i)));
  89. }
  90. }
  91. byte_swap :: proc{
  92. byte_swap_u16,
  93. byte_swap_u32,
  94. byte_swap_u64,
  95. byte_swap_u128,
  96. byte_swap_i16,
  97. byte_swap_i32,
  98. byte_swap_i64,
  99. byte_swap_i128,
  100. byte_swap_uint,
  101. byte_swap_int,
  102. };
  103. count_zeros8 :: proc(i: u8) -> u8 { return 8 - count_ones8(i); }
  104. count_zeros16 :: proc(i: u16) -> u16 { return 16 - count_ones16(i); }
  105. count_zeros32 :: proc(i: u32) -> u32 { return 32 - count_ones32(i); }
  106. count_zeros64 :: proc(i: u64) -> u64 { return 64 - count_ones64(i); }
  107. rotate_left8 :: proc(x: u8, k: int) -> u8 {
  108. n :: 8;
  109. s := uint(k) & (n-1);
  110. return x <<s | x>>(n-s);
  111. }
  112. rotate_left16 :: proc(x: u16, k: int) -> u16 {
  113. n :: 16;
  114. s := uint(k) & (n-1);
  115. return x <<s | x>>(n-s);
  116. }
  117. rotate_left32 :: proc(x: u32, k: int) -> u32 {
  118. n :: 32;
  119. s := uint(k) & (n-1);
  120. return x <<s | x>>(n-s);
  121. }
  122. rotate_left64 :: proc(x: u64, k: int) -> u64 {
  123. n :: 64;
  124. s := uint(k) & (n-1);
  125. return x <<s | x>>(n-s);
  126. }
  127. rotate_left :: proc(x: uint, k: int) -> uint {
  128. n :: 8*size_of(uint);
  129. s := uint(k) & (n-1);
  130. return x <<s | x>>(n-s);
  131. }
  132. from_be_u8 :: proc(i: u8) -> u8 { return i; }
  133. from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  134. from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  135. from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  136. from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  137. from_le_u8 :: proc(i: u8) -> u8 { return i; }
  138. from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  139. from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  140. from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  141. from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  142. to_be_u8 :: proc(i: u8) -> u8 { return i; }
  143. to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  144. to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  145. to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  146. to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  147. to_le_u8 :: proc(i: u8) -> u8 { return i; }
  148. to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  149. to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  150. to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  151. to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  152. @(default_calling_convention="none")
  153. foreign {
  154. @(link_name="llvm.uadd.with.overflow.i8") overflowing_add_u8 :: proc(lhs, rhs: u8) -> (u8, bool) ---
  155. @(link_name="llvm.sadd.with.overflow.i8") overflowing_add_i8 :: proc(lhs, rhs: i8) -> (i8, bool) ---
  156. @(link_name="llvm.uadd.with.overflow.i16") overflowing_add_u16 :: proc(lhs, rhs: u16) -> (u16, bool) ---
  157. @(link_name="llvm.sadd.with.overflow.i16") overflowing_add_i16 :: proc(lhs, rhs: i16) -> (i16, bool) ---
  158. @(link_name="llvm.uadd.with.overflow.i32") overflowing_add_u32 :: proc(lhs, rhs: u32) -> (u32, bool) ---
  159. @(link_name="llvm.sadd.with.overflow.i32") overflowing_add_i32 :: proc(lhs, rhs: i32) -> (i32, bool) ---
  160. @(link_name="llvm.uadd.with.overflow.i64") overflowing_add_u64 :: proc(lhs, rhs: u64) -> (u64, bool) ---
  161. @(link_name="llvm.sadd.with.overflow.i64") overflowing_add_i64 :: proc(lhs, rhs: i64) -> (i64, bool) ---
  162. }
  163. overflowing_add_uint :: proc(lhs, rhs: uint) -> (uint, bool) {
  164. when size_of(uint) == size_of(u32) {
  165. x, ok := overflowing_add_u32(u32(lhs), u32(rhs));
  166. return uint(x), ok;
  167. } else {
  168. x, ok := overflowing_add_u64(u64(lhs), u64(rhs));
  169. return uint(x), ok;
  170. }
  171. }
  172. overflowing_add_int :: proc(lhs, rhs: int) -> (int, bool) {
  173. when size_of(int) == size_of(i32) {
  174. x, ok := overflowing_add_i32(i32(lhs), i32(rhs));
  175. return int(x), ok;
  176. } else {
  177. x, ok := overflowing_add_i64(i64(lhs), i64(rhs));
  178. return int(x), ok;
  179. }
  180. }
  181. overflowing_add :: proc{
  182. overflowing_add_u8, overflowing_add_i8,
  183. overflowing_add_u16, overflowing_add_i16,
  184. overflowing_add_u32, overflowing_add_i32,
  185. overflowing_add_u64, overflowing_add_i64,
  186. overflowing_add_uint, overflowing_add_int,
  187. };
  188. @(default_calling_convention="none")
  189. foreign {
  190. @(link_name="llvm.usub.with.overflow.i8") overflowing_sub_u8 :: proc(lhs, rhs: u8) -> (u8, bool) ---
  191. @(link_name="llvm.ssub.with.overflow.i8") overflowing_sub_i8 :: proc(lhs, rhs: i8) -> (i8, bool) ---
  192. @(link_name="llvm.usub.with.overflow.i16") overflowing_sub_u16 :: proc(lhs, rhs: u16) -> (u16, bool) ---
  193. @(link_name="llvm.ssub.with.overflow.i16") overflowing_sub_i16 :: proc(lhs, rhs: i16) -> (i16, bool) ---
  194. @(link_name="llvm.usub.with.overflow.i32") overflowing_sub_u32 :: proc(lhs, rhs: u32) -> (u32, bool) ---
  195. @(link_name="llvm.ssub.with.overflow.i32") overflowing_sub_i32 :: proc(lhs, rhs: i32) -> (i32, bool) ---
  196. @(link_name="llvm.usub.with.overflow.i64") overflowing_sub_u64 :: proc(lhs, rhs: u64) -> (u64, bool) ---
  197. @(link_name="llvm.ssub.with.overflow.i64") overflowing_sub_i64 :: proc(lhs, rhs: i64) -> (i64, bool) ---
  198. }
  199. overflowing_sub_uint :: proc(lhs, rhs: uint) -> (uint, bool) {
  200. when size_of(uint) == size_of(u32) {
  201. x, ok := overflowing_sub_u32(u32(lhs), u32(rhs));
  202. return uint(x), ok;
  203. } else {
  204. x, ok := overflowing_sub_u64(u64(lhs), u64(rhs));
  205. return uint(x), ok;
  206. }
  207. }
  208. overflowing_sub_int :: proc(lhs, rhs: int) -> (int, bool) {
  209. when size_of(int) == size_of(i32) {
  210. x, ok := overflowing_sub_i32(i32(lhs), i32(rhs));
  211. return int(x), ok;
  212. } else {
  213. x, ok := overflowing_sub_i64(i64(lhs), i64(rhs));
  214. return int(x), ok;
  215. }
  216. }
  217. overflowing_sub :: proc{
  218. overflowing_sub_u8, overflowing_sub_i8,
  219. overflowing_sub_u16, overflowing_sub_i16,
  220. overflowing_sub_u32, overflowing_sub_i32,
  221. overflowing_sub_u64, overflowing_sub_i64,
  222. overflowing_sub_uint, overflowing_sub_int,
  223. };
  224. @(default_calling_convention="none")
  225. foreign {
  226. @(link_name="llvm.umul.with.overflow.i8") overflowing_mul_u8 :: proc(lhs, rhs: u8) -> (u8, bool) ---
  227. @(link_name="llvm.smul.with.overflow.i8") overflowing_mul_i8 :: proc(lhs, rhs: i8) -> (i8, bool) ---
  228. @(link_name="llvm.umul.with.overflow.i16") overflowing_mul_u16 :: proc(lhs, rhs: u16) -> (u16, bool) ---
  229. @(link_name="llvm.smul.with.overflow.i16") overflowing_mul_i16 :: proc(lhs, rhs: i16) -> (i16, bool) ---
  230. @(link_name="llvm.umul.with.overflow.i32") overflowing_mul_u32 :: proc(lhs, rhs: u32) -> (u32, bool) ---
  231. @(link_name="llvm.smul.with.overflow.i32") overflowing_mul_i32 :: proc(lhs, rhs: i32) -> (i32, bool) ---
  232. @(link_name="llvm.umul.with.overflow.i64") overflowing_mul_u64 :: proc(lhs, rhs: u64) -> (u64, bool) ---
  233. @(link_name="llvm.smul.with.overflow.i64") overflowing_mul_i64 :: proc(lhs, rhs: i64) -> (i64, bool) ---
  234. }
  235. overflowing_mul_uint :: proc(lhs, rhs: uint) -> (uint, bool) {
  236. when size_of(uint) == size_of(u32) {
  237. x, ok := overflowing_mul_u32(u32(lhs), u32(rhs));
  238. return uint(x), ok;
  239. } else {
  240. x, ok := overflowing_mul_u64(u64(lhs), u64(rhs));
  241. return uint(x), ok;
  242. }
  243. }
  244. overflowing_mul_int :: proc(lhs, rhs: int) -> (int, bool) {
  245. when size_of(int) == size_of(i32) {
  246. x, ok := overflowing_mul_i32(i32(lhs), i32(rhs));
  247. return int(x), ok;
  248. } else {
  249. x, ok := overflowing_mul_i64(i64(lhs), i64(rhs));
  250. return int(x), ok;
  251. }
  252. }
  253. overflowing_mul :: proc{
  254. overflowing_mul_u8, overflowing_mul_i8,
  255. overflowing_mul_u16, overflowing_mul_i16,
  256. overflowing_mul_u32, overflowing_mul_i32,
  257. overflowing_mul_u64, overflowing_mul_i64,
  258. overflowing_mul_uint, overflowing_mul_int,
  259. };
  260. len_u8 :: proc(x: u8) -> int {
  261. return int(len_u8_table[x]);
  262. }
  263. len_u16 :: proc(x: u16) -> (n: int) {
  264. x := x;
  265. if x >= 1<<8 {
  266. x >>= 8;
  267. n = 8;
  268. }
  269. return n + int(len_u8_table[x]);
  270. }
  271. len_u32 :: proc(x: u32) -> (n: int) {
  272. x := x;
  273. if x >= 1<<16 {
  274. x >>= 16;
  275. n = 16;
  276. }
  277. if x >= 1<<8 {
  278. x >>= 8;
  279. n += 8;
  280. }
  281. return n + int(len_u8_table[x]);
  282. }
  283. len_u64 :: proc(x: u64) -> (n: int) {
  284. x := x;
  285. if x >= 1<<32 {
  286. x >>= 32;
  287. n = 32;
  288. }
  289. if x >= 1<<16 {
  290. x >>= 16;
  291. n += 16;
  292. }
  293. if x >= 1<<8 {
  294. x >>= 8;
  295. n += 8;
  296. }
  297. return n + int(len_u8_table[x]);
  298. }
  299. len_uint :: proc(x: uint) -> (n: int) {
  300. when size_of(uint) == size_of(u64) {
  301. return len_u64(u64(x));
  302. } else {
  303. return len_u32(u32(x));
  304. }
  305. }
  306. // returns the minimum number of bits required to represent x
  307. len :: proc{len_u8, len_u16, len_u32, len_u64, len_uint};
  308. add_u32 :: proc(x, y, carry: u32) -> (sum, carry_out: u32) {
  309. yc := y + carry;
  310. sum = x + yc;
  311. if sum < x || yc < y {
  312. carry_out = 1;
  313. }
  314. return;
  315. }
  316. add_u64 :: proc(x, y, carry: u64) -> (sum, carry_out: u64) {
  317. yc := y + carry;
  318. sum = x + yc;
  319. if sum < x || yc < y {
  320. carry_out = 1;
  321. }
  322. return;
  323. }
  324. add_uint :: proc(x, y, carry: uint) -> (sum, carry_out: uint) {
  325. yc := y + carry;
  326. sum = x + yc;
  327. if sum < x || yc < y {
  328. carry_out = 1;
  329. }
  330. return;
  331. }
  332. add :: proc{add_u32, add_u64, add_uint};
  333. sub_u32 :: proc(x, y, borrow: u32) -> (diff, borrow_out: u32) {
  334. yb := y + borrow;
  335. diff = x - yb;
  336. if diff > x || yb < y {
  337. borrow_out = 1;
  338. }
  339. return;
  340. }
  341. sub_u64 :: proc(x, y, borrow: u64) -> (diff, borrow_out: u64) {
  342. yb := y + borrow;
  343. diff = x - yb;
  344. if diff > x || yb < y {
  345. borrow_out = 1;
  346. }
  347. return;
  348. }
  349. sub_uint :: proc(x, y, borrow: uint) -> (diff, borrow_out: uint) {
  350. yb := y + borrow;
  351. diff = x - yb;
  352. if diff > x || yb < y {
  353. borrow_out = 1;
  354. }
  355. return;
  356. }
  357. sub :: proc{sub_u32, sub_u64, sub_uint};
  358. mul_u32 :: proc(x, y: u32) -> (hi, lo: u32) {
  359. z := u64(x) * u64(y);
  360. hi, lo = u32(z>>32), u32(z);
  361. return;
  362. }
  363. mul_u64 :: proc(x, y: u64) -> (hi, lo: u64) {
  364. mask :: 1<<32 - 1;
  365. x0, x1 := x & mask, x >> 32;
  366. y0, y1 := y & mask, y >> 32;
  367. w0 := x0 * y0;
  368. t := x1*y0 + w0>>32;
  369. w1, w2 := t & mask, t >> 32;
  370. w1 += x0 * y1;
  371. hi = x1*y1 + w2 + w1>>32;
  372. lo = x * y;
  373. return;
  374. }
  375. mul_uint :: proc(x, y: uint) -> (hi, lo: uint) {
  376. when size_of(uint) == size_of(u32) {
  377. a, b := mul_u32(u32(x), u32(y));
  378. } else {
  379. #assert(size_of(uint) == size_of(u64));
  380. a, b := mul_u64(u64(x), u64(y));
  381. }
  382. return uint(a), uint(b);
  383. }
  384. mul :: proc{mul_u32, mul_u64, mul_uint};
  385. div_u32 :: proc(hi, lo, y: u32) -> (quo, rem: u32) {
  386. assert(y != 0 && y <= hi);
  387. z := u64(hi)<<32 | u64(lo);
  388. quo, rem = u32(z/u64(y)), u32(z%u64(y));
  389. return;
  390. }
  391. div_u64 :: proc(hi, lo, y: u64) -> (quo, rem: u64) {
  392. y := y;
  393. two32 :: 1 << 32;
  394. mask32 :: two32 - 1;
  395. if y == 0 {
  396. panic("divide error");
  397. }
  398. if y <= hi {
  399. panic("overflow error");
  400. }
  401. s := uint(leading_zeros_u64(y));
  402. y <<= s;
  403. yn1 := y >> 32;
  404. yn0 := y & mask32;
  405. un32 := hi<<s | lo>>(64-s);
  406. un10 := lo << s;
  407. un1 := un10 >> 32;
  408. un0 := un10 & mask32;
  409. q1 := un32 / yn1;
  410. rhat := un32 - q1*yn1;
  411. for q1 >= two32 || q1*yn0 > two32*rhat+un1 {
  412. q1 -= 1;
  413. rhat += yn1;
  414. if rhat >= two32 {
  415. break;
  416. }
  417. }
  418. un21 := un32*two32 + un1 - q1*y;
  419. q0 := un21 / yn1;
  420. rhat = un21 - q0*yn1;
  421. for q0 >= two32 || q0*yn0 > two32*rhat+un0 {
  422. q0 -= 1;
  423. rhat += yn1;
  424. if rhat >= two32 {
  425. break;
  426. }
  427. }
  428. return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s;
  429. }
  430. div_uint :: proc(hi, lo, y: uint) -> (quo, rem: uint) {
  431. when size_of(uint) == size_of(u32) {
  432. a, b := div_u32(u32(hi), u32(lo), u32(y));
  433. } else {
  434. #assert(size_of(uint) == size_of(u64));
  435. a, b := div_u64(u64(hi), u64(lo), u64(y));
  436. }
  437. return uint(a), uint(b);
  438. }
  439. div :: proc{div_u32, div_u64, div_uint};
  440. is_power_of_two_u8 :: proc(i: u8) -> bool { return i > 0 && (i & (i-1)) == 0; }
  441. is_power_of_two_i8 :: proc(i: i8) -> bool { return i > 0 && (i & (i-1)) == 0; }
  442. is_power_of_two_u16 :: proc(i: u16) -> bool { return i > 0 && (i & (i-1)) == 0; }
  443. is_power_of_two_i16 :: proc(i: i16) -> bool { return i > 0 && (i & (i-1)) == 0; }
  444. is_power_of_two_u32 :: proc(i: u32) -> bool { return i > 0 && (i & (i-1)) == 0; }
  445. is_power_of_two_i32 :: proc(i: i32) -> bool { return i > 0 && (i & (i-1)) == 0; }
  446. is_power_of_two_u64 :: proc(i: u64) -> bool { return i > 0 && (i & (i-1)) == 0; }
  447. is_power_of_two_i64 :: proc(i: i64) -> bool { return i > 0 && (i & (i-1)) == 0; }
  448. is_power_of_two_uint :: proc(i: uint) -> bool { return i > 0 && (i & (i-1)) == 0; }
  449. is_power_of_two_int :: proc(i: int) -> bool { return i > 0 && (i & (i-1)) == 0; }
  450. is_power_of_two :: proc{
  451. is_power_of_two_u8, is_power_of_two_i8,
  452. is_power_of_two_u16, is_power_of_two_i16,
  453. is_power_of_two_u32, is_power_of_two_i32,
  454. is_power_of_two_u64, is_power_of_two_i64,
  455. is_power_of_two_uint, is_power_of_two_int,
  456. };
  457. @private
  458. len_u8_table := [256]u8{
  459. 0 = 0,
  460. 1 = 1,
  461. 2..<4 = 2,
  462. 4..<8 = 3,
  463. 8..<16 = 4,
  464. 16..<32 = 5,
  465. 32..<64 = 6,
  466. 64..<128 = 7,
  467. 128..<256 = 8,
  468. };
  469. bitfield_extract_u8 :: proc(value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1<<bits - 1); }
  470. bitfield_extract_u16 :: proc(value: u16, offset, bits: uint) -> u16 { return (value >> offset) & u16(1<<bits - 1); }
  471. bitfield_extract_u32 :: proc(value: u32, offset, bits: uint) -> u32 { return (value >> offset) & u32(1<<bits - 1); }
  472. bitfield_extract_u64 :: proc(value: u64, offset, bits: uint) -> u64 { return (value >> offset) & u64(1<<bits - 1); }
  473. bitfield_extract_u128 :: proc(value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1); }
  474. bitfield_extract_uint :: proc(value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1); }
  475. bitfield_extract_i8 :: proc(value: i8, offset, bits: uint) -> i8 {
  476. v := (u8(value) >> offset) & u8(1<<bits - 1);
  477. m := u8(1<<(bits-1));
  478. r := (v~m) - m;
  479. return i8(r);
  480. }
  481. bitfield_extract_i16 :: proc(value: i16, offset, bits: uint) -> i16 {
  482. v := (u16(value) >> offset) & u16(1<<bits - 1);
  483. m := u16(1<<(bits-1));
  484. r := (v~m) - m;
  485. return i16(r);
  486. }
  487. bitfield_extract_i32 :: proc(value: i32, offset, bits: uint) -> i32 {
  488. v := (u32(value) >> offset) & u32(1<<bits - 1);
  489. m := u32(1<<(bits-1));
  490. r := (v~m) - m;
  491. return i32(r);
  492. }
  493. bitfield_extract_i64 :: proc(value: i64, offset, bits: uint) -> i64 {
  494. v := (u64(value) >> offset) & u64(1<<bits - 1);
  495. m := u64(1<<(bits-1));
  496. r := (v~m) - m;
  497. return i64(r);
  498. }
  499. bitfield_extract_i128 :: proc(value: i128, offset, bits: uint) -> i128 {
  500. v := (u128(value) >> offset) & u128(1<<bits - 1);
  501. m := u128(1<<(bits-1));
  502. r := (v~m) - m;
  503. return i128(r);
  504. }
  505. bitfield_extract_int :: proc(value: int, offset, bits: uint) -> int {
  506. v := (uint(value) >> offset) & uint(1<<bits - 1);
  507. m := uint(1<<(bits-1));
  508. r := (v~m) - m;
  509. return int(r);
  510. }
  511. bitfield_extract :: proc{
  512. bitfield_extract_u8,
  513. bitfield_extract_u16,
  514. bitfield_extract_u32,
  515. bitfield_extract_u64,
  516. bitfield_extract_u128,
  517. bitfield_extract_uint,
  518. bitfield_extract_i8,
  519. bitfield_extract_i16,
  520. bitfield_extract_i32,
  521. bitfield_extract_i64,
  522. bitfield_extract_i128,
  523. bitfield_extract_int,
  524. };
  525. bitfield_insert_u8 :: proc(base, insert: u8, offset, bits: uint) -> u8 {
  526. mask := u8(1<<bits - 1);
  527. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  528. }
  529. bitfield_insert_u16 :: proc(base, insert: u16, offset, bits: uint) -> u16 {
  530. mask := u16(1<<bits - 1);
  531. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  532. }
  533. bitfield_insert_u32 :: proc(base, insert: u32, offset, bits: uint) -> u32 {
  534. mask := u32(1<<bits - 1);
  535. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  536. }
  537. bitfield_insert_u64 :: proc(base, insert: u64, offset, bits: uint) -> u64 {
  538. mask := u64(1<<bits - 1);
  539. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  540. }
  541. bitfield_insert_u128 :: proc(base, insert: u128, offset, bits: uint) -> u128 {
  542. mask := u128(1<<bits - 1);
  543. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  544. }
  545. bitfield_insert_uint :: proc(base, insert: uint, offset, bits: uint) -> uint {
  546. mask := uint(1<<bits - 1);
  547. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  548. }
  549. bitfield_insert_i8 :: proc(base, insert: i8, offset, bits: uint) -> i8 {
  550. mask := i8(1<<bits - 1);
  551. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  552. }
  553. bitfield_insert_i16 :: proc(base, insert: i16, offset, bits: uint) -> i16 {
  554. mask := i16(1<<bits - 1);
  555. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  556. }
  557. bitfield_insert_i32 :: proc(base, insert: i32, offset, bits: uint) -> i32 {
  558. mask := i32(1<<bits - 1);
  559. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  560. }
  561. bitfield_insert_i64 :: proc(base, insert: i64, offset, bits: uint) -> i64 {
  562. mask := i64(1<<bits - 1);
  563. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  564. }
  565. bitfield_insert_i128 :: proc(base, insert: i128, offset, bits: uint) -> i128 {
  566. mask := i128(1<<bits - 1);
  567. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  568. }
  569. bitfield_insert_int :: proc(base, insert: int, offset, bits: uint) -> int {
  570. mask := int(1<<bits - 1);
  571. return (base &~ (mask<<offset)) | ((insert&mask) << offset);
  572. }
  573. bitfield_insert :: proc{
  574. bitfield_insert_u8,
  575. bitfield_insert_u16,
  576. bitfield_insert_u32,
  577. bitfield_insert_u64,
  578. bitfield_insert_u128,
  579. bitfield_insert_uint,
  580. bitfield_insert_i8,
  581. bitfield_insert_i16,
  582. bitfield_insert_i32,
  583. bitfield_insert_i64,
  584. bitfield_insert_i128,
  585. bitfield_insert_int,
  586. };