internal.odin 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  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 :: false // !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 "contextless" (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 "contextless" (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. when !IS_WASM {
  813. @(link_name="__udivti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  814. udivti3 :: proc "c" (a, b: u128) -> u128 {
  815. return udivmodti4(a, b, nil)
  816. }
  817. }
  818. @(link_name="__modti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  819. modti3 :: proc "c" (a, b: i128) -> i128 {
  820. s_a := a >> (128 - 1)
  821. s_b := b >> (128 - 1)
  822. an := (a ~ s_a) - s_a
  823. bn := (b ~ s_b) - s_b
  824. r: u128 = ---
  825. _ = udivmod128(transmute(u128)an, transmute(u128)bn, &r)
  826. return (transmute(i128)r ~ s_a) - s_a
  827. }
  828. @(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  829. divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
  830. u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem)
  831. return transmute(i128)u
  832. }
  833. @(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  834. divti3 :: proc "c" (a, b: i128) -> i128 {
  835. u := udivmodti4(transmute(u128)a, transmute(u128)b, nil)
  836. return transmute(i128)u
  837. }
  838. @(link_name="__fixdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
  839. fixdfti :: proc(a: u64) -> i128 {
  840. significandBits :: 52
  841. typeWidth :: (size_of(u64)*8)
  842. exponentBits :: (typeWidth - significandBits - 1)
  843. maxExponent :: ((1 << exponentBits) - 1)
  844. exponentBias :: (maxExponent >> 1)
  845. implicitBit :: (u64(1) << significandBits)
  846. significandMask :: (implicitBit - 1)
  847. signBit :: (u64(1) << (significandBits + exponentBits))
  848. absMask :: (signBit - 1)
  849. exponentMask :: (absMask ~ significandMask)
  850. // Break a into sign, exponent, significand
  851. aRep := a
  852. aAbs := aRep & absMask
  853. sign := i128(-1 if aRep & signBit != 0 else 1)
  854. exponent := u64((aAbs >> significandBits) - exponentBias)
  855. significand := u64((aAbs & significandMask) | implicitBit)
  856. // If exponent is negative, the result is zero.
  857. if exponent < 0 {
  858. return 0
  859. }
  860. // If the value is too large for the integer type, saturate.
  861. if exponent >= size_of(i128) * 8 {
  862. return max(i128) if sign == 1 else min(i128)
  863. }
  864. // If 0 <= exponent < significandBits, right shift to get the result.
  865. // Otherwise, shift left.
  866. if exponent < significandBits {
  867. return sign * i128(significand >> (significandBits - exponent))
  868. } else {
  869. return sign * (i128(significand) << (exponent - significandBits))
  870. }
  871. }
  872. __write_bits :: proc "contextless" (dst, src: [^]byte, offset: uintptr, size: uintptr) {
  873. for i in 0..<size {
  874. j := offset+i
  875. the_bit := byte((src[i>>3]) & (1<<(i&7)) != 0)
  876. dst[j>>3] &~= 1<<(j&7)
  877. dst[j>>3] |= the_bit<<(j&7)
  878. }
  879. }
  880. __read_bits :: proc "contextless" (dst, src: [^]byte, offset: uintptr, size: uintptr) {
  881. for j in 0..<size {
  882. i := offset+j
  883. the_bit := byte((src[i>>3]) & (1<<(i&7)) != 0)
  884. dst[j>>3] &~= 1<<(j&7)
  885. dst[j>>3] |= the_bit<<(j&7)
  886. }
  887. }