Fix 128-bit integer support for wasm targets

This commit is contained in:
gingerBill
2024-09-20 01:29:39 +01:00
parent a4dd489284
commit b116e8ff55
3 changed files with 51 additions and 24 deletions
+41 -19
View File
@@ -14,33 +14,57 @@ ti_uint :: struct #raw_union {
}
@(link_name="__ashlti3", linkage="strong")
__ashlti3 :: proc "contextless" (la, ha: u64, b_: u32) -> i128 {
bits_in_dword :: size_of(u32)*8
b := u32(b_)
__ashlti3 :: proc "contextless" (a: i128, b: u32) -> i128 {
bits :: 64
input, result: ti_int
input.lo, input.hi = la, ha
if b & bits_in_dword != 0 {
input: ti_int = ---
result: ti_int = ---
input.all = a
if b & bits != 0 {
result.lo = 0
result.hi = input.lo << (b-bits_in_dword)
result.hi = input.lo << (b-bits)
} else {
if b == 0 {
return input.all
return a
}
result.lo = input.lo<<b
result.hi = (input.hi<<b) | (input.lo>>(bits_in_dword-b))
result.hi = (input.hi<<b) | (input.lo>>(bits-b))
}
return result.all
}
__ashlti3_unsigned :: proc "contextless" (a: u128, b: u32) -> u128 {
return cast(u128)__ashlti3(cast(i128)a, b)
}
@(link_name="__mulddi3", linkage="strong")
__mulddi3 :: proc "contextless" (a, b: u64) -> i128 {
r: ti_int
bits :: 32
mask :: ~u64(0) >> bits
r.lo = (a & mask) * (b & mask)
t := r.lo >> bits
r.lo &= mask
t += (a >> bits) * (b & mask)
r.lo += (t & mask) << bits
r.hi = t >> bits
t = r.lo >> bits
r.lo &= mask
t += (b >> bits) * (a & mask)
r.lo += (t & mask) << bits
r.hi += t >> bits
r.hi += (a >> bits) * (b >> bits)
return r.all
}
@(link_name="__multi3", linkage="strong")
__multi3 :: proc "contextless" (la, ha, lb, hb: u64) -> i128 {
__multi3 :: proc "contextless" (a, b: i128) -> i128 {
x, y, r: ti_int
x.lo, x.hi = la, ha
y.lo, y.hi = lb, hb
r.all = i128(x.lo * y.lo) // TODO this is incorrect
x.all = a
y.all = b
r.all = __mulddi3(x.lo, y.lo)
r.hi += x.hi*y.lo + x.lo*y.hi
return r.all
}
@@ -54,18 +78,16 @@ udivti3 :: proc "c" (la, ha, lb, hb: u64) -> u128 {
}
@(link_name="__lshrti3", linkage="strong")
__lshrti3 :: proc "c" (la, ha: u64, b: u32) -> i128 {
bits :: size_of(u32)*8
__lshrti3 :: proc "c" (a: i128, b: u32) -> i128 {
bits :: 64
input, result: ti_int
input.lo = la
input.hi = ha
input.all = a
if b & bits != 0 {
result.hi = 0
result.lo = input.hi >> (b - bits)
} else if b == 0 {
return input.all
return a
} else {
result.hi = input.hi >> b
result.lo = (input.hi << (bits - b)) | (input.lo >> b)