mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-23 16:07:52 +00:00
Hexadecimal floats for "perfect values" 0h42f60000 == 123; use bit_cast in compiler
This commit is contained in:
@@ -346,7 +346,7 @@ void init_build_context(void) {
|
||||
|
||||
{
|
||||
u16 x = 1;
|
||||
bool big = !(*cast(u8 *)&x);
|
||||
bool big = !bit_cast<u8>(x);
|
||||
bc->ODIN_ENDIAN = big ? str_lit("big") : str_lit("little");
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1227,7 +1227,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
||||
}
|
||||
|
||||
i64 i = v.value_integer;
|
||||
u64 u = *cast(u64 *)&i;
|
||||
u64 u = bit_cast<u64>(i);
|
||||
i64 s = 8*type_size_of(c->allocator, type);
|
||||
u64 umax = ~cast(u64)0ull;
|
||||
if (s < 64) {
|
||||
@@ -1336,7 +1336,7 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) {
|
||||
String str = {};
|
||||
i64 i = o->value.value_integer;
|
||||
if (is_type_unsigned(o->type)) {
|
||||
str = u64_to_string(*cast(u64 *)&i, buf, gb_size_of(buf));
|
||||
str = u64_to_string(bit_cast<u64>(i), buf, gb_size_of(buf));
|
||||
} else {
|
||||
str = i64_to_string(i, buf, gb_size_of(buf));
|
||||
}
|
||||
|
||||
+1
-1
@@ -262,7 +262,7 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
|
||||
ExactValue v = exact_value_to_integer(rhs->value);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
i64 i = v.value_integer;
|
||||
u64 u = *cast(u64 *)&i;
|
||||
u64 u = bit_cast<u64>(i);
|
||||
u64 umax = ~cast(u64)0ull;
|
||||
if (lhs_bits < 64) {
|
||||
umax = (1ull << cast(u64)lhs_bits) - 1ull;
|
||||
|
||||
@@ -12,6 +12,14 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
template <typename U, typename V>
|
||||
gb_inline U bit_cast(V &v) { return reinterpret_cast<U &>(v); }
|
||||
|
||||
template <typename U, typename V>
|
||||
gb_inline U const &bit_cast(V const &v) { return reinterpret_cast<U const &>(v); }
|
||||
|
||||
|
||||
gb_inline i64 align_formula(i64 size, i64 align) {
|
||||
if (align > 0) {
|
||||
i64 result = size + align-1;
|
||||
@@ -164,6 +172,7 @@ u64 u64_from_string(String string) {
|
||||
case 'd': base = 10; has_prefix = true; break;
|
||||
case 'z': base = 12; has_prefix = true; break;
|
||||
case 'x': base = 16; has_prefix = true; break;
|
||||
case 'h': base = 16; has_prefix = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-34
@@ -156,39 +156,6 @@ f64 float_from_string(String string) {
|
||||
i++;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (len-i > 2 &&
|
||||
str[i] == '0' &&
|
||||
str[i+1] == 'h') {
|
||||
i += 2;
|
||||
u8 *text = string.text;
|
||||
isize len = string.len;
|
||||
if (has_prefix) {
|
||||
text += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
u64 base = 16;
|
||||
|
||||
u64 result = {0};
|
||||
for (isize i = 0; i < len; i++) {
|
||||
Rune r = cast(Rune)text[i];
|
||||
if (r == '_') {
|
||||
continue;
|
||||
}
|
||||
u64 v = bit128__digit_value(r);
|
||||
if (v >= base) {
|
||||
break;
|
||||
}
|
||||
result *= base;
|
||||
result += v;
|
||||
}
|
||||
|
||||
|
||||
return *cast(f64 *)&result;
|
||||
}
|
||||
#endif
|
||||
|
||||
f64 value = 0.0;
|
||||
for (; i < len; i++) {
|
||||
Rune r = cast(Rune)str[i];
|
||||
@@ -255,7 +222,29 @@ f64 float_from_string(String string) {
|
||||
}
|
||||
|
||||
ExactValue exact_value_float_from_string(String string) {
|
||||
return exact_value_float(float_from_string(string));
|
||||
if (string.len > 2 && string[0] == '0' && string[1] == 'h') {
|
||||
|
||||
isize digit_count = 0;
|
||||
for (isize i = 2; i < string.len; i++) {
|
||||
if (string[i] != '_') {
|
||||
digit_count += 1;
|
||||
}
|
||||
}
|
||||
u64 u = u64_from_string(string);
|
||||
if (digit_count == 8) {
|
||||
u32 x = cast(u32)u;
|
||||
f32 f = bit_cast<f32>(x);
|
||||
return exact_value_float(cast(f64)f);
|
||||
} else if (digit_count == 16) {
|
||||
f64 f = bit_cast<f64>(u);
|
||||
return exact_value_float(f);
|
||||
} else {
|
||||
GB_PANIC("Invalid hexadecimal float, expected 8 or 16 digits, got %td", digit_count);
|
||||
}
|
||||
}
|
||||
|
||||
f64 f = float_from_string(string);
|
||||
return exact_value_float(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -278,7 +278,7 @@ f64 u128_to_f64(u128 a) {
|
||||
return -((cast(f64)h * 18446744073709551616.0) + cast(f64)l);
|
||||
}
|
||||
i128 u128_to_i128(u128 a) {
|
||||
return *cast(i128 *)&a;
|
||||
return bit_cast<i128>(a);
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ f64 i128_to_f64(i128 a) {
|
||||
return -((cast(f64)h * 18446744073709551616.0) + cast(f64)l);
|
||||
}
|
||||
u128 i128_to_u128(i128 a) {
|
||||
return *cast(u128 *)&a;
|
||||
return bit_cast<u128>(a);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,7 +335,7 @@ String i128_to_string(i128 a, char *out_buf, isize out_buf_len) {
|
||||
a = i128_neg(a);
|
||||
}
|
||||
|
||||
u128 v = *cast(u128 *)&a;
|
||||
u128 v = bit_cast<u128>(a);
|
||||
u128 b = u128_from_u64(10);;
|
||||
while (u128_ge(v, b)) {
|
||||
buf[--i] = gb__num_to_char_table[u128_to_i64(u128_mod(v, b))];
|
||||
@@ -692,9 +692,9 @@ void i128_divide(i128 a, i128 b, i128 *quo_, i128 *rem_) {
|
||||
irem = i128_from_i64(r);
|
||||
} else if (a.hi > 0 || b.hi > 0) {
|
||||
u128 q, r = {0};
|
||||
u128_divide(*cast(u128 *)&a, *cast(u128 *)&b, &q, &r);
|
||||
iquo = *cast(i128 *)&q;
|
||||
irem = *cast(i128 *)&r;
|
||||
u128_divide(bit_cast<u128>(a), bit_cast<u128>(b), &q, &r);
|
||||
iquo = bit_cast<i128>(q);
|
||||
irem = bit_cast<i128>(r);
|
||||
} else if (i128_eq(b, I128_ZERO)) {
|
||||
iquo = i128_from_u64(a.lo/b.lo);
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -595,7 +595,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
case ExactValue_Float: {
|
||||
GB_ASSERT_MSG(is_type_float(type), "%s", type_to_string(type));
|
||||
type = core_type(type);
|
||||
u64 u = *cast(u64*)&value.value_float;
|
||||
u64 u = bit_cast<u64>(value.value_float);
|
||||
switch (type->Basic.kind) {
|
||||
case Basic_f32:
|
||||
// IMPORTANT NOTE(bill): LLVM requires all floating point constants to be
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ gb_inline HashKey hash_integer(u64 u) {
|
||||
}
|
||||
gb_inline HashKey hash_f64(f64 f) {
|
||||
HashKey h = {HashKey_Default};
|
||||
h.key = *cast(u64 *)&f;
|
||||
h.key = bit_cast<u64>(f);
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
+26
-8
@@ -254,7 +254,7 @@ void syntax_error_va(Token token, char *fmt, va_list va) {
|
||||
LIT(token.pos.file), token.pos.line, token.pos.column,
|
||||
gb_bprintf_va(fmt, va));
|
||||
} else if (token.pos.line == 0) {
|
||||
gb_printf_err("Error: %s\n", gb_bprintf_va(fmt, va));
|
||||
gb_printf_err("Syntax Error: %s\n", gb_bprintf_va(fmt, va));
|
||||
}
|
||||
|
||||
gb_mutex_unlock(&global_error_collector.mutex);
|
||||
@@ -401,15 +401,15 @@ void tokenizer_err(Tokenizer *t, char *msg, ...) {
|
||||
if (column < 1) {
|
||||
column = 1;
|
||||
}
|
||||
|
||||
gb_printf_err("%.*s(%td:%td) Syntax error: ", LIT(t->fullpath), t->line_count, column);
|
||||
Token token = {};
|
||||
token.pos.file = t->fullpath;
|
||||
token.pos.line = t->line_count;
|
||||
token.pos.column = column;
|
||||
|
||||
va_start(va, msg);
|
||||
gb_printf_err_va(msg, va);
|
||||
syntax_error_va(token, msg, va);
|
||||
va_end(va);
|
||||
|
||||
gb_printf_err("\n");
|
||||
|
||||
t->error_count++;
|
||||
}
|
||||
|
||||
@@ -577,14 +577,32 @@ Token scan_number_to_token(Tokenizer *t, bool seen_decimal_point) {
|
||||
if (t->curr - prev <= 2) {
|
||||
token.kind = Token_Invalid;
|
||||
}
|
||||
} /* else if (t->curr_rune == 'h') { // Hexadecimal Float
|
||||
} else if (t->curr_rune == 'h') { // Hexadecimal Float
|
||||
token.kind = Token_Float;
|
||||
advance_to_next_rune(t);
|
||||
scan_mantissa(t, 16);
|
||||
if (t->curr - prev <= 2) {
|
||||
token.kind = Token_Invalid;
|
||||
} else {
|
||||
u8 *start = prev+2;
|
||||
isize n = t->curr - start;
|
||||
isize digit_count = 0;
|
||||
for (isize i = 0; i < n; i++) {
|
||||
if (start[i] != '_') {
|
||||
digit_count += 1;
|
||||
}
|
||||
}
|
||||
switch (digit_count) {
|
||||
case 8:
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
tokenizer_err(t, "Invalid hexadecimal float, expected 8 or 16 digits, got %td", digit_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} */ else {
|
||||
|
||||
} else {
|
||||
seen_decimal_point = false;
|
||||
scan_mantissa(t, 10);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user