internal.odin 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. package runtime
  2. import "base:intrinsics"
  3. @(private="file")
  4. IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32
  5. @(private)
  6. RUNTIME_LINKAGE :: "strong" when (
  7. (ODIN_USE_SEPARATE_MODULES ||
  8. ODIN_BUILD_MODE == .Dynamic ||
  9. !ODIN_NO_CRT) &&
  10. !IS_WASM) else "internal"
  11. RUNTIME_REQUIRE :: !ODIN_TILDE
  12. @(private)
  13. __float16 :: f16 when __ODIN_LLVM_F16_SUPPORTED else u16
  14. @(private)
  15. byte_slice :: #force_inline proc "contextless" (data: rawptr, len: int) -> []byte #no_bounds_check {
  16. return ([^]byte)(data)[:max(len, 0)]
  17. }
  18. is_power_of_two_int :: #force_inline proc(x: int) -> bool {
  19. if x <= 0 {
  20. return false
  21. }
  22. return (x & (x-1)) == 0
  23. }
  24. align_forward_int :: #force_inline proc(ptr, align: int) -> int {
  25. assert(is_power_of_two_int(align))
  26. p := ptr
  27. modulo := p & (align-1)
  28. if modulo != 0 {
  29. p += align - modulo
  30. }
  31. return p
  32. }
  33. is_power_of_two_uintptr :: #force_inline proc(x: uintptr) -> bool {
  34. if x <= 0 {
  35. return false
  36. }
  37. return (x & (x-1)) == 0
  38. }
  39. align_forward_uintptr :: #force_inline proc(ptr, align: uintptr) -> uintptr {
  40. assert(is_power_of_two_uintptr(align))
  41. p := ptr
  42. modulo := p & (align-1)
  43. if modulo != 0 {
  44. p += align - modulo
  45. }
  46. return p
  47. }
  48. mem_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr {
  49. if data == nil {
  50. return nil
  51. }
  52. if len <= 0 {
  53. return data
  54. }
  55. intrinsics.mem_zero(data, len)
  56. return data
  57. }
  58. mem_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
  59. if src != nil && dst != src && len > 0 {
  60. // NOTE(bill): This _must_ be implemented like C's memmove
  61. intrinsics.mem_copy(dst, src, len)
  62. }
  63. return dst
  64. }
  65. mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
  66. if src != nil && dst != src && len > 0 {
  67. // NOTE(bill): This _must_ be implemented like C's memcpy
  68. intrinsics.mem_copy_non_overlapping(dst, src, len)
  69. }
  70. return dst
  71. }
  72. DEFAULT_ALIGNMENT :: 2*align_of(rawptr)
  73. mem_alloc_bytes :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
  74. if size == 0 {
  75. return nil, nil
  76. }
  77. if allocator.procedure == nil {
  78. return nil, nil
  79. }
  80. return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
  81. }
  82. mem_alloc :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
  83. if size == 0 || allocator.procedure == nil {
  84. return nil, nil
  85. }
  86. return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
  87. }
  88. mem_alloc_non_zeroed :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
  89. if size == 0 || allocator.procedure == nil {
  90. return nil, nil
  91. }
  92. return allocator.procedure(allocator.data, .Alloc_Non_Zeroed, size, alignment, nil, 0, loc)
  93. }
  94. mem_free :: #force_inline proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
  95. if ptr == nil || allocator.procedure == nil {
  96. return nil
  97. }
  98. _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, 0, loc)
  99. return err
  100. }
  101. mem_free_with_size :: #force_inline proc(ptr: rawptr, byte_count: int, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
  102. if ptr == nil || allocator.procedure == nil {
  103. return nil
  104. }
  105. _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, byte_count, loc)
  106. return err
  107. }
  108. mem_free_bytes :: #force_inline proc(bytes: []byte, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
  109. if bytes == nil || allocator.procedure == nil {
  110. return nil
  111. }
  112. _, err := allocator.procedure(allocator.data, .Free, 0, 0, raw_data(bytes), len(bytes), loc)
  113. return err
  114. }
  115. mem_free_all :: #force_inline proc(allocator := context.allocator, loc := #caller_location) -> (err: Allocator_Error) {
  116. if allocator.procedure != nil {
  117. _, err = allocator.procedure(allocator.data, .Free_All, 0, 0, nil, 0, loc)
  118. }
  119. return
  120. }
  121. _mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, should_zero: bool, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
  122. if allocator.procedure == nil {
  123. return nil, nil
  124. }
  125. if new_size == 0 {
  126. if ptr != nil {
  127. _, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc)
  128. return
  129. }
  130. return
  131. } else if ptr == nil {
  132. if should_zero {
  133. return allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
  134. } else {
  135. return allocator.procedure(allocator.data, .Alloc_Non_Zeroed, new_size, alignment, nil, 0, loc)
  136. }
  137. } else if old_size == new_size && uintptr(ptr) % uintptr(alignment) == 0 {
  138. data = ([^]byte)(ptr)[:old_size]
  139. return
  140. }
  141. if should_zero {
  142. data, err = allocator.procedure(allocator.data, .Resize, new_size, alignment, ptr, old_size, loc)
  143. } else {
  144. data, err = allocator.procedure(allocator.data, .Resize_Non_Zeroed, new_size, alignment, ptr, old_size, loc)
  145. }
  146. if err == .Mode_Not_Implemented {
  147. if should_zero {
  148. data, err = allocator.procedure(allocator.data, .Alloc, new_size, alignment, nil, 0, loc)
  149. } else {
  150. data, err = allocator.procedure(allocator.data, .Alloc_Non_Zeroed, new_size, alignment, nil, 0, loc)
  151. }
  152. if err != nil {
  153. return
  154. }
  155. copy(data, ([^]byte)(ptr)[:old_size])
  156. _, err = allocator.procedure(allocator.data, .Free, 0, 0, ptr, old_size, loc)
  157. }
  158. return
  159. }
  160. mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
  161. return _mem_resize(ptr, old_size, new_size, alignment, allocator, true, loc)
  162. }
  163. non_zero_mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
  164. return _mem_resize(ptr, old_size, new_size, alignment, allocator, false, loc)
  165. }
  166. memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool {
  167. switch {
  168. case n == 0: return true
  169. case x == y: return true
  170. }
  171. a, b := ([^]byte)(x), ([^]byte)(y)
  172. length := uint(n)
  173. for i := uint(0); i < length; i += 1 {
  174. if a[i] != b[i] {
  175. return false
  176. }
  177. }
  178. return true
  179. /*
  180. when size_of(uint) == 8 {
  181. if word_length := length >> 3; word_length != 0 {
  182. for _ in 0..<word_length {
  183. if intrinsics.unaligned_load((^u64)(a)) != intrinsics.unaligned_load((^u64)(b)) {
  184. return false
  185. }
  186. a = a[size_of(u64):]
  187. b = b[size_of(u64):]
  188. }
  189. }
  190. if length & 4 != 0 {
  191. if intrinsics.unaligned_load((^u32)(a)) != intrinsics.unaligned_load((^u32)(b)) {
  192. return false
  193. }
  194. a = a[size_of(u32):]
  195. b = b[size_of(u32):]
  196. }
  197. if length & 2 != 0 {
  198. if intrinsics.unaligned_load((^u16)(a)) != intrinsics.unaligned_load((^u16)(b)) {
  199. return false
  200. }
  201. a = a[size_of(u16):]
  202. b = b[size_of(u16):]
  203. }
  204. if length & 1 != 0 && a[0] != b[0] {
  205. return false
  206. }
  207. return true
  208. } else {
  209. if word_length := length >> 2; word_length != 0 {
  210. for _ in 0..<word_length {
  211. if intrinsics.unaligned_load((^u32)(a)) != intrinsics.unaligned_load((^u32)(b)) {
  212. return false
  213. }
  214. a = a[size_of(u32):]
  215. b = b[size_of(u32):]
  216. }
  217. }
  218. length &= 3
  219. if length != 0 {
  220. for i in 0..<length {
  221. if a[i] != b[i] {
  222. return false
  223. }
  224. }
  225. }
  226. return true
  227. }
  228. */
  229. }
  230. memory_compare :: proc "contextless" (a, b: rawptr, n: int) -> int #no_bounds_check {
  231. switch {
  232. case a == b: return 0
  233. case a == nil: return -1
  234. case b == nil: return +1
  235. }
  236. x := uintptr(a)
  237. y := uintptr(b)
  238. n := uintptr(n)
  239. SU :: size_of(uintptr)
  240. fast := n/SU + 1
  241. offset := (fast-1)*SU
  242. curr_block := uintptr(0)
  243. if n < SU {
  244. fast = 0
  245. }
  246. for /**/; curr_block < fast; curr_block += 1 {
  247. va := (^uintptr)(x + curr_block * size_of(uintptr))^
  248. vb := (^uintptr)(y + curr_block * size_of(uintptr))^
  249. if va ~ vb != 0 {
  250. for pos := curr_block*SU; pos < n; pos += 1 {
  251. a := (^byte)(x+pos)^
  252. b := (^byte)(y+pos)^
  253. if a ~ b != 0 {
  254. return -1 if (int(a) - int(b)) < 0 else +1
  255. }
  256. }
  257. }
  258. }
  259. for /**/; offset < n; offset += 1 {
  260. a := (^byte)(x+offset)^
  261. b := (^byte)(y+offset)^
  262. if a ~ b != 0 {
  263. return -1 if (int(a) - int(b)) < 0 else +1
  264. }
  265. }
  266. return 0
  267. }
  268. memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_check {
  269. x := uintptr(a)
  270. n := uintptr(n)
  271. SU :: size_of(uintptr)
  272. fast := n/SU + 1
  273. offset := (fast-1)*SU
  274. curr_block := uintptr(0)
  275. if n < SU {
  276. fast = 0
  277. }
  278. for /**/; curr_block < fast; curr_block += 1 {
  279. va := (^uintptr)(x + curr_block * size_of(uintptr))^
  280. if va ~ 0 != 0 {
  281. for pos := curr_block*SU; pos < n; pos += 1 {
  282. a := (^byte)(x+pos)^
  283. if a ~ 0 != 0 {
  284. return -1 if int(a) < 0 else +1
  285. }
  286. }
  287. }
  288. }
  289. for /**/; offset < n; offset += 1 {
  290. a := (^byte)(x+offset)^
  291. if a ~ 0 != 0 {
  292. return -1 if int(a) < 0 else +1
  293. }
  294. }
  295. return 0
  296. }
  297. string_eq :: proc "contextless" (lhs, rhs: string) -> bool {
  298. x := transmute(Raw_String)lhs
  299. y := transmute(Raw_String)rhs
  300. if x.len != y.len {
  301. return false
  302. }
  303. return #force_inline memory_equal(x.data, y.data, x.len)
  304. }
  305. string_cmp :: proc "contextless" (a, b: string) -> int {
  306. x := transmute(Raw_String)a
  307. y := transmute(Raw_String)b
  308. ret := memory_compare(x.data, y.data, min(x.len, y.len))
  309. if ret == 0 && x.len != y.len {
  310. return -1 if x.len < y.len else +1
  311. }
  312. return ret
  313. }
  314. string_ne :: #force_inline proc "contextless" (a, b: string) -> bool { return !string_eq(a, b) }
  315. string_lt :: #force_inline proc "contextless" (a, b: string) -> bool { return string_cmp(a, b) < 0 }
  316. string_gt :: #force_inline proc "contextless" (a, b: string) -> bool { return string_cmp(a, b) > 0 }
  317. string_le :: #force_inline proc "contextless" (a, b: string) -> bool { return string_cmp(a, b) <= 0 }
  318. string_ge :: #force_inline proc "contextless" (a, b: string) -> bool { return string_cmp(a, b) >= 0 }
  319. cstring_len :: proc "contextless" (s: cstring) -> int {
  320. p0 := uintptr((^byte)(s))
  321. p := p0
  322. for p != 0 && (^byte)(p)^ != 0 {
  323. p += 1
  324. }
  325. return int(p - p0)
  326. }
  327. cstring_to_string :: proc "contextless" (s: cstring) -> string {
  328. if s == nil {
  329. return ""
  330. }
  331. ptr := (^byte)(s)
  332. n := cstring_len(s)
  333. return transmute(string)Raw_String{ptr, n}
  334. }
  335. cstring_eq :: proc "contextless" (lhs, rhs: cstring) -> bool {
  336. x := ([^]byte)(lhs)
  337. y := ([^]byte)(rhs)
  338. if x == y {
  339. return true
  340. }
  341. if (x == nil) ~ (y == nil) {
  342. return false
  343. }
  344. xn := cstring_len(lhs)
  345. yn := cstring_len(rhs)
  346. if xn != yn {
  347. return false
  348. }
  349. return #force_inline memory_equal(x, y, xn)
  350. }
  351. cstring_cmp :: proc "contextless" (lhs, rhs: cstring) -> int {
  352. x := ([^]byte)(lhs)
  353. y := ([^]byte)(rhs)
  354. if x == y {
  355. return 0
  356. }
  357. if (x == nil) ~ (y == nil) {
  358. return -1 if x == nil else +1
  359. }
  360. xn := cstring_len(lhs)
  361. yn := cstring_len(rhs)
  362. ret := memory_compare(x, y, min(xn, yn))
  363. if ret == 0 && xn != yn {
  364. return -1 if xn < yn else +1
  365. }
  366. return ret
  367. }
  368. cstring_ne :: #force_inline proc "contextless" (a, b: cstring) -> bool { return !cstring_eq(a, b) }
  369. cstring_lt :: #force_inline proc "contextless" (a, b: cstring) -> bool { return cstring_cmp(a, b) < 0 }
  370. cstring_gt :: #force_inline proc "contextless" (a, b: cstring) -> bool { return cstring_cmp(a, b) > 0 }
  371. cstring_le :: #force_inline proc "contextless" (a, b: cstring) -> bool { return cstring_cmp(a, b) <= 0 }
  372. cstring_ge :: #force_inline proc "contextless" (a, b: cstring) -> bool { return cstring_cmp(a, b) >= 0 }
  373. complex32_eq :: #force_inline proc "contextless" (a, b: complex32) -> bool { return real(a) == real(b) && imag(a) == imag(b) }
  374. complex32_ne :: #force_inline proc "contextless" (a, b: complex32) -> bool { return real(a) != real(b) || imag(a) != imag(b) }
  375. complex64_eq :: #force_inline proc "contextless" (a, b: complex64) -> bool { return real(a) == real(b) && imag(a) == imag(b) }
  376. complex64_ne :: #force_inline proc "contextless" (a, b: complex64) -> bool { return real(a) != real(b) || imag(a) != imag(b) }
  377. complex128_eq :: #force_inline proc "contextless" (a, b: complex128) -> bool { return real(a) == real(b) && imag(a) == imag(b) }
  378. complex128_ne :: #force_inline proc "contextless" (a, b: complex128) -> bool { return real(a) != real(b) || imag(a) != imag(b) }
  379. quaternion64_eq :: #force_inline proc "contextless" (a, b: quaternion64) -> bool { return real(a) == real(b) && imag(a) == imag(b) && jmag(a) == jmag(b) && kmag(a) == kmag(b) }
  380. quaternion64_ne :: #force_inline proc "contextless" (a, b: quaternion64) -> bool { return real(a) != real(b) || imag(a) != imag(b) || jmag(a) != jmag(b) || kmag(a) != kmag(b) }
  381. quaternion128_eq :: #force_inline proc "contextless" (a, b: quaternion128) -> bool { return real(a) == real(b) && imag(a) == imag(b) && jmag(a) == jmag(b) && kmag(a) == kmag(b) }
  382. quaternion128_ne :: #force_inline proc "contextless" (a, b: quaternion128) -> bool { return real(a) != real(b) || imag(a) != imag(b) || jmag(a) != jmag(b) || kmag(a) != kmag(b) }
  383. quaternion256_eq :: #force_inline proc "contextless" (a, b: quaternion256) -> bool { return real(a) == real(b) && imag(a) == imag(b) && jmag(a) == jmag(b) && kmag(a) == kmag(b) }
  384. quaternion256_ne :: #force_inline proc "contextless" (a, b: quaternion256) -> bool { return real(a) != real(b) || imag(a) != imag(b) || jmag(a) != jmag(b) || kmag(a) != kmag(b) }
  385. string_decode_rune :: #force_inline proc "contextless" (s: string) -> (rune, int) {
  386. // NOTE(bill): Duplicated here to remove dependency on package unicode/utf8
  387. @static accept_sizes := [256]u8{
  388. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f
  389. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f
  390. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f
  391. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x30-0x3f
  392. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x40-0x4f
  393. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x50-0x5f
  394. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x60-0x6f
  395. 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x70-0x7f
  396. 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0x80-0x8f
  397. 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0x90-0x9f
  398. 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xa0-0xaf
  399. 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xb0-0xbf
  400. 0xf1, 0xf1, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xc0-0xcf
  401. 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xd0-0xdf
  402. 0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x23, 0x03, 0x03, // 0xe0-0xef
  403. 0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
  404. }
  405. Accept_Range :: struct {lo, hi: u8}
  406. @static accept_ranges := [5]Accept_Range{
  407. {0x80, 0xbf},
  408. {0xa0, 0xbf},
  409. {0x80, 0x9f},
  410. {0x90, 0xbf},
  411. {0x80, 0x8f},
  412. }
  413. MASKX :: 0b0011_1111
  414. MASK2 :: 0b0001_1111
  415. MASK3 :: 0b0000_1111
  416. MASK4 :: 0b0000_0111
  417. LOCB :: 0b1000_0000
  418. HICB :: 0b1011_1111
  419. RUNE_ERROR :: '\ufffd'
  420. n := len(s)
  421. if n < 1 {
  422. return RUNE_ERROR, 0
  423. }
  424. s0 := s[0]
  425. x := accept_sizes[s0]
  426. if x >= 0xF0 {
  427. mask := rune(x) << 31 >> 31 // NOTE(bill): Create 0x0000 or 0xffff.
  428. return rune(s[0])&~mask | RUNE_ERROR&mask, 1
  429. }
  430. sz := x & 7
  431. accept := accept_ranges[x>>4]
  432. if n < int(sz) {
  433. return RUNE_ERROR, 1
  434. }
  435. b1 := s[1]
  436. if b1 < accept.lo || accept.hi < b1 {
  437. return RUNE_ERROR, 1
  438. }
  439. if sz == 2 {
  440. return rune(s0&MASK2)<<6 | rune(b1&MASKX), 2
  441. }
  442. b2 := s[2]
  443. if b2 < LOCB || HICB < b2 {
  444. return RUNE_ERROR, 1
  445. }
  446. if sz == 3 {
  447. return rune(s0&MASK3)<<12 | rune(b1&MASKX)<<6 | rune(b2&MASKX), 3
  448. }
  449. b3 := s[3]
  450. if b3 < LOCB || HICB < b3 {
  451. return RUNE_ERROR, 1
  452. }
  453. return rune(s0&MASK4)<<18 | rune(b1&MASKX)<<12 | rune(b2&MASKX)<<6 | rune(b3&MASKX), 4
  454. }
  455. string_decode_last_rune :: proc "contextless" (s: string) -> (rune, int) {
  456. RUNE_ERROR :: '\ufffd'
  457. RUNE_SELF :: 0x80
  458. UTF_MAX :: 4
  459. r: rune
  460. size: int
  461. start, end, limit: int
  462. end = len(s)
  463. if end == 0 {
  464. return RUNE_ERROR, 0
  465. }
  466. start = end-1
  467. r = rune(s[start])
  468. if r < RUNE_SELF {
  469. return r, 1
  470. }
  471. limit = max(end - UTF_MAX, 0)
  472. for start-=1; start >= limit; start-=1 {
  473. if (s[start] & 0xc0) != RUNE_SELF {
  474. break
  475. }
  476. }
  477. start = max(start, 0)
  478. r, size = string_decode_rune(s[start:end])
  479. if start+size != end {
  480. return RUNE_ERROR, 1
  481. }
  482. return r, size
  483. }
  484. abs_complex32 :: #force_inline proc "contextless" (x: complex32) -> f16 {
  485. p, q := abs(real(x)), abs(imag(x))
  486. if p < q {
  487. p, q = q, p
  488. }
  489. if p == 0 {
  490. return 0
  491. }
  492. q = q / p
  493. return p * f16(intrinsics.sqrt(f32(1 + q*q)))
  494. }
  495. abs_complex64 :: #force_inline proc "contextless" (x: complex64) -> f32 {
  496. p, q := abs(real(x)), abs(imag(x))
  497. if p < q {
  498. p, q = q, p
  499. }
  500. if p == 0 {
  501. return 0
  502. }
  503. q = q / p
  504. return p * intrinsics.sqrt(1 + q*q)
  505. }
  506. abs_complex128 :: #force_inline proc "contextless" (x: complex128) -> f64 {
  507. p, q := abs(real(x)), abs(imag(x))
  508. if p < q {
  509. p, q = q, p
  510. }
  511. if p == 0 {
  512. return 0
  513. }
  514. q = q / p
  515. return p * intrinsics.sqrt(1 + q*q)
  516. }
  517. abs_quaternion64 :: #force_inline proc "contextless" (x: quaternion64) -> f16 {
  518. r, i, j, k := real(x), imag(x), jmag(x), kmag(x)
  519. return f16(intrinsics.sqrt(f32(r*r + i*i + j*j + k*k)))
  520. }
  521. abs_quaternion128 :: #force_inline proc "contextless" (x: quaternion128) -> f32 {
  522. r, i, j, k := real(x), imag(x), jmag(x), kmag(x)
  523. return intrinsics.sqrt(r*r + i*i + j*j + k*k)
  524. }
  525. abs_quaternion256 :: #force_inline proc "contextless" (x: quaternion256) -> f64 {
  526. r, i, j, k := real(x), imag(x), jmag(x), kmag(x)
  527. return intrinsics.sqrt(r*r + i*i + j*j + k*k)
  528. }
  529. quo_complex32 :: proc "contextless" (n, m: complex32) -> complex32 {
  530. e, f: f16
  531. if abs(real(m)) >= abs(imag(m)) {
  532. ratio := imag(m) / real(m)
  533. denom := real(m) + ratio*imag(m)
  534. e = (real(n) + imag(n)*ratio) / denom
  535. f = (imag(n) - real(n)*ratio) / denom
  536. } else {
  537. ratio := real(m) / imag(m)
  538. denom := imag(m) + ratio*real(m)
  539. e = (real(n)*ratio + imag(n)) / denom
  540. f = (imag(n)*ratio - real(n)) / denom
  541. }
  542. return complex(e, f)
  543. }
  544. quo_complex64 :: proc "contextless" (n, m: complex64) -> complex64 {
  545. e, f: f32
  546. if abs(real(m)) >= abs(imag(m)) {
  547. ratio := imag(m) / real(m)
  548. denom := real(m) + ratio*imag(m)
  549. e = (real(n) + imag(n)*ratio) / denom
  550. f = (imag(n) - real(n)*ratio) / denom
  551. } else {
  552. ratio := real(m) / imag(m)
  553. denom := imag(m) + ratio*real(m)
  554. e = (real(n)*ratio + imag(n)) / denom
  555. f = (imag(n)*ratio - real(n)) / denom
  556. }
  557. return complex(e, f)
  558. }
  559. quo_complex128 :: proc "contextless" (n, m: complex128) -> complex128 {
  560. e, f: f64
  561. if abs(real(m)) >= abs(imag(m)) {
  562. ratio := imag(m) / real(m)
  563. denom := real(m) + ratio*imag(m)
  564. e = (real(n) + imag(n)*ratio) / denom
  565. f = (imag(n) - real(n)*ratio) / denom
  566. } else {
  567. ratio := real(m) / imag(m)
  568. denom := imag(m) + ratio*real(m)
  569. e = (real(n)*ratio + imag(n)) / denom
  570. f = (imag(n)*ratio - real(n)) / denom
  571. }
  572. return complex(e, f)
  573. }
  574. mul_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 {
  575. q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
  576. r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
  577. t0 := r0*q0 - r1*q1 - r2*q2 - r3*q3
  578. t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2
  579. t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1
  580. t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0
  581. return quaternion(w=t0, x=t1, y=t2, z=t3)
  582. }
  583. mul_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 {
  584. q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
  585. r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
  586. t0 := r0*q0 - r1*q1 - r2*q2 - r3*q3
  587. t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2
  588. t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1
  589. t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0
  590. return quaternion(w=t0, x=t1, y=t2, z=t3)
  591. }
  592. mul_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 {
  593. q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
  594. r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
  595. t0 := r0*q0 - r1*q1 - r2*q2 - r3*q3
  596. t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2
  597. t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1
  598. t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0
  599. return quaternion(w=t0, x=t1, y=t2, z=t3)
  600. }
  601. quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 {
  602. q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
  603. r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
  604. invmag2 := 1.0 / (r0*r0 + r1*r1 + r2*r2 + r3*r3)
  605. t0 := (r0*q0 + r1*q1 + r2*q2 + r3*q3) * invmag2
  606. t1 := (r0*q1 - r1*q0 - r2*q3 - r3*q2) * invmag2
  607. t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2
  608. t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2
  609. return quaternion(w=t0, x=t1, y=t2, z=t3)
  610. }
  611. quo_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 {
  612. q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
  613. r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
  614. invmag2 := 1.0 / (r0*r0 + r1*r1 + r2*r2 + r3*r3)
  615. t0 := (r0*q0 + r1*q1 + r2*q2 + r3*q3) * invmag2
  616. t1 := (r0*q1 - r1*q0 - r2*q3 - r3*q2) * invmag2
  617. t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2
  618. t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2
  619. return quaternion(w=t0, x=t1, y=t2, z=t3)
  620. }
  621. quo_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 {
  622. q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
  623. r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
  624. invmag2 := 1.0 / (r0*r0 + r1*r1 + r2*r2 + r3*r3)
  625. t0 := (r0*q0 + r1*q1 + r2*q2 + r3*q3) * invmag2
  626. t1 := (r0*q1 - r1*q0 - r2*q3 - r3*q2) * invmag2
  627. t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2
  628. t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2
  629. return quaternion(w=t0, x=t1, y=t2, z=t3)
  630. }
  631. @(link_name="__truncsfhf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  632. truncsfhf2 :: proc "c" (value: f32) -> __float16 {
  633. v: struct #raw_union { i: u32, f: f32 }
  634. i, s, e, m: i32
  635. v.f = value
  636. i = i32(v.i)
  637. s = (i >> 16) & 0x00008000
  638. e = ((i >> 23) & 0x000000ff) - (127 - 15)
  639. m = i & 0x007fffff
  640. if e <= 0 {
  641. if e < -10 {
  642. return transmute(__float16)u16(s)
  643. }
  644. m = (m | 0x00800000) >> u32(1 - e)
  645. if m & 0x00001000 != 0 {
  646. m += 0x00002000
  647. }
  648. return transmute(__float16)u16(s | (m >> 13))
  649. } else if e == 0xff - (127 - 15) {
  650. if m == 0 {
  651. return transmute(__float16)u16(s | 0x7c00) /* NOTE(bill): infinity */
  652. } else {
  653. /* NOTE(bill): NAN */
  654. m >>= 13
  655. return transmute(__float16)u16(s | 0x7c00 | m | i32(m == 0))
  656. }
  657. } else {
  658. if m & 0x00001000 != 0 {
  659. m += 0x00002000
  660. if (m & 0x00800000) != 0 {
  661. m = 0
  662. e += 1
  663. }
  664. }
  665. if e > 30 {
  666. f := i64(1e12)
  667. for j := 0; j < 10; j += 1 {
  668. /* NOTE(bill): Cause overflow */
  669. g := intrinsics.volatile_load(&f)
  670. g *= g
  671. intrinsics.volatile_store(&f, g)
  672. }
  673. return transmute(__float16)u16(s | 0x7c00)
  674. }
  675. return transmute(__float16)u16(s | (e << 10) | (m >> 13))
  676. }
  677. }
  678. @(link_name="__truncdfhf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  679. truncdfhf2 :: proc "c" (value: f64) -> __float16 {
  680. return truncsfhf2(f32(value))
  681. }
  682. @(link_name="__gnu_h2f_ieee", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  683. gnu_h2f_ieee :: proc "c" (value_: __float16) -> f32 {
  684. fp32 :: struct #raw_union { u: u32, f: f32 }
  685. value := transmute(u16)value_
  686. v: fp32
  687. magic, inf_or_nan: fp32
  688. magic.u = u32((254 - 15) << 23)
  689. inf_or_nan.u = u32((127 + 16) << 23)
  690. v.u = u32(value & 0x7fff) << 13
  691. v.f *= magic.f
  692. if v.f >= inf_or_nan.f {
  693. v.u |= 255 << 23
  694. }
  695. v.u |= u32(value & 0x8000) << 16
  696. return v.f
  697. }
  698. @(link_name="__gnu_f2h_ieee", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  699. gnu_f2h_ieee :: proc "c" (value: f32) -> __float16 {
  700. return truncsfhf2(value)
  701. }
  702. @(link_name="__extendhfsf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  703. extendhfsf2 :: proc "c" (value: __float16) -> f32 {
  704. return gnu_h2f_ieee(value)
  705. }
  706. @(link_name="__floattidf", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  707. floattidf :: proc "c" (a: i128) -> f64 {
  708. when IS_WASM {
  709. return 0
  710. } else {
  711. DBL_MANT_DIG :: 53
  712. if a == 0 {
  713. return 0.0
  714. }
  715. a := a
  716. N :: size_of(i128) * 8
  717. s := a >> (N-1)
  718. a = (a ~ s) - s
  719. sd: = N - intrinsics.count_leading_zeros(a) // number of significant digits
  720. e := i32(sd - 1) // exponent
  721. if sd > DBL_MANT_DIG {
  722. switch sd {
  723. case DBL_MANT_DIG + 1:
  724. a <<= 1
  725. case DBL_MANT_DIG + 2:
  726. // okay
  727. case:
  728. a = i128(u128(a) >> u128(sd - (DBL_MANT_DIG+2))) |
  729. i128(u128(a) & (~u128(0) >> u128(N + DBL_MANT_DIG+2 - sd)) != 0)
  730. }
  731. a |= i128((a & 4) != 0)
  732. a += 1
  733. a >>= 2
  734. if a & (i128(1) << DBL_MANT_DIG) != 0 {
  735. a >>= 1
  736. e += 1
  737. }
  738. } else {
  739. a <<= u128(DBL_MANT_DIG - sd) & 127
  740. }
  741. fb: [2]u32
  742. fb[1] = (u32(s) & 0x80000000) | // sign
  743. (u32(e + 1023) << 20) | // exponent
  744. u32((u64(a) >> 32) & 0x000FFFFF) // mantissa-high
  745. fb[0] = u32(a) // mantissa-low
  746. return transmute(f64)fb
  747. }
  748. }
  749. @(link_name="__floattidf_unsigned", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  750. floattidf_unsigned :: proc "c" (a: u128) -> f64 {
  751. when IS_WASM {
  752. return 0
  753. } else {
  754. DBL_MANT_DIG :: 53
  755. if a == 0 {
  756. return 0.0
  757. }
  758. a := a
  759. N :: size_of(u128) * 8
  760. sd: = N - intrinsics.count_leading_zeros(a) // number of significant digits
  761. e := i32(sd - 1) // exponent
  762. if sd > DBL_MANT_DIG {
  763. switch sd {
  764. case DBL_MANT_DIG + 1:
  765. a <<= 1
  766. case DBL_MANT_DIG + 2:
  767. // okay
  768. case:
  769. a = u128(u128(a) >> u128(sd - (DBL_MANT_DIG+2))) |
  770. u128(u128(a) & (~u128(0) >> u128(N + DBL_MANT_DIG+2 - sd)) != 0)
  771. }
  772. a |= u128((a & 4) != 0)
  773. a += 1
  774. a >>= 2
  775. if a & (1 << DBL_MANT_DIG) != 0 {
  776. a >>= 1
  777. e += 1
  778. }
  779. } else {
  780. a <<= u128(DBL_MANT_DIG - sd)
  781. }
  782. fb: [2]u32
  783. fb[1] = (0) | // sign
  784. u32((e + 1023) << 20) | // exponent
  785. u32((u64(a) >> 32) & 0x000FFFFF) // mantissa-high
  786. fb[0] = u32(a) // mantissa-low
  787. return transmute(f64)fb
  788. }
  789. }
  790. @(link_name="__fixunsdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  791. fixunsdfti :: #force_no_inline proc "c" (a: f64) -> u128 {
  792. // TODO(bill): implement `fixunsdfti` correctly
  793. x := u64(a)
  794. return u128(x)
  795. }
  796. @(link_name="__fixunsdfdi", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  797. fixunsdfdi :: #force_no_inline proc "c" (a: f64) -> i128 {
  798. // TODO(bill): implement `fixunsdfdi` correctly
  799. x := i64(a)
  800. return i128(x)
  801. }
  802. @(link_name="__umodti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  803. umodti3 :: proc "c" (a, b: u128) -> u128 {
  804. r: u128 = ---
  805. _ = udivmod128(a, b, &r)
  806. return r
  807. }
  808. @(link_name="__udivmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  809. udivmodti4 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
  810. return udivmod128(a, b, rem)
  811. }
  812. @(link_name="__udivti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  813. udivti3 :: proc "c" (a, b: u128) -> u128 {
  814. return udivmodti4(a, b, nil)
  815. }
  816. @(link_name="__modti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  817. modti3 :: proc "c" (a, b: i128) -> i128 {
  818. s_a := a >> (128 - 1)
  819. s_b := b >> (128 - 1)
  820. an := (a ~ s_a) - s_a
  821. bn := (b ~ s_b) - s_b
  822. r: u128 = ---
  823. _ = udivmod128(transmute(u128)an, transmute(u128)bn, &r)
  824. return (transmute(i128)r ~ s_a) - s_a
  825. }
  826. @(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  827. divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
  828. u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem)
  829. return transmute(i128)u
  830. }
  831. @(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  832. divti3 :: proc "c" (a, b: i128) -> i128 {
  833. u := udivmodti4(transmute(u128)a, transmute(u128)b, nil)
  834. return transmute(i128)u
  835. }
  836. @(link_name="__fixdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  837. fixdfti :: proc(a: u64) -> i128 {
  838. significandBits :: 52
  839. typeWidth :: (size_of(u64)*8)
  840. exponentBits :: (typeWidth - significandBits - 1)
  841. maxExponent :: ((1 << exponentBits) - 1)
  842. exponentBias :: (maxExponent >> 1)
  843. implicitBit :: (u64(1) << significandBits)
  844. significandMask :: (implicitBit - 1)
  845. signBit :: (u64(1) << (significandBits + exponentBits))
  846. absMask :: (signBit - 1)
  847. exponentMask :: (absMask ~ significandMask)
  848. // Break a into sign, exponent, significand
  849. aRep := a
  850. aAbs := aRep & absMask
  851. sign := i128(-1 if aRep & signBit != 0 else 1)
  852. exponent := u64((aAbs >> significandBits) - exponentBias)
  853. significand := u64((aAbs & significandMask) | implicitBit)
  854. // If exponent is negative, the result is zero.
  855. if exponent < 0 {
  856. return 0
  857. }
  858. // If the value is too large for the integer type, saturate.
  859. if exponent >= size_of(i128) * 8 {
  860. return max(i128) if sign == 1 else min(i128)
  861. }
  862. // If 0 <= exponent < significandBits, right shift to get the result.
  863. // Otherwise, shift left.
  864. if exponent < significandBits {
  865. return sign * i128(significand >> (significandBits - exponent))
  866. } else {
  867. return sign * (i128(significand) << (exponent - significandBits))
  868. }
  869. }