Skip to content

Commit

Permalink
Add -disallow-128-bit
Browse files Browse the repository at this point in the history
  • Loading branch information
gingerBill committed Nov 15, 2024
1 parent 2af014b commit 62bc7b0
Show file tree
Hide file tree
Showing 16 changed files with 235 additions and 88 deletions.
5 changes: 4 additions & 1 deletion base/runtime/error_checks.odin
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ when ODIN_NO_RTTI {
case 2: idx = int((^u16)(tag_ptr)^) - 1
case 4: idx = int((^u32)(tag_ptr)^) - 1
case 8: idx = int((^u64)(tag_ptr)^) - 1
case 16: idx = int((^u128)(tag_ptr)^) - 1
case 16:
when ODIN_ALLOW_128_BIT {
idx = int((^u128)(tag_ptr)^) - 1
}
}
if idx < 0 {
return nil
Expand Down
4 changes: 2 additions & 2 deletions base/runtime/internal.odin
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ extendhfsf2 :: proc "c" (value: __float16) -> f32 {
}



when ODIN_ALLOW_128_BIT {
@(link_name="__floattidf", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
floattidf :: proc "c" (a: i128) -> f64 {
DBL_MANT_DIG :: 53
Expand Down Expand Up @@ -1086,7 +1086,7 @@ fixdfti :: proc "c" (a: u64) -> i128 {
}

}

}


__write_bits :: proc "contextless" (dst, src: [^]byte, offset: uintptr, size: uintptr) {
Expand Down
4 changes: 4 additions & 0 deletions base/runtime/udivmod128.odin
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package runtime

import "base:intrinsics"

when ODIN_ALLOW_128_BIT {

udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
_ctz :: intrinsics.count_trailing_zeros
_clz :: intrinsics.count_leading_zeros
Expand Down Expand Up @@ -154,3 +156,5 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {

return q_all
}

}
48 changes: 33 additions & 15 deletions core/fmt/fmt.odin
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,8 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
fi.zero = false
_pad(fi, s)
}

when ODIN_ALLOW_128_BIT {
// Formats an int128 value based on the provided formatting options.
//
// Inputs:
Expand Down Expand Up @@ -1191,6 +1193,8 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i
fi.zero = false
_pad(fi, s)
}
}

// Units of measurements:
__MEMORY_LOWER := " b kib mib gib tib pib eib"
__MEMORY_UPPER := " B KiB MiB GiB TiB PiB EiB"
Expand Down Expand Up @@ -1306,6 +1310,8 @@ fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) {
fmt_bad_verb(fi, verb)
}
}

when ODIN_ALLOW_128_BIT {
// Formats an int128 value according to the specified formatting verb.
//
// Inputs:
Expand Down Expand Up @@ -1340,6 +1346,8 @@ fmt_int_128 :: proc(fi: ^Info, u: u128, is_signed: bool, bit_size: int, verb: ru
fmt_bad_verb(fi, verb)
}
}
}

// Pads a formatted string with the appropriate padding, based on the provided formatting options.
//
// Inputs:
Expand Down Expand Up @@ -1696,8 +1704,10 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') {
fmt_bit_set(fi, val, info.name, verb)

case runtime.Type_Info_Bit_Set:
bits: u128
bit_size := u128(8*type_info.size)
IT :: u128 when ODIN_ALLOW_128_BIT else u64

bits: IT
bit_size := IT(8*type_info.size)

do_byte_swap := is_bit_set_different_endian_to_platform(info.underlying)

