mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 03:40:08 +00:00
128 bit integers
Kind of works but may be buggy due to LLVM not actually sure
This commit is contained in:
+2
-1
@@ -131,7 +131,6 @@ fmuladd64 :: proc(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64"
|
||||
|
||||
|
||||
|
||||
|
||||
Allocator :: struct #ordered {
|
||||
Mode :: enum {
|
||||
ALLOC,
|
||||
@@ -364,3 +363,5 @@ __enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
#shared_global_scope
|
||||
|
||||
#import "fmt.odin"
|
||||
|
||||
|
||||
__u128_mod :: proc(a, b: u128) -> u128 #link_name "__umodti3" {
|
||||
_, r := __u128_quo_mod(a, b)
|
||||
return r
|
||||
}
|
||||
|
||||
__u128_quo :: proc(a, b: u128) -> u128 #link_name "__udivti3" {
|
||||
n, _ := __u128_quo_mod(a, b)
|
||||
return n
|
||||
}
|
||||
|
||||
__i128_mod :: proc(a, b: i128) -> i128 #link_name "__modti3" {
|
||||
_, r := __i128_quo_mod(a, b)
|
||||
return r
|
||||
}
|
||||
|
||||
__i128_quo :: proc(a, b: i128) -> i128 #link_name "__divti3" {
|
||||
n, _ := __i128_quo_mod(a, b)
|
||||
return n
|
||||
}
|
||||
|
||||
__i128_quo_mod :: proc(a, b: i128) -> (i128, i128) #link_name "__divmodti4" {
|
||||
s := b >> 127
|
||||
b = (b ~ s) - s
|
||||
s = a >> 127
|
||||
a = (a ~ s) - s
|
||||
|
||||
n, r := __u128_quo_mod(a as u128, b as u128)
|
||||
return (n as i128 ~ s) - s, (r as i128 ~ s) - s
|
||||
}
|
||||
|
||||
|
||||
__u128_quo_mod :: proc(a, b: u128) -> (u128, u128) #link_name "__udivmodti4" {
|
||||
clz :: proc(x: u64) -> u64 {
|
||||
clz_u64 :: proc(x: u64, is_zero_undef: bool) -> u64 #foreign "llvm.ctlz.i64"
|
||||
return clz_u64(x, false)
|
||||
}
|
||||
ctz :: proc(x: u64) -> u64 {
|
||||
ctz_u64 :: proc(x: u64, is_zero_undef: bool) -> u64 #foreign "llvm.cttz.i64"
|
||||
return ctz_u64(x, false)
|
||||
}
|
||||
|
||||
|
||||
u128_lo_hi :: raw_union {
|
||||
all: u128
|
||||
using _lohi: struct {lo, hi: u64}
|
||||
}
|
||||
|
||||
n, d, q, r: u128_lo_hi
|
||||
sr: u64
|
||||
|
||||
n.all = a
|
||||
d.all = b
|
||||
|
||||
if n.hi == 0 {
|
||||
if d.hi == 0 {
|
||||
return (n.lo / d.lo) as u128, (n.lo % d.lo) as u128
|
||||
}
|
||||
return 0, n.lo as u128
|
||||
}
|
||||
if d.lo == 0 {
|
||||
if d.hi == 0 {
|
||||
return (n.hi / d.lo) as u128, (n.hi % d.lo) as u128
|
||||
}
|
||||
if n.lo == 0 {
|
||||
r.hi = n.hi % d.hi
|
||||
r.lo = 0
|
||||
return (n.hi / d.hi) as u128, r.all
|
||||
}
|
||||
if (d.hi & (d.hi-1)) == 0 {
|
||||
r.lo = n.lo
|
||||
r.hi = n.hi & (d.hi-1)
|
||||
return (n.hi >> ctz(d.hi)) as u128, r.all
|
||||
}
|
||||
|
||||
sr = clz(d.hi) - clz(n.hi)
|
||||
if sr > 64 - 2 {
|
||||
return 0, n.all
|
||||
}
|
||||
sr++
|
||||
q.lo = 0
|
||||
q.hi = n.lo << (64-sr)
|
||||
r.hi = n.hi >> sr
|
||||
r.lo = (n.hi << (64-sr)) | (n.lo >> sr)
|
||||
} else {
|
||||
if d.hi == 0 {
|
||||
if (d.lo & (d.lo - 1)) == 0 {
|
||||
rem := (n.lo % (d.lo - 1)) as u128
|
||||
if d.lo == 1 {
|
||||
return n.all, rem
|
||||
}
|
||||
sr = ctz(d.lo)
|
||||
q.hi = n.hi >> sr
|
||||
q.lo = (n.hi << (64-sr)) | (n.lo >> sr);
|
||||
return q.all, rem
|
||||
}
|
||||
|
||||
sr = 1 + 64 + clz(d.lo) - clz(n.hi)
|
||||
|
||||
q.all = n.all << (128-sr)
|
||||
r.all = n.all >> sr
|
||||
if sr == 64 {
|
||||
q.lo = 0
|
||||
q.hi = n.lo
|
||||
r.hi = 0
|
||||
r.lo = n.hi
|
||||
} else if sr < 64 {
|
||||
q.lo = 0
|
||||
q.hi = n.lo << (64-sr)
|
||||
r.hi = n.hi >> sr
|
||||
r.lo = (n.hi << (64-sr)) | (n.lo >> sr)
|
||||
} else {
|
||||
q.lo = n.lo << (128-sr)
|
||||
q.hi = (n.hi << (128-sr)) | (n.lo >> (sr-64))
|
||||
r.hi = 0
|
||||
r.lo = n.hi >> (sr-64)
|
||||
}
|
||||
} else {
|
||||
sr = clz(d.hi) - clz(n.hi)
|
||||
if sr > 64-1 {
|
||||
return 0, n.all
|
||||
}
|
||||
sr++
|
||||
q.lo = 0
|
||||
q.hi = n.lo << (64-sr)
|
||||
r.all = n.all >> sr
|
||||
if sr < 64 {
|
||||
r.hi = n.hi >> sr
|
||||
r.lo = (n.hi << (64-sr)) | (n.lo >> sr)
|
||||
} else {
|
||||
r.hi = 0
|
||||
r.lo = n.hi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
carry: u64
|
||||
for ; sr > 0; sr-- {
|
||||
r.hi = (r.hi << 1) | (r.lo >> (64-1))
|
||||
r.lo = (r.lo << 1) | (r.hi >> (64-1))
|
||||
q.hi = (q.hi << 1) | (q.lo >> (64-1))
|
||||
q.lo = (q.lo << 1) | carry
|
||||
|
||||
carry = 0
|
||||
if r.all >= d.all {
|
||||
r.all -= d.all
|
||||
carry = 1
|
||||
}
|
||||
}
|
||||
|
||||
q.all = (q.all << 1) | (carry as u128)
|
||||
return q.all, r.all
|
||||
}
|
||||
+65
-58
@@ -91,11 +91,12 @@ print_pointer_to_buffer :: proc(buffer: ^[]byte, p: rawptr) #inline {
|
||||
print_u64_to_buffer(buffer, p as uint as u64)
|
||||
}
|
||||
|
||||
print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7) }
|
||||
print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f, 10) }
|
||||
print_f16_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 4) }
|
||||
print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7) }
|
||||
print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f as f64, 16) }
|
||||
print_u64_to_buffer :: proc(buffer: ^[]byte, value: u64) {
|
||||
i := value
|
||||
buf: [22]byte
|
||||
buf: [20]byte
|
||||
len := 0
|
||||
if i == 0 {
|
||||
buf[len] = #rune "0"
|
||||
@@ -119,6 +120,25 @@ print_i64_to_buffer :: proc(buffer: ^[]byte, value: i64) {
|
||||
print_u64_to_buffer(buffer, i as u64)
|
||||
}
|
||||
|
||||
print_u128_to_buffer :: proc(buffer: ^[]byte, value: u128) {
|
||||
a := value transmute [2]u64
|
||||
if a[1] != 0 {
|
||||
print_u64_to_buffer(buffer, a[1])
|
||||
}
|
||||
print_u64_to_buffer(buffer, a[0])
|
||||
}
|
||||
print_i128_to_buffer :: proc(buffer: ^[]byte, value: i128) {
|
||||
i := value
|
||||
neg := i < 0
|
||||
if neg {
|
||||
i = -i
|
||||
print_rune_to_buffer(buffer, #rune "-")
|
||||
}
|
||||
print_u128_to_buffer(buffer, i as u128)
|
||||
}
|
||||
|
||||
|
||||
|
||||
print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) {
|
||||
f := value
|
||||
if f == 0 {
|
||||
@@ -136,8 +156,8 @@ print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) {
|
||||
|
||||
print_rune_to_buffer(buffer, #rune ".")
|
||||
|
||||
mult := 10.0
|
||||
for decimal_places := 6; decimal_places >= 0; decimal_places-- {
|
||||
mult: f64 = 10.0
|
||||
for ; decimal_places >= 0; decimal_places-- {
|
||||
i = (f * mult) as u64
|
||||
print_u64_to_buffer(buffer, i as u64)
|
||||
f -= i as f64 / mult
|
||||
@@ -289,6 +309,11 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
||||
return
|
||||
}
|
||||
|
||||
if arg.data == nil {
|
||||
print_string_to_buffer(buf, "<nil>")
|
||||
return
|
||||
}
|
||||
|
||||
using Type_Info
|
||||
match type info : arg.type_info {
|
||||
case Named:
|
||||
@@ -315,63 +340,50 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
||||
}
|
||||
|
||||
case Integer:
|
||||
if arg.data != nil {
|
||||
match type i : arg {
|
||||
case i8: print_i64_to_buffer(buf, i as i64)
|
||||
case i16: print_i64_to_buffer(buf, i as i64)
|
||||
case i32: print_i64_to_buffer(buf, i as i64)
|
||||
case i64: print_i64_to_buffer(buf, i as i64)
|
||||
case u8: print_u64_to_buffer(buf, i as u64)
|
||||
case u16: print_u64_to_buffer(buf, i as u64)
|
||||
case u32: print_u64_to_buffer(buf, i as u64)
|
||||
case u64: print_u64_to_buffer(buf, i as u64)
|
||||
}
|
||||
} else {
|
||||
print_u64_to_buffer(buf, 0)
|
||||
match type i : arg {
|
||||
case i8: print_i64_to_buffer(buf, i as i64)
|
||||
case u8: print_u64_to_buffer(buf, i as u64)
|
||||
case i16: print_i64_to_buffer(buf, i as i64)
|
||||
case u16: print_u64_to_buffer(buf, i as u64)
|
||||
case i32: print_i64_to_buffer(buf, i as i64)
|
||||
case u32: print_u64_to_buffer(buf, i as u64)
|
||||
case i64: print_i64_to_buffer(buf, i as i64)
|
||||
case u64: print_u64_to_buffer(buf, i as u64)
|
||||
case i128: print_i128_to_buffer(buf, i)
|
||||
case u128: print_u128_to_buffer(buf, i)
|
||||
|
||||
case int: print_u64_to_buffer(buf, i as u64)
|
||||
case uint: print_u64_to_buffer(buf, i as u64)
|
||||
}
|
||||
|
||||
case Float:
|
||||
if arg.data != nil {
|
||||
match type f : arg {
|
||||
case f32: print_f64_to_buffer(buf, f as f64)
|
||||
case f64: print_f64_to_buffer(buf, f as f64)
|
||||
}
|
||||
} else {
|
||||
print_f64_to_buffer(buf, 0)
|
||||
match type f : arg {
|
||||
// case f16: print_f64_to_buffer(buf, f as f64)
|
||||
case f32: print_f64_to_buffer(buf, f as f64)
|
||||
case f64: print_f64_to_buffer(buf, f as f64)
|
||||
// case f128: print_f64_to_buffer(buf, f as f64)
|
||||
}
|
||||
|
||||
case String:
|
||||
if arg.data != nil {
|
||||
match type s : arg {
|
||||
case string: print_string_to_buffer(buf, s)
|
||||
}
|
||||
} else {
|
||||
print_string_to_buffer(buf, "")
|
||||
match type s : arg {
|
||||
case string: print_string_to_buffer(buf, s)
|
||||
}
|
||||
|
||||
case Boolean:
|
||||
if arg.data != nil {
|
||||
match type b : arg {
|
||||
case bool: print_bool_to_buffer(buf, b)
|
||||
}
|
||||
} else {
|
||||
print_bool_to_buffer(buf, false)
|
||||
match type b : arg {
|
||||
case bool: print_bool_to_buffer(buf, b)
|
||||
}
|
||||
|
||||
case Pointer:
|
||||
if arg.data != nil {
|
||||
match type p : arg {
|
||||
case ^Type_Info: print_type_to_buffer(buf, p)
|
||||
default: print_pointer_to_buffer(buf, (arg.data as ^rawptr)^)
|
||||
}
|
||||
} else {
|
||||
print_pointer_to_buffer(buf, nil)
|
||||
match type p : arg {
|
||||
case ^Type_Info: print_type_to_buffer(buf, p)
|
||||
default: print_pointer_to_buffer(buf, (arg.data as ^rawptr)^)
|
||||
}
|
||||
|
||||
case Maybe:
|
||||
size := mem.size_of_type_info(info.elem)
|
||||
data := slice_ptr(arg.data as ^byte, size+1)
|
||||
if data[size] != 0 && arg.data != nil {
|
||||
if data[size] != 0 {
|
||||
print_any_to_buffer(buf, make_any(info.elem, arg.data))
|
||||
} else {
|
||||
print_string_to_buffer(buf, "nil")
|
||||
@@ -381,14 +393,14 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
||||
value: i64 = 0
|
||||
|
||||
match type i : make_any(info.base, arg.data) {
|
||||
case i8: value = i as i64
|
||||
case i16: value = i as i64
|
||||
case i32: value = i as i64
|
||||
case i64: value = i as i64
|
||||
case u8: value = i as i64
|
||||
case u16: value = i as i64
|
||||
case u32: value = i as i64
|
||||
case u64: value = i as i64
|
||||
case i8: value = i as i64
|
||||
case i16: value = i as i64
|
||||
case i32: value = i as i64
|
||||
case i64: value = i as i64
|
||||
case u8: value = i as i64
|
||||
case u16: value = i as i64
|
||||
case u32: value = i as i64
|
||||
case u64: value = i as i64
|
||||
}
|
||||
print_string_to_buffer(buf, __enum_to_string(arg.type_info, value))
|
||||
|
||||
@@ -448,11 +460,6 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
|
||||
|
||||
|
||||
case Struct:
|
||||
if arg.data == nil {
|
||||
print_string_to_buffer(buf, "nil")
|
||||
return
|
||||
}
|
||||
|
||||
bprintf(buf, "%{", arg.type_info)
|
||||
defer print_string_to_buffer(buf, "}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user