bits.odin 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. U8_MIN :: u8(0);
  2. U16_MIN :: u16(0);
  3. U32_MIN :: u32(0);
  4. U64_MIN :: u64(0);
  5. U128_MIN :: u128(0);
  6. U8_MAX :: ~u8(0);
  7. U16_MAX :: ~u16(0);
  8. U32_MAX :: ~u32(0);
  9. U64_MAX :: ~u64(0);
  10. U128_MAX :: ~u128(0);
  11. I8_MIN :: i8( ~u8(0) >> 1);
  12. I16_MIN :: i16( ~u16(0) >> 1);
  13. I32_MIN :: i32( ~u32(0) >> 1);
  14. I64_MIN :: i64( ~u64(0) >> 1);
  15. I128_MIN :: i128(~u128(0) >> 1);
  16. I8_MAX :: -I8_MIN - 1;
  17. I16_MAX :: -I16_MIN - 1;
  18. I32_MAX :: -I32_MIN - 1;
  19. I64_MAX :: -I64_MIN - 1;
  20. I128_MAX :: -I128_MIN - 1;
  21. foreign __llvm_core {
  22. @(link_name="llvm.ctpop.i8") __llvm_ctpop :: proc(u8) -> u8 ---;
  23. @(link_name="llvm.ctpop.i8") __llvm_ctpop :: proc(i8) -> i8 ---;
  24. @(link_name="llvm.ctpop.i16") __llvm_ctpop :: proc(u16) -> u16 ---;
  25. @(link_name="llvm.ctpop.i16") __llvm_ctpop :: proc(i16) -> i16 ---;
  26. @(link_name="llvm.ctpop.i32") __llvm_ctpop :: proc(u32) -> u32 ---;
  27. @(link_name="llvm.ctpop.i32") __llvm_ctpop :: proc(i32) -> i32 ---;
  28. @(link_name="llvm.ctpop.i64") __llvm_ctpop :: proc(u64) -> u64 ---;
  29. @(link_name="llvm.ctpop.i64") __llvm_ctpop :: proc(i64) -> i64 ---;
  30. @(link_name="llvm.ctpop.i128") __llvm_ctpop :: proc(u128) -> u128 ---;
  31. @(link_name="llvm.ctpop.i128") __llvm_ctpop :: proc(i128) -> i128 ---;
  32. @(link_name="llvm.ctlz.i8") __llvm_ctlz :: proc(u8, bool) -> u8 ---;
  33. @(link_name="llvm.ctlz.i8") __llvm_ctlz :: proc(i8, bool) -> i8 ---;
  34. @(link_name="llvm.ctlz.i16") __llvm_ctlz :: proc(u16, bool) -> u16 ---;
  35. @(link_name="llvm.ctlz.i16") __llvm_ctlz :: proc(i16, bool) -> i16 ---;
  36. @(link_name="llvm.ctlz.i32") __llvm_ctlz :: proc(u32, bool) -> u32 ---;
  37. @(link_name="llvm.ctlz.i32") __llvm_ctlz :: proc(i32, bool) -> i32 ---;
  38. @(link_name="llvm.ctlz.i64") __llvm_ctlz :: proc(u64, bool) -> u64 ---;
  39. @(link_name="llvm.ctlz.i64") __llvm_ctlz :: proc(i64, bool) -> i64 ---;
  40. @(link_name="llvm.ctlz.i128") __llvm_ctlz :: proc(u128, bool) -> u128 ---;
  41. @(link_name="llvm.ctlz.i128") __llvm_ctlz :: proc(i128, bool) -> i128 ---;
  42. @(link_name="llvm.cttz.i8") __llvm_cttz :: proc(u8, bool) -> u8 ---;
  43. @(link_name="llvm.cttz.i8") __llvm_cttz :: proc(i8, bool) -> i8 ---;
  44. @(link_name="llvm.cttz.i16") __llvm_cttz :: proc(u16, bool) -> u16 ---;
  45. @(link_name="llvm.cttz.i16") __llvm_cttz :: proc(i16, bool) -> i16 ---;
  46. @(link_name="llvm.cttz.i32") __llvm_cttz :: proc(u32, bool) -> u32 ---;
  47. @(link_name="llvm.cttz.i32") __llvm_cttz :: proc(i32, bool) -> i32 ---;
  48. @(link_name="llvm.cttz.i64") __llvm_cttz :: proc(u64, bool) -> u64 ---;
  49. @(link_name="llvm.cttz.i64") __llvm_cttz :: proc(i64, bool) -> i64 ---;
  50. @(link_name="llvm.cttz.i128") __llvm_cttz :: proc(u128, bool) -> u128 ---;
  51. @(link_name="llvm.cttz.i128") __llvm_cttz :: proc(i128, bool) -> i128 ---;
  52. @(link_name="llvm.bitreverse.i8") __llvm_bitreverse :: proc(u8) -> u8 ---;
  53. @(link_name="llvm.bitreverse.i8") __llvm_bitreverse :: proc(i8) -> i8 ---;
  54. @(link_name="llvm.bitreverse.i16") __llvm_bitreverse :: proc(u16) -> u16 ---;
  55. @(link_name="llvm.bitreverse.i16") __llvm_bitreverse :: proc(i16) -> i16 ---;
  56. @(link_name="llvm.bitreverse.i32") __llvm_bitreverse :: proc(u32) -> u32 ---;
  57. @(link_name="llvm.bitreverse.i32") __llvm_bitreverse :: proc(i32) -> i32 ---;
  58. @(link_name="llvm.bitreverse.i64") __llvm_bitreverse :: proc(u64) -> u64 ---;
  59. @(link_name="llvm.bitreverse.i64") __llvm_bitreverse :: proc(i64) -> i64 ---;
  60. @(link_name="llvm.bitreverse.i128") __llvm_bitreverse :: proc(u128) -> u128 ---;
  61. @(link_name="llvm.bitreverse.i128") __llvm_bitreverse :: proc(i128) -> i128 ---;
  62. @(link_name="llvm.bswap.i16") byte_swap :: proc(u16) -> u16 ---;
  63. @(link_name="llvm.bswap.i16") byte_swap :: proc(i16) -> i16 ---;
  64. @(link_name="llvm.bswap.i32") byte_swap :: proc(u32) -> u32 ---;
  65. @(link_name="llvm.bswap.i32") byte_swap :: proc(i32) -> i32 ---;
  66. @(link_name="llvm.bswap.i64") byte_swap :: proc(u64) -> u64 ---;
  67. @(link_name="llvm.bswap.i64") byte_swap :: proc(i64) -> i64 ---;
  68. @(link_name="llvm.bswap.i128") byte_swap :: proc(u128) -> u128 ---;
  69. @(link_name="llvm.bswap.i128") byte_swap :: proc(i128) -> i128 ---;
  70. }
  71. byte_swap :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(byte_swap(u32(i))); } else { return uint(byte_swap(u64(i))); } }
  72. byte_swap :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(byte_swap(i32(i))); } else { return int(byte_swap(i64(i))); } }
  73. count_ones :: proc(i: u8) -> u8 { return __llvm_ctpop(i); }
  74. count_ones :: proc(i: i8) -> i8 { return __llvm_ctpop(i); }
  75. count_ones :: proc(i: u16) -> u16 { return __llvm_ctpop(i); }
  76. count_ones :: proc(i: i16) -> i16 { return __llvm_ctpop(i); }
  77. count_ones :: proc(i: u32) -> u32 { return __llvm_ctpop(i); }
  78. count_ones :: proc(i: i32) -> i32 { return __llvm_ctpop(i); }
  79. count_ones :: proc(i: u64) -> u64 { return __llvm_ctpop(i); }
  80. count_ones :: proc(i: i64) -> i64 { return __llvm_ctpop(i); }
  81. count_ones :: proc(i: u128) -> u128 { return __llvm_ctpop(i); }
  82. count_ones :: proc(i: i128) -> i128 { return __llvm_ctpop(i); }
  83. count_ones :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(count_ones(u32(i))); } else { return uint(count_ones(u64(i))); } }
  84. count_ones :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(count_ones(i32(i))); } else { return int(count_ones(i64(i))); } }
  85. count_zeros :: proc(i: u8) -> u8 { return 8 - count_ones(i); }
  86. count_zeros :: proc(i: i8) -> i8 { return 8 - count_ones(i); }
  87. count_zeros :: proc(i: u16) -> u16 { return 16 - count_ones(i); }
  88. count_zeros :: proc(i: i16) -> i16 { return 16 - count_ones(i); }
  89. count_zeros :: proc(i: u32) -> u32 { return 32 - count_ones(i); }
  90. count_zeros :: proc(i: i32) -> i32 { return 32 - count_ones(i); }
  91. count_zeros :: proc(i: u64) -> u64 { return 64 - count_ones(i); }
  92. count_zeros :: proc(i: i64) -> i64 { return 64 - count_ones(i); }
  93. count_zeros :: proc(i: u128) -> u128 { return 128 - count_ones(i); }
  94. count_zeros :: proc(i: i128) -> i128 { return 128 - count_ones(i); }
  95. count_zeros :: proc(i: uint) -> uint { return 8*size_of(uint) - count_ones(i); }
  96. count_zeros :: proc(i: int) -> int { return 8*size_of(int) - count_ones(i); }
  97. rotate_left :: proc(i: u8, s: uint) -> u8 { return (i << s)|(i >> (8*size_of(u8) - s)); }
  98. rotate_left :: proc(i: i8, s: uint) -> i8 { return (i << s)|(i >> (8*size_of(i8) - s)); }
  99. rotate_left :: proc(i: u16, s: uint) -> u16 { return (i << s)|(i >> (8*size_of(u16) - s)); }
  100. rotate_left :: proc(i: i16, s: uint) -> i16 { return (i << s)|(i >> (8*size_of(i16) - s)); }
  101. rotate_left :: proc(i: u32, s: uint) -> u32 { return (i << s)|(i >> (8*size_of(u32) - s)); }
  102. rotate_left :: proc(i: i32, s: uint) -> i32 { return (i << s)|(i >> (8*size_of(i32) - s)); }
  103. rotate_left :: proc(i: u64, s: uint) -> u64 { return (i << s)|(i >> (8*size_of(u64) - s)); }
  104. rotate_left :: proc(i: i64, s: uint) -> i64 { return (i << s)|(i >> (8*size_of(i64) - s)); }
  105. rotate_left :: proc(i: u128, s: uint) -> u128 { return (i << s)|(i >> (8*size_of(u128) - s)); }
  106. rotate_left :: proc(i: i128, s: uint) -> i128 { return (i << s)|(i >> (8*size_of(i128) - s)); }
  107. rotate_left :: proc(i: uint, s: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(rotate_left(u32(i), s)); } else { return uint(rotate_left(u64(i), s)); } }
  108. rotate_left :: proc(i: int, s: uint) -> int { when size_of(int) == size_of(i32) { return int(rotate_left(i32(i), s)); } else { return int(rotate_left(i64(i), s)); } }
  109. rotate_right :: proc(i: u8, s: uint) -> u8 { return (i >> s)|(i << (8*size_of(u8) - s)); }
  110. rotate_right :: proc(i: i8, s: uint) -> i8 { return (i >> s)|(i << (8*size_of(i8) - s)); }
  111. rotate_right :: proc(i: u16, s: uint) -> u16 { return (i >> s)|(i << (8*size_of(u16) - s)); }
  112. rotate_right :: proc(i: i16, s: uint) -> i16 { return (i >> s)|(i << (8*size_of(i16) - s)); }
  113. rotate_right :: proc(i: u32, s: uint) -> u32 { return (i >> s)|(i << (8*size_of(u32) - s)); }
  114. rotate_right :: proc(i: i32, s: uint) -> i32 { return (i >> s)|(i << (8*size_of(i32) - s)); }
  115. rotate_right :: proc(i: u64, s: uint) -> u64 { return (i >> s)|(i << (8*size_of(u64) - s)); }
  116. rotate_right :: proc(i: i64, s: uint) -> i64 { return (i >> s)|(i << (8*size_of(i64) - s)); }
  117. rotate_right :: proc(i: u128, s: uint) -> u128 { return (i >> s)|(i << (8*size_of(u128) - s)); }
  118. rotate_right :: proc(i: i128, s: uint) -> i128 { return (i >> s)|(i << (8*size_of(i128) - s)); }
  119. rotate_right :: proc(i: uint, s: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(rotate_right(u32(i), s)); } else { return uint(rotate_right(u64(i), s)); } }
  120. rotate_right :: proc(i: int, s: uint) -> int { when size_of(int) == size_of(i32) { return int(rotate_right(i32(i), s)); } else { return int(rotate_right(i64(i), s)); } }
  121. leading_zeros :: proc(i: u8) -> u8 { return __llvm_ctlz(i, false); }
  122. leading_zeros :: proc(i: i8) -> i8 { return __llvm_ctlz(i, false); }
  123. leading_zeros :: proc(i: u16) -> u16 { return __llvm_ctlz(i, false); }
  124. leading_zeros :: proc(i: i16) -> i16 { return __llvm_ctlz(i, false); }
  125. leading_zeros :: proc(i: u32) -> u32 { return __llvm_ctlz(i, false); }
  126. leading_zeros :: proc(i: i32) -> i32 { return __llvm_ctlz(i, false); }
  127. leading_zeros :: proc(i: u64) -> u64 { return __llvm_ctlz(i, false); }
  128. leading_zeros :: proc(i: i64) -> i64 { return __llvm_ctlz(i, false); }
  129. leading_zeros :: proc(i: u128) -> u128 { return __llvm_ctlz(i, false); }
  130. leading_zeros :: proc(i: i128) -> i128 { return __llvm_ctlz(i, false); }
  131. leading_zeros :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(leading_zeros(u32(i))); } else { return uint(leading_zeros(u64(i))); } }
  132. leading_zeros :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(leading_zeros(i32(i))); } else { return int(leading_zeros(i64(i))); } }
  133. trailing_zeros :: proc(i: u8) -> u8 { return __llvm_cttz(i, false); }
  134. trailing_zeros :: proc(i: i8) -> i8 { return __llvm_cttz(i, false); }
  135. trailing_zeros :: proc(i: u16) -> u16 { return __llvm_cttz(i, false); }
  136. trailing_zeros :: proc(i: i16) -> i16 { return __llvm_cttz(i, false); }
  137. trailing_zeros :: proc(i: u32) -> u32 { return __llvm_cttz(i, false); }
  138. trailing_zeros :: proc(i: i32) -> i32 { return __llvm_cttz(i, false); }
  139. trailing_zeros :: proc(i: u64) -> u64 { return __llvm_cttz(i, false); }
  140. trailing_zeros :: proc(i: i64) -> i64 { return __llvm_cttz(i, false); }
  141. trailing_zeros :: proc(i: u128) -> u128 { return __llvm_cttz(i, false); }
  142. trailing_zeros :: proc(i: i128) -> i128 { return __llvm_cttz(i, false); }
  143. trailing_zeros :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(trailing_zeros(u32(i))); } else { return uint(trailing_zeros(u64(i))); } }
  144. trailing_zeros :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(trailing_zeros(i32(i))); } else { return int(trailing_zeros(i64(i))); } }
  145. reverse_bits :: proc(i: u8) -> u8 { return __llvm_bitreverse(i); }
  146. reverse_bits :: proc(i: i8) -> i8 { return __llvm_bitreverse(i); }
  147. reverse_bits :: proc(i: u16) -> u16 { return __llvm_bitreverse(i); }
  148. reverse_bits :: proc(i: i16) -> i16 { return __llvm_bitreverse(i); }
  149. reverse_bits :: proc(i: u32) -> u32 { return __llvm_bitreverse(i); }
  150. reverse_bits :: proc(i: i32) -> i32 { return __llvm_bitreverse(i); }
  151. reverse_bits :: proc(i: u64) -> u64 { return __llvm_bitreverse(i); }
  152. reverse_bits :: proc(i: i64) -> i64 { return __llvm_bitreverse(i); }
  153. reverse_bits :: proc(i: u128) -> u128 { return __llvm_bitreverse(i); }
  154. reverse_bits :: proc(i: i128) -> i128 { return __llvm_bitreverse(i); }
  155. reverse_bits :: proc(i: uint) -> uint { when size_of(uint) == size_of(u32) { return uint(reverse_bits(u32(i))); } else { return uint(reverse_bits(u64(i))); } }
  156. reverse_bits :: proc(i: int) -> int { when size_of(int) == size_of(i32) { return int(reverse_bits(i32(i))); } else { return int(reverse_bits(i64(i))); } }
  157. from_be :: proc(i: u8) -> u8 { return i; }
  158. from_be :: proc(i: i8) -> i8 { return i; }
  159. from_be :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  160. from_be :: proc(i: i16) -> i16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  161. from_be :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  162. from_be :: proc(i: i32) -> i32 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  163. from_be :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  164. from_be :: proc(i: i64) -> i64 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  165. from_be :: proc(i: u128) -> u128 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  166. from_be :: proc(i: i128) -> i128 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  167. from_be :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  168. from_be :: proc(i: int) -> int { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  169. from_le :: proc(i: u8) -> u8 { return i; }
  170. from_le :: proc(i: i8) -> i8 { return i; }
  171. from_le :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  172. from_le :: proc(i: i16) -> i16 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  173. from_le :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  174. from_le :: proc(i: i32) -> i32 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  175. from_le :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  176. from_le :: proc(i: i64) -> i64 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  177. from_le :: proc(i: u128) -> u128 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  178. from_le :: proc(i: i128) -> i128 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  179. from_le :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  180. from_le :: proc(i: int) -> int { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  181. to_be :: proc(i: u8) -> u8 { return i; }
  182. to_be :: proc(i: i8) -> i8 { return i; }
  183. to_be :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  184. to_be :: proc(i: i16) -> i16 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  185. to_be :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  186. to_be :: proc(i: i32) -> i32 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  187. to_be :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  188. to_be :: proc(i: i64) -> i64 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  189. to_be :: proc(i: u128) -> u128 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  190. to_be :: proc(i: i128) -> i128 { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  191. to_be :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  192. to_be :: proc(i: int) -> int { when ODIN_ENDIAN == "big" { return i; } else { return byte_swap(i); } }
  193. to_le :: proc(i: u8) -> u8 { return i; }
  194. to_le :: proc(i: i8) -> i8 { return i; }
  195. to_le :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  196. to_le :: proc(i: i16) -> i16 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  197. to_le :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  198. to_le :: proc(i: i32) -> i32 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  199. to_le :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  200. to_le :: proc(i: i64) -> i64 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  201. to_le :: proc(i: u128) -> u128 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  202. to_le :: proc(i: i128) -> i128 { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  203. to_le :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  204. to_le :: proc(i: int) -> int { when ODIN_ENDIAN == "little" { return i; } else { return byte_swap(i); } }
  205. overflowing_add :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); }
  206. overflowing_add :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); }
  207. overflowing_add :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); }
  208. overflowing_add :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); }
  209. overflowing_add :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); }
  210. overflowing_add :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); }
  211. overflowing_add :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); }
  212. overflowing_add :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); }
  213. overflowing_add :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i128") op :: proc(u128, u128) -> (u128, bool) ---; return op(lhs, rhs); }
  214. overflowing_add :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i128") op :: proc(i128, i128) -> (i128, bool) ---; return op(lhs, rhs); }
  215. overflowing_add :: proc(lhs, rhs: uint) -> (uint, bool) {
  216. when size_of(uint) == size_of(u32) {
  217. x, ok := overflowing_add(u32(lhs), u32(rhs));
  218. return uint(x), ok;
  219. } else {
  220. x, ok := overflowing_add(u64(lhs), u64(rhs));
  221. return uint(x), ok;
  222. }
  223. }
  224. overflowing_add :: proc(lhs, rhs: int) -> (int, bool) {
  225. when size_of(int) == size_of(i32) {
  226. x, ok := overflowing_add(i32(lhs), i32(rhs));
  227. return int(x), ok;
  228. } else {
  229. x, ok := overflowing_add(i64(lhs), i64(rhs));
  230. return int(x), ok;
  231. }
  232. }
  233. overflowing_sub :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); }
  234. overflowing_sub :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); }
  235. overflowing_sub :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); }
  236. overflowing_sub :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); }
  237. overflowing_sub :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); }
  238. overflowing_sub :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); }
  239. overflowing_sub :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); }
  240. overflowing_sub :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); }
  241. overflowing_sub :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i128") op :: proc(u128, u128) -> (u128, bool) ---; return op(lhs, rhs); }
  242. overflowing_sub :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i128") op :: proc(i128, i128) -> (i128, bool) ---; return op(lhs, rhs); }
  243. overflowing_sub :: proc(lhs, rhs: uint) -> (uint, bool) {
  244. when size_of(uint) == size_of(u32) {
  245. x, ok := overflowing_sub(u32(lhs), u32(rhs));
  246. return uint(x), ok;
  247. } else {
  248. x, ok := overflowing_sub(u64(lhs), u64(rhs));
  249. return uint(x), ok;
  250. }
  251. }
  252. overflowing_sub :: proc(lhs, rhs: int) -> (int, bool) {
  253. when size_of(int) == size_of(i32) {
  254. x, ok := overflowing_sub(i32(lhs), i32(rhs));
  255. return int(x), ok;
  256. } else {
  257. x, ok := overflowing_sub(i64(lhs), i64(rhs));
  258. return int(x), ok;
  259. }
  260. }
  261. overflowing_mul :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); }
  262. overflowing_mul :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); }
  263. overflowing_mul :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); }
  264. overflowing_mul :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); }
  265. overflowing_mul :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); }
  266. overflowing_mul :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); }
  267. overflowing_mul :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); }
  268. overflowing_mul :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); }
  269. overflowing_mul :: proc(lhs, rhs: u128) -> (u128, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i128") op :: proc(u128, u128) -> (u128, bool) ---; return op(lhs, rhs); }
  270. overflowing_mul :: proc(lhs, rhs: i128) -> (i128, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i128") op :: proc(i128, i128) -> (i128, bool) ---; return op(lhs, rhs); }
  271. overflowing_mul :: proc(lhs, rhs: uint) -> (uint, bool) {
  272. when size_of(uint) == size_of(u32) {
  273. x, ok := overflowing_mul(u32(lhs), u32(rhs));
  274. return uint(x), ok;
  275. } else {
  276. x, ok := overflowing_mul(u64(lhs), u64(rhs));
  277. return uint(x), ok;
  278. }
  279. }
  280. overflowing_mul :: proc(lhs, rhs: int) -> (int, bool) {
  281. when size_of(int) == size_of(i32) {
  282. x, ok := overflowing_mul(i32(lhs), i32(rhs));
  283. return int(x), ok;
  284. } else {
  285. x, ok := overflowing_mul(i64(lhs), i64(rhs));
  286. return int(x), ok;
  287. }
  288. }
  289. is_power_of_two :: proc(i: u8) -> bool { return i > 0 && (i & (i-1)) == 0; }
  290. is_power_of_two :: proc(i: i8) -> bool { return i > 0 && (i & (i-1)) == 0; }
  291. is_power_of_two :: proc(i: u16) -> bool { return i > 0 && (i & (i-1)) == 0; }
  292. is_power_of_two :: proc(i: i16) -> bool { return i > 0 && (i & (i-1)) == 0; }
  293. is_power_of_two :: proc(i: u32) -> bool { return i > 0 && (i & (i-1)) == 0; }
  294. is_power_of_two :: proc(i: i32) -> bool { return i > 0 && (i & (i-1)) == 0; }
  295. is_power_of_two :: proc(i: u64) -> bool { return i > 0 && (i & (i-1)) == 0; }
  296. is_power_of_two :: proc(i: i64) -> bool { return i > 0 && (i & (i-1)) == 0; }
  297. is_power_of_two :: proc(i: u128) -> bool { return i > 0 && (i & (i-1)) == 0; }
  298. is_power_of_two :: proc(i: i128) -> bool { return i > 0 && (i & (i-1)) == 0; }
  299. is_power_of_two :: proc(i: uint) -> bool { return i > 0 && (i & (i-1)) == 0; }
  300. is_power_of_two :: proc(i: int) -> bool { return i > 0 && (i & (i-1)) == 0; }