Expand All @@ -1715,33 +1725,34 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') {
fmt_arg(fi, x, verb)
return
}
bits = u128(x)
bits = IT(x)
case 16:
x := (^u16)(v.data)^
if do_byte_swap { x = byte_swap(x) }
if as_arg {
fmt_arg(fi, x, verb)
return
}
bits = u128(x)
bits = IT(x)
case 32:
x := (^u32)(v.data)^
if do_byte_swap { x = byte_swap(x) }
if as_arg {
fmt_arg(fi, x, verb)
return
}
bits = u128(x)
bits = IT(x)
case 64:
x := (^u64)(v.data)^
if do_byte_swap { x = byte_swap(x) }
if as_arg {
fmt_arg(fi, x, verb)
return
}
bits = u128(x)
bits = IT(x)
case 128:
x := (^u128)(v.data)^
assert(ODIN_ALLOW_128_BIT)
x := (^IT)(v.data)^
if do_byte_swap { x = byte_swap(x) }
if as_arg {
fmt_arg(fi, x, verb)
Expand Down Expand Up @@ -3190,16 +3201,23 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) {
case i64be: fmt_int(fi, u64(a), true, 64, verb)
case u64be: fmt_int(fi, u64(a), false, 64, verb)

case i128: fmt_int_128(fi, u128(a), true, 128, verb)
case u128: fmt_int_128(fi, a, false, 128, verb)

case i128le: fmt_int_128(fi, u128(a), true, 128, verb)
case u128le: fmt_int_128(fi, u128(a), false, 128, verb)
case:
when ODIN_ALLOW_128_BIT {
switch a in base_arg {
case i128: fmt_int_128(fi, u128(a), true, 128, verb)
case u128: fmt_int_128(fi, a, false, 128, verb)

case i128be: fmt_int_128(fi, u128(a), true, 128, verb)
case u128be: fmt_int_128(fi, u128(a), false, 128, verb)
case i128le: fmt_int_128(fi, u128(a), true, 128, verb)
case u128le: fmt_int_128(fi, u128(a), false, 128, verb)

case: fmt_value(fi, arg, verb)
case i128be: fmt_int_128(fi, u128(a), true, 128, verb)
case u128be: fmt_int_128(fi, u128(a), false, 128, verb)
case:
fmt_value(fi, arg, verb)
}
} else {
fmt_value(fi, arg, verb)
}
}

}
3 changes: 3 additions & 0 deletions core/io/util.odin
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ write_int :: proc(w: Writer, i: int, base: int = 10, n_written: ^int = nil) -> (
return write_i64(w, i64(i), base, n_written)
}

when ODIN_ALLOW_128_BIT {
write_u128 :: proc(w: Writer, i: u128, base: int = 10, n_written: ^int = nil) -> (n: int, err: Error) {
buf: [39]byte
s := strconv.append_bits_128(buf[:], i, base, false, 128, strconv.digits, nil)
Expand All @@ -48,6 +49,8 @@ write_i128 :: proc(w: Writer, i: i128, base: int = 10, n_written: ^int = nil) ->
s := strconv.append_bits_128(buf[:], u128(i), base, true, 128, strconv.digits, nil)
return write_string(w, s, n_written)
}
}

