mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-06 21:17:40 +00:00
Add -disallow-128-bit
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1086,7 +1086,7 @@ fixdfti :: proc "c" (a: u64) -> i128 {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
__write_bits :: proc "contextless" (dst, src: [^]byte, offset: uintptr, size: uintptr) {
|
||||
|
||||
@@ -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
|
||||
@@ -154,3 +156,5 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
|
||||
|
||||
return q_all
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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"
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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)
|
||||
|
||||
@@ -1715,7 +1725,7 @@ 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) }
|
||||
@@ -1723,7 +1733,7 @@ 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 32:
|
||||
x := (^u32)(v.data)^
|
||||
if do_byte_swap { x = byte_swap(x) }
|
||||
@@ -1731,7 +1741,7 @@ 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 64:
|
||||
x := (^u64)(v.data)^
|
||||
if do_byte_swap { x = byte_swap(x) }
|
||||
@@ -1739,9 +1749,10 @@ 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 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)
|
||||
@@ -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:
|
||||
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 i128le: fmt_int_128(fi, u128(a), true, 128, verb)
|
||||
case u128le: 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 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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
@@ -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 {
|
||||
@@ -414,6 +427,7 @@ 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)
|
||||
@@ -421,6 +435,7 @@ bitfield_extract_i128 :: proc "contextless" (value: i128, offset, bits: uint) ->
|
||||
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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1152,37 +1152,44 @@ as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
|
||||
case i16: value = i64(v)
|
||||
case i32: value = i64(v)
|
||||
case i64: value = v
|
||||
case i128: value = i64(v)
|
||||
case int: value = i64(v)
|
||||
|
||||
case u8: value = i64(v)
|
||||
case u16: value = i64(v)
|
||||
case u32: value = i64(v)
|
||||
case u64: value = i64(v)
|
||||
case u128: value = i64(v)
|
||||
case uint: value = i64(v)
|
||||
case uintptr: value = i64(v)
|
||||
|
||||
case u16le: value = i64(v)
|
||||
case u32le: value = i64(v)
|
||||
case u64le: value = i64(v)
|
||||
case u128le: value = i64(v)
|
||||
|
||||
case i16le: value = i64(v)
|
||||
case i32le: value = i64(v)
|
||||
case i64le: value = i64(v)
|
||||
case i128le: value = i64(v)
|
||||
|
||||
case u16be: value = i64(v)
|
||||
case u32be: value = i64(v)
|
||||
case u64be: value = i64(v)
|
||||
case u128be: value = i64(v)
|
||||
|
||||
case i16be: value = i64(v)
|
||||
case i32be: value = i64(v)
|
||||
case i64be: value = i64(v)
|
||||
case i128be: value = i64(v)
|
||||
case: valid = false
|
||||
case:
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
switch v in a {
|
||||
case i128: value = i64(v)
|
||||
case u128: value = i64(v)
|
||||
case u128le: value = i64(v)
|
||||
case i128le: value = i64(v)
|
||||
case u128be: value = i64(v)
|
||||
case i128be: value = i64(v)
|
||||
case: valid = false
|
||||
}
|
||||
} else {
|
||||
valid = false
|
||||
}
|
||||
}
|
||||
|
||||
case Type_Info_Rune:
|
||||
@@ -1260,37 +1267,44 @@ as_u64 :: proc(a: any) -> (value: u64, valid: bool) {
|
||||
case i16: value = u64(v)
|
||||
case i32: value = u64(v)
|
||||
case i64: value = u64(v)
|
||||
case i128: value = u64(v)
|
||||
case int: value = u64(v)
|
||||
|
||||
case u8: value = u64(v)
|
||||
case u16: value = u64(v)
|
||||
case u32: value = u64(v)
|
||||
case u64: value = (v)
|
||||
case u128: value = u64(v)
|
||||
case uint: value = u64(v)
|
||||
case uintptr:value = u64(v)
|
||||
|
||||
case u16le: value = u64(v)
|
||||
case u32le: value = u64(v)
|
||||
case u64le: value = u64(v)
|
||||
case u128le: value = u64(v)
|
||||
|
||||
case i16le: value = u64(v)
|
||||
case i32le: value = u64(v)
|
||||
case i64le: value = u64(v)
|
||||
case i128le: value = u64(v)
|
||||
|
||||
case u16be: value = u64(v)
|
||||
case u32be: value = u64(v)
|
||||
case u64be: value = u64(v)
|
||||
case u128be: value = u64(v)
|
||||
|
||||
case i16be: value = u64(v)
|
||||
case i32be: value = u64(v)
|
||||
case i64be: value = u64(v)
|
||||
case i128be: value = u64(v)
|
||||
case: valid = false
|
||||
case:
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
switch v in a {
|
||||
case i128: value = u64(v)
|
||||
case u128: value = u64(v)
|
||||
case u128le: value = u64(v)
|
||||
case i128le: value = u64(v)
|
||||
case u128be: value = u64(v)
|
||||
case i128be: value = u64(v)
|
||||
case: valid = false
|
||||
}
|
||||
} else {
|
||||
valid = false
|
||||
}
|
||||
}
|
||||
|
||||
case Type_Info_Rune:
|
||||
@@ -1370,34 +1384,41 @@ as_f64 :: proc(a: any) -> (value: f64, valid: bool) {
|
||||
case i16: value = f64(v)
|
||||
case i32: value = f64(v)
|
||||
case i64: value = f64(v)
|
||||
case i128: value = f64(v)
|
||||
|
||||
case u8: value = f64(v)
|
||||
case u16: value = f64(v)
|
||||
case u32: value = f64(v)
|
||||
case u64: value = f64(v)
|
||||
case u128: value = f64(v)
|
||||
|
||||
case u16le: value = f64(v)
|
||||
case u32le: value = f64(v)
|
||||
case u64le: value = f64(v)
|
||||
case u128le:value = f64(v)
|
||||
|
||||
case i16le: value = f64(v)
|
||||
case i32le: value = f64(v)
|
||||
case i64le: value = f64(v)
|
||||
case i128le:value = f64(v)
|
||||
|
||||
case u16be: value = f64(v)
|
||||
case u32be: value = f64(v)
|
||||
case u64be: value = f64(v)
|
||||
case u128be:value = f64(v)
|
||||
|
||||
case i16be: value = f64(v)
|
||||
case i32be: value = f64(v)
|
||||
case i64be: value = f64(v)
|
||||
case i128be:value = f64(v)
|
||||
case: valid = false
|
||||
case:
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
switch v in a {
|
||||
case i128: value = f64(v)
|
||||
case u128: value = f64(v)
|
||||
case u128le: value = f64(v)
|
||||
case i128le: value = f64(v)
|
||||
case u128be: value = f64(v)
|
||||
case i128be: value = f64(v)
|
||||
case: valid = false
|
||||
}
|
||||
} else {
|
||||
valid = false
|
||||
}
|
||||
}
|
||||
|
||||
case Type_Info_Rune:
|
||||
|
||||
@@ -103,6 +103,9 @@ append_bits :: proc(buf: []byte, x: u64, base: int, is_signed: bool, bit_size: i
|
||||
copy(buf, out)
|
||||
return string(buf[0:len(out)])
|
||||
}
|
||||
|
||||
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
/*
|
||||
Determines whether the given unsigned 128-bit integer is a negative value by interpreting it as a signed integer with the specified bit size.
|
||||
|
||||
@@ -208,3 +211,4 @@ append_bits_128 :: proc(buf: []byte, x: u128, base: int, is_signed: bool, bit_si
|
||||
copy(buf, out)
|
||||
return string(buf[0:len(out)])
|
||||
}
|
||||
}
|
||||
@@ -420,6 +420,8 @@ parse_uint :: proc(s: string, base := 0, n: ^int = nil) -> (value: uint, ok: boo
|
||||
value = uint(v)
|
||||
return
|
||||
}
|
||||
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
/*
|
||||
Parses an integer value from a string in the given base, without any prefix
|
||||
|
||||
@@ -703,6 +705,9 @@ parse_u128_maybe_prefixed :: proc(str: string, n: ^int = nil) -> (value: u128, o
|
||||
}
|
||||
//
|
||||
parse_u128 :: proc{parse_u128_maybe_prefixed, parse_u128_of_base}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Converts a byte to lowercase
|
||||
|
||||
@@ -1508,10 +1513,11 @@ append_int :: proc(buf: []byte, i: i64, base: int) -> string {
|
||||
}
|
||||
|
||||
|
||||
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
append_u128 :: proc(buf: []byte, u: u128, base: int) -> string {
|
||||
return append_bits_128(buf, u, base, false, 8*size_of(uint), digits, nil)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Converts an integer value to a string and stores it in the given buffer
|
||||
|
||||
@@ -4519,10 +4519,10 @@ DNS_RECORD :: struct { // aka DNS_RECORDA
|
||||
Flags: DWORD,
|
||||
dwTtl: DWORD,
|
||||
_: DWORD,
|
||||
Data: struct #raw_union {
|
||||
Data: struct #raw_union #align(16) {
|
||||
CNAME: DNS_PTR_DATAA,
|
||||
A: u32be, // Ipv4 Address
|
||||
AAAA: u128be, // Ipv6 Address
|
||||
AAAA: (u128be when ODIN_ALLOW_128_BIT else [16]u8), // Ipv6 Address
|
||||
TXT: DNS_TXT_DATAA,
|
||||
NS: DNS_PTR_DATAA,
|
||||
MX: DNS_MX_DATAA,
|
||||
|
||||
@@ -2,6 +2,8 @@ package time
|
||||
|
||||
import "base:runtime"
|
||||
import "base:intrinsics"
|
||||
import "core:math/bits"
|
||||
_ :: bits
|
||||
|
||||
/*
|
||||
Type representing monotonic time, useful for measuring durations.
|
||||
@@ -129,8 +131,14 @@ tsc_frequency :: proc "contextless" (fallback_sleep := 2 * Second) -> (u64, bool
|
||||
tsc_end := intrinsics.read_cycle_counter()
|
||||
tick_end := tick_now()
|
||||
|
||||
time_diff := u128(duration_nanoseconds(tick_diff(tick_begin, tick_end)))
|
||||
hz = u64((u128(tsc_end - tsc_begin) * 1_000_000_000) / time_diff)
|
||||
when ODIN_ALLOW_128_BIT {
|
||||
time_diff := u128(duration_nanoseconds(tick_diff(tick_begin, tick_end)))
|
||||
hz = u64((u128(tsc_end - tsc_begin) * 1_000_000_000) / time_diff)
|
||||
} else {
|
||||
time_diff := u64(duration_nanoseconds(tick_diff(tick_begin, tick_end)))
|
||||
hi, lo := bits.mul_u64(u64(tsc_end - tsc_begin), 1_000_000_000)
|
||||
hz, _ = bits.div_u64(hi, lo, time_diff)
|
||||
}
|
||||
}
|
||||
|
||||
return hz, true
|
||||
@@ -169,7 +177,7 @@ Benchmark_Options :: struct {
|
||||
// `bench()` can write the output slice here.
|
||||
output: []u8, // Unused for hash benchmarks
|
||||
// `bench()` can write the output hash here.
|
||||
hash: u128,
|
||||
hash: [16]u8,
|
||||
// `benchmark()` procedure will output the duration of benchmark
|
||||
duration: Duration,
|
||||
// `benchmark()` procedure will output the average count of elements
|
||||
|
||||
@@ -439,6 +439,7 @@ struct BuildContext {
|
||||
bool different_os;
|
||||
bool keep_object_files;
|
||||
bool disallow_do;
|
||||
bool disallow_128_bit;
|
||||
|
||||
LinkerChoice linker_choice;
|
||||
|
||||
|
||||
@@ -5219,7 +5219,9 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
}
|
||||
|
||||
if (sz >= 64) {
|
||||
if (is_type_unsigned(x.type)) {
|
||||
if (build_context.disallow_128_bit) {
|
||||
error(call, "'%.*s' is not allowed as requires 128-bit arithmetic which has been disallowed", LIT(builtin_name));
|
||||
} else if (is_type_unsigned(x.type)) {
|
||||
add_package_dependency(c, "runtime", "umodti3", true);
|
||||
add_package_dependency(c, "runtime", "udivti3", true);
|
||||
} else {
|
||||
|
||||
@@ -1851,6 +1851,11 @@ gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *nam
|
||||
if (o->type != nullptr && o->type->kind == Type_Named && o->type->Named.type_name->TypeName.is_type_alias) {
|
||||
o->type = base_type(o->type);
|
||||
}
|
||||
if (build_context.disallow_128_bit && is_type_integer_128bit(o->type)) {
|
||||
gbString s = type_to_string(o->type);
|
||||
error(n, "Use of '%s' has been disallowed", s);
|
||||
gb_string_free(s);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -3496,11 +3501,15 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forb
|
||||
if (src != dst) {
|
||||
bool const REQUIRE = true;
|
||||
if (is_type_integer_128bit(src) && is_type_float(dst)) {
|
||||
add_package_dependency(c, "runtime", "floattidf_unsigned", REQUIRE);
|
||||
add_package_dependency(c, "runtime", "floattidf", REQUIRE);
|
||||
if (!build_context.disallow_128_bit) {
|
||||
add_package_dependency(c, "runtime", "floattidf_unsigned", REQUIRE);
|
||||
add_package_dependency(c, "runtime", "floattidf", REQUIRE);
|
||||
}
|
||||
} else if (is_type_integer_128bit(dst) && is_type_float(src)) {
|
||||
add_package_dependency(c, "runtime", "fixunsdfti", REQUIRE);
|
||||
add_package_dependency(c, "runtime", "fixunsdfdi", REQUIRE);
|
||||
if (!build_context.disallow_128_bit) {
|
||||
add_package_dependency(c, "runtime", "fixunsdfti", REQUIRE);
|
||||
add_package_dependency(c, "runtime", "fixunsdfdi", REQUIRE);
|
||||
}
|
||||
} else if (src == t_f16 && is_type_float(dst)) {
|
||||
add_package_dependency(c, "runtime", "gnu_h2f_ieee", REQUIRE);
|
||||
add_package_dependency(c, "runtime", "extendhfsf2", REQUIRE);
|
||||
@@ -4043,8 +4052,16 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
|
||||
case Basic_quaternion128: add_package_dependency(c, "runtime", "quo_quaternion128"); break;
|
||||
case Basic_quaternion256: add_package_dependency(c, "runtime", "quo_quaternion256"); break;
|
||||
|
||||
case Basic_u128: add_package_dependency(c, "runtime", "udivti3", REQUIRE); break;
|
||||
case Basic_i128: add_package_dependency(c, "runtime", "divti3", REQUIRE); break;
|
||||
case Basic_u128:
|
||||
if (!build_context.disallow_128_bit) {
|
||||
add_package_dependency(c, "runtime", "udivti3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
case Basic_i128:
|
||||
if (!build_context.disallow_128_bit) {
|
||||
add_package_dependency(c, "runtime", "divti3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (op.kind == Token_Mul || op.kind == Token_MulEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
|
||||
@@ -1177,6 +1177,8 @@ gb_internal void init_universal(void) {
|
||||
|
||||
add_global_constant("ODIN_COMPILE_TIMESTAMP", t_untyped_integer, exact_value_i64(odin_compile_timestamp()));
|
||||
|
||||
add_global_bool_constant("ODIN_ALLOW_128_BIT", !bc->disallow_128_bit);
|
||||
|
||||
{
|
||||
String version = {};
|
||||
|
||||
|
||||
@@ -372,6 +372,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_NoRTTI,
|
||||
BuildFlag_DynamicMapCalls,
|
||||
BuildFlag_ObfuscateSourceCodeLocations,
|
||||
BuildFlag_Disallow128Bit,
|
||||
|
||||
BuildFlag_Compact,
|
||||
BuildFlag_GlobalDefinitions,
|
||||
@@ -589,6 +590,8 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
|
||||
add_flag(&build_flags, BuildFlag_ObfuscateSourceCodeLocations, str_lit("obfuscate-source-code-locations"), BuildFlagParam_None, Command__does_build);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_Disallow128Bit, str_lit("disallow-128-bit"), BuildFlagParam_None, Command__does_check);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc);
|
||||
add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc | Command_test);
|
||||
add_flag(&build_flags, BuildFlag_DocFormat, str_lit("doc-format"), BuildFlagParam_None, Command_doc);
|
||||
@@ -1389,6 +1392,10 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
build_context.obfuscate_source_code_locations = true;
|
||||
break;
|
||||
|
||||
case BuildFlag_Disallow128Bit:
|
||||
build_context.disallow_128_bit = true;
|
||||
break;
|
||||
|
||||
case BuildFlag_DefaultToNilAllocator:
|
||||
if (build_context.ODIN_DEFAULT_TO_PANIC_ALLOCATOR) {
|
||||
gb_printf_err("'-default-to-panic-allocator' cannot be used with '-default-to-nil-allocator'\n");
|
||||
|
||||
Reference in New Issue
Block a user