write_f16 :: proc(w: Writer, val: f16, n_written: ^int = nil) -> (n: int, err: Error) {
buf: [386]byte

Expand Down
123 changes: 87 additions & 36 deletions core/math/bits/bits.odin
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,19 @@ mul_u32 :: proc "contextless" (x, y: u32) -> (hi, lo: u32) {
}
@(require_results)
mul_u64 :: proc "contextless" (x, y: u64) -> (hi, lo: u64) {
prod_wide := u128(x) * u128(y)
hi, lo = u64(prod_wide>>64), u64(prod_wide)
m :: 1<<32 - 1
x0 := x & m
x1 := x >> 32
y0 := y & m
y1 := y >> 32
w0 := x0 * y0
t := x1*y0 + w0>>32
w1 := t & m
w2 := t >> 32
w1 += x0 * y1

hi = x1*y1 + w2 + w1>>32
lo = x * y
return
}

Expand All @@ -263,22 +274,22 @@ mul :: proc{mul_u32, mul_u64, mul_uint}


@(require_results)
div_u32 :: proc "odin" (hi, lo, y: u32) -> (quo, rem: u32) {
assert(y != 0 && y <= hi)
div_u32 :: proc "contextless" (hi, lo, y: u32) -> (quo, rem: u32) {
assert_contextless(y != 0 && y <= hi)
z := u64(hi)<<32 | u64(lo)
quo, rem = u32(z/u64(y)), u32(z%u64(y))
return
}
@(require_results)
div_u64 :: proc "odin" (hi, lo, y: u64) -> (quo, rem: u64) {
div_u64 :: proc "contextless" (hi, lo, y: u64) -> (quo, rem: u64) {
y := y
two32 :: 1 << 32
mask32 :: two32 - 1
if y == 0 {
panic("divide error")
panic_contextless("divide error")
}
if y <= hi {
panic("overflow error")
panic_contextless("overflow error")
}

s := uint(count_leading_zeros(y))
Expand Down Expand Up @@ -382,9 +393,11 @@ bitfield_extract_u32 :: proc "contextless" (value: u32, offset, bits: uint) ->
@(require_results)
bitfield_extract_u64 :: proc "contextless" (value: u64, offset, bits: uint) -> u64 { return (value >> offset) & u64(1<<bits - 1) }
@(require_results)
bitfield_extract_u128 :: proc "contextless" (value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1) }
@(require_results)
bitfield_extract_uint :: proc "contextless" (value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1) }
when ODIN_ALLOW_128_BIT {
@(require_results)
bitfield_extract_u128 :: proc "contextless" (value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1) }
}

@(require_results)
bitfield_extract_i8 :: proc "contextless" (value: i8, offset, bits: uint) -> i8 {
Expand Down Expand Up @@ -414,13 +427,15 @@ bitfield_extract_i64 :: proc "contextless" (value: i64, offset, bits: uint) -> i
r := (v~m) - m
return i64(r)
}
when ODIN_ALLOW_128_BIT {
@(require_results)
bitfield_extract_i128 :: proc "contextless" (value: i128, offset, bits: uint) -> i128 {
v := (u128(value) >> offset) & u128(1<<bits - 1)
m := u128(1<<(bits-1))
r := (v~m) - m
return i128(r)
}
}
@(require_results)
bitfield_extract_int :: proc "contextless" (value: int, offset, bits: uint) -> int {
v := (uint(value) >> offset) & uint(1<<bits - 1)
Expand All @@ -429,23 +444,38 @@ bitfield_extract_int :: proc "contextless" (value: int, offset, bits: uint) -> i
return int(r)
}


bitfield_extract :: proc{
bitfield_extract_u8,
bitfield_extract_u16,
bitfield_extract_u32,
bitfield_extract_u64,
bitfield_extract_u128,
bitfield_extract_uint,
bitfield_extract_i8,
bitfield_extract_i16,
bitfield_extract_i32,
bitfield_extract_i64,
bitfield_extract_i128,
bitfield_extract_int,
when ODIN_ALLOW_128_BIT {
bitfield_extract :: proc{
bitfield_extract_u8,
bitfield_extract_u16,
bitfield_extract_u32,
bitfield_extract_u64,
bitfield_extract_u128,
bitfield_extract_uint,
bitfield_extract_i8,
bitfield_extract_i16,
bitfield_extract_i32,
bitfield_extract_i64,
bitfield_extract_i128,
bitfield_extract_int,
}
} else {
bitfield_extract :: proc{
bitfield_extract_u8,
bitfield_extract_u16,
bitfield_extract_u32,
bitfield_extract_u64,
bitfield_extract_uint,
bitfield_extract_i8,
bitfield_extract_i16,
bitfield_extract_i32,
bitfield_extract_i64,
bitfield_extract_int,
}
}



@(require_results)
bitfield_insert_u8 :: proc "contextless" (base, insert: u8, offset, bits: uint) -> u8 {
mask := u8(1<<bits - 1)
Expand All @@ -466,11 +496,13 @@ bitfield_insert_u64 :: proc "contextless" (base, insert: u64, offset, bits: uint
mask := u64(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
when ODIN_ALLOW_128_BIT {
@(require_results)
bitfield_insert_u128 :: proc "contextless" (base, insert: u128, offset, bits: uint) -> u128 {
mask := u128(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
}
@(require_results)
bitfield_insert_uint :: proc "contextless" (base, insert: uint, offset, bits: uint) -> uint {
mask := uint(1<<bits - 1)
Expand All @@ -497,28 +529,47 @@ bitfield_insert_i64 :: proc "contextless" (base, insert: i64, offset, bits: uint
mask := i64(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
when ODIN_ALLOW_128_BIT {
@(require_results)
bitfield_insert_i128 :: proc "contextless" (base, insert: i128, offset, bits: uint) -> i128 {
mask := i128(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
}
@(require_results)
bitfield_insert_int :: proc "contextless" (base, insert: int, offset, bits: uint) -> int {
mask := int(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}

bitfield_insert :: proc{
bitfield_insert_u8,
bitfield_insert_u16,
bitfield_insert_u32,
bitfield_insert_u64,
bitfield_insert_u128,
bitfield_insert_uint,
bitfield_insert_i8,
bitfield_insert_i16,
bitfield_insert_i32,
bitfield_insert_i64,
bitfield_insert_i128,
bitfield_insert_int,

when ODIN_ALLOW_128_BIT {
bitfield_insert :: proc{
bitfield_insert_u8,
bitfield_insert_u16,
bitfield_insert_u32,
bitfield_insert_u64,
bitfield_insert_u128,
bitfield_insert_uint,
bitfield_insert_i8,
bitfield_insert_i16,
bitfield_insert_i32,
bitfield_insert_i64,
bitfield_insert_i128,
bitfield_insert_int,
}
} else {
bitfield_insert :: proc{
bitfield_insert_u8,
bitfield_insert_u16,
bitfield_insert_u32,
bitfield_insert_u64,
bitfield_insert_uint,
bitfield_insert_i8,
bitfield_insert_i16,
bitfield_insert_i32,
bitfield_insert_i64,
bitfield_insert_int,
}
}

Loading

0 comments on commit 62bc7b0

Please sign in to comment.