authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-20 00:33:05-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-20 01:04:51-04:00
log09bd4a9a8693485fa87a5f62af90540ca8ce9d47
tree295ed2543f174d014dd85acd95181e615d2f24f8
parentc73a0c92d0b8736b0473b10bd5deacf62e0753d8

compile-time f32, f64 operations are now correctly lossy

previously we used the bigfloat abstraction to do all compile-time float math. but runtime code and comptime code are supposed to get the same result. so now if you add a f32 to a f32 at compile time it does it with f32 math instead of the bigfloat. float literals still get the bigfloat math. closes #424

14 files changed, 808 insertions(+), 110 deletions(-)

src/all_types.hpp+3
......@@ -225,6 +225,9 @@ struct ConstExprValue {
225225 // populated if special == ConstValSpecialStatic
226226 BigInt x_bigint;
227227 BigFloat x_bigfloat;
228 float x_f32;
229 double x_f64;
230 __float128 x_f128;
228231 bool x_bool;
229232 ConstFn x_fn;
230233 ConstBoundFnValue x_bound_fn;
src/analyze.cpp+82-5
......@@ -13,6 +13,7 @@
1313#include "ir_print.hpp"
1414#include "os.hpp"
1515#include "parser.hpp"
16#include "quadmath.hpp"
1617#include "zig_llvm.hpp"
1718
1819static const size_t default_backward_branch_quota = 1000;
......@@ -3273,8 +3274,35 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
32733274 return result;
32743275 }
32753276 case TypeTableEntryIdFloat:
3277 switch (const_val->type->data.floating.bit_count) {
3278 case 32:
3279 {
3280 uint32_t result;
3281 memcpy(&result, &const_val->data.x_f32, 4);
3282 return result ^ 4084870010;
3283 }
3284 case 64:
3285 {
3286 uint32_t ints[2];
3287 memcpy(&ints[0], &const_val->data.x_f64, 8);
3288 return ints[0] ^ ints[1] ^ 0x22ed43c6;
3289 }
3290 case 128:
3291 {
3292 uint32_t ints[4];
3293 memcpy(&ints[0], &const_val->data.x_f128, 16);
3294 return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xb5ffef27;
3295 }
3296 default:
3297 zig_unreachable();
3298 }
32763299 case TypeTableEntryIdNumLitFloat:
3277 return (uint32_t)(const_val->data.x_bigfloat.value * (uint32_t)UINT32_MAX);
3300 {
3301 __float128 f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
3302 uint32_t ints[4];
3303 memcpy(&ints[0], &f128, 16);
3304 return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xed8b3dfb;
3305 }
32783306 case TypeTableEntryIdArgTuple:
32793307 return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +
32803308 (uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768;
......@@ -3575,7 +3603,25 @@ ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {
35753603void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) {
35763604 const_val->special = ConstValSpecialStatic;
35773605 const_val->type = type;
3578 bigfloat_init_float(&const_val->data.x_bigfloat, value);
3606 if (type->id == TypeTableEntryIdNumLitFloat) {
3607 bigfloat_init_64(&const_val->data.x_bigfloat, value);
3608 } else if (type->id == TypeTableEntryIdFloat) {
3609 switch (type->data.floating.bit_count) {
3610 case 32:
3611 const_val->data.x_f32 = value;
3612 break;
3613 case 64:
3614 const_val->data.x_f64 = value;
3615 break;
3616 case 128:
3617 // if we need this, we should add a function that accepts a __float128 param
3618 zig_unreachable();
3619 default:
3620 zig_unreachable();
3621 }
3622 } else {
3623 zig_unreachable();
3624 }
35793625}
35803626
35813627ConstExprValue *create_const_float(TypeTableEntry *type, double value) {
......@@ -3816,6 +3862,17 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
38163862 case TypeTableEntryIdBool:
38173863 return a->data.x_bool == b->data.x_bool;
38183864 case TypeTableEntryIdFloat:
3865 assert(a->type->data.floating.bit_count == b->type->data.floating.bit_count);
3866 switch (a->type->data.floating.bit_count) {
3867 case 32:
3868 return a->data.x_f32 == b->data.x_f32;
3869 case 64:
3870 return a->data.x_f64 == b->data.x_f64;
3871 case 128:
3872 return a->data.x_f128 == b->data.x_f128;
3873 default:
3874 zig_unreachable();
3875 }
38193876 case TypeTableEntryIdNumLitFloat:
38203877 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;
38213878 case TypeTableEntryIdInt:
......@@ -3984,12 +4041,32 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
39844041 buf_appendf(buf, "{}");
39854042 return;
39864043 case TypeTableEntryIdNumLitFloat:
3987 case TypeTableEntryIdFloat:
3988 bigfloat_write_buf(buf, &const_val->data.x_bigfloat);
4044 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);
39894045 return;
4046 case TypeTableEntryIdFloat:
4047 switch (type_entry->data.floating.bit_count) {
4048 case 32:
4049 buf_appendf(buf, "%f", const_val->data.x_f32);
4050 return;
4051 case 64:
4052 buf_appendf(buf, "%f", const_val->data.x_f64);
4053 return;
4054 case 128:
4055 {
4056 const size_t extra_len = 100;
4057 size_t old_len = buf_len(buf);
4058 buf_resize(buf, old_len + extra_len);
4059 int len = quadmath_snprintf(buf_ptr(buf) + old_len, extra_len, "%Qf", const_val->data.x_f128);
4060 assert(len > 0);
4061 buf_resize(buf, old_len + len);
4062 return;
4063 }
4064 default:
4065 zig_unreachable();
4066 }
39904067 case TypeTableEntryIdNumLitInt:
39914068 case TypeTableEntryIdInt:
3992 bigint_write_buf(buf, &const_val->data.x_bigint, 10);
4069 bigint_append_buf(buf, &const_val->data.x_bigint, 10);
39934070 return;
39944071 case TypeTableEntryIdMetaType:
39954072 buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name));
src/ast_render.cpp+2-2
......@@ -540,7 +540,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
540540 {
541541 Buf rendered_buf = BUF_INIT;
542542 buf_resize(&rendered_buf, 0);
543 bigfloat_write_buf(&rendered_buf, node->data.float_literal.bigfloat);
543 bigfloat_append_buf(&rendered_buf, node->data.float_literal.bigfloat);
544544 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));
545545 }
546546 break;
......@@ -548,7 +548,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
548548 {
549549 Buf rendered_buf = BUF_INIT;
550550 buf_resize(&rendered_buf, 0);
551 bigint_write_buf(&rendered_buf, node->data.int_literal.bigint, 10);
551 bigint_append_buf(&rendered_buf, node->data.int_literal.bigint, 10);
552552 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));
553553 }
554554 break;
src/bigfloat.cpp+18-43
......@@ -8,19 +8,19 @@
88#include "bigfloat.hpp"
99#include "bigint.hpp"
1010#include "buffer.hpp"
11#include "quadmath.hpp"
1112#include <math.h>
1213#include <errno.h>
1314
14extern "C" {
15 __float128 fmodq(__float128 a, __float128 b);
16 __float128 ceilq(__float128 a);
17 __float128 floorq(__float128 a);
18 __float128 strtoflt128 (const char *s, char **sp);
19 int quadmath_snprintf (char *s, size_t size, const char *format, ...);
15void bigfloat_init_128(BigFloat *dest, __float128 x) {
16 dest->value = x;
2017}
2118
19void bigfloat_init_32(BigFloat *dest, float x) {
20 dest->value = x;
21}
2222
23void bigfloat_init_float(BigFloat *dest, __float128 x) {
23void bigfloat_init_64(BigFloat *dest, double x) {
2424 dest->value = x;
2525}
2626
......@@ -104,11 +104,13 @@ void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
104104 dest->value = fmodq(fmodq(op1->value, op2->value) + op2->value, op2->value);
105105}
106106
107void bigfloat_write_buf(Buf *buf, const BigFloat *op) {
108 buf_resize(buf, 256);
109 int len = quadmath_snprintf(buf_ptr(buf), buf_len(buf), "%Qf", op->value);
107void bigfloat_append_buf(Buf *buf, const BigFloat *op) {
108 const size_t extra_len = 100;
109 size_t old_len = buf_len(buf);
110 buf_resize(buf, old_len + extra_len);
111 int len = quadmath_snprintf(buf_ptr(buf) + old_len, extra_len, "%Qf", op->value);
110112 assert(len > 0);
111 buf_resize(buf, len);
113 buf_resize(buf, old_len + len);
112114}
113115
114116Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
......@@ -121,42 +123,15 @@ Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
121123 }
122124}
123125
124// TODO this is wrong when compiler running on big endian systems. caught by tests
125void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count, bool is_big_endian) {
126 if (bit_count == 32) {
127 float f32 = op->value;
128 memcpy(buf, &f32, 4);
129 } else if (bit_count == 64) {
130 double f64 = op->value;
131 memcpy(buf, &f64, 8);
132 } else if (bit_count == 128) {
133 __float128 f128 = op->value;
134 memcpy(buf, &f128, 16);
135 } else {
136 zig_unreachable();
137 }
126float bigfloat_to_f32(const BigFloat *bigfloat) {
127 return (float)bigfloat->value;
138128}
139129
140// TODO this is wrong when compiler running on big endian systems. caught by tests
141void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian) {
142 if (bit_count == 32) {
143 float f32;
144 memcpy(&f32, buf, 4);
145 dest->value = f32;
146 } else if (bit_count == 64) {
147 double f64;
148 memcpy(&f64, buf, 8);
149 dest->value = f64;
150 } else if (bit_count == 128) {
151 __float128 f128;
152 memcpy(&f128, buf, 16);
153 dest->value = f128;
154 } else {
155 zig_unreachable();
156 }
130double bigfloat_to_f64(const BigFloat *bigfloat) {
131 return (double)bigfloat->value;
157132}
158133
159double bigfloat_to_double(const BigFloat *bigfloat) {
134__float128 bigfloat_to_f128(const BigFloat *bigfloat) {
160135 return bigfloat->value;
161136}
162137
src/bigfloat.hpp+7-5
......@@ -19,12 +19,16 @@ struct BigFloat {
1919
2020struct Buf;
2121
22void bigfloat_init_float(BigFloat *dest, __float128 x);
22void bigfloat_init_32(BigFloat *dest, float x);
23void bigfloat_init_64(BigFloat *dest, double x);
24void bigfloat_init_128(BigFloat *dest, __float128 x);
2325void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);
2426void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);
2527int bigfloat_init_buf_base10(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len);
2628
27double bigfloat_to_double(const BigFloat *bigfloat);
29float bigfloat_to_f32(const BigFloat *bigfloat);
30double bigfloat_to_f64(const BigFloat *bigfloat);
31__float128 bigfloat_to_f128(const BigFloat *bigfloat);
2832
2933void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
3034void bigfloat_negate(BigFloat *dest, const BigFloat *op);
......@@ -35,10 +39,8 @@ void bigfloat_div_trunc(BigFloat *dest, const BigFloat *op1, const BigFloat *op2
3539void bigfloat_div_floor(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
3640void bigfloat_rem(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
3741void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
38void bigfloat_write_buf(Buf *buf, const BigFloat *op);
42void bigfloat_append_buf(Buf *buf, const BigFloat *op);
3943Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2);
40void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count, bool is_big_endian);
41void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian);
4244
4345
4446// convenience functions
src/bigint.cpp+18-3
......@@ -141,6 +141,21 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {
141141 dest->is_negative = false;
142142}
143143
144void bigint_init_u128(BigInt *dest, unsigned __int128 x) {
145 uint64_t low = (uint64_t)(x & UINT64_MAX);
146 uint64_t high = (uint64_t)(x >> 64);
147
148 if (high == 0) {
149 return bigint_init_unsigned(dest, low);
150 }
151
152 dest->digit_count = 2;
153 dest->data.digits = allocate_nonzero<uint64_t>(2);
154 dest->data.digits[0] = low;
155 dest->data.digits[1] = high;
156 dest->is_negative = false;
157}
158
144159void bigint_init_signed(BigInt *dest, int64_t x) {
145160 if (x >= 0) {
146161 return bigint_init_unsigned(dest, x);
......@@ -167,9 +182,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {
167182
168183void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
169184 if (op->value >= 0) {
170 bigint_init_unsigned(dest, op->value);
185 bigint_init_u128(dest, (unsigned __int128)(op->value));
171186 } else {
172 bigint_init_unsigned(dest, -op->value);
187 bigint_init_u128(dest, (unsigned __int128)(-op->value));
173188 dest->is_negative = true;
174189 }
175190}
......@@ -1023,7 +1038,7 @@ Cmp bigint_cmp(const BigInt *op1, const BigInt *op2) {
10231038 }
10241039}
10251040
1026void bigint_write_buf(Buf *buf, const BigInt *op, uint64_t base) {
1041void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base) {
10271042 if (op->digit_count == 0) {
10281043 buf_append_char(buf, '0');
10291044 return;
src/bigint.hpp+2-1
......@@ -30,6 +30,7 @@ enum Cmp {
3030};
3131
3232void bigint_init_unsigned(BigInt *dest, uint64_t x);
33void bigint_init_u128(BigInt *dest, unsigned __int128 x);
3334void bigint_init_signed(BigInt *dest, int64_t x);
3435void bigint_init_bigint(BigInt *dest, const BigInt *src);
3536void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);
......@@ -76,7 +77,7 @@ void bigint_truncate(BigInt *dest, const BigInt *op, size_t bit_count, bool is_s
7677
7778Cmp bigint_cmp(const BigInt *op1, const BigInt *op2);
7879
79void bigint_write_buf(Buf *buf, const BigInt *op, uint64_t base);
80void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base);
8081
8182size_t bigint_ctz(const BigInt *bi, size_t bit_count);
8283size_t bigint_clz(const BigInt *bi, size_t bit_count);
src/codegen.cpp+22-7
......@@ -1243,10 +1243,6 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
12431243 }
12441244}
12451245
1246static LLVMValueRef bigfloat_to_llvm_const(LLVMTypeRef type_ref, BigFloat *bigfloat) {
1247 return LLVMConstReal(type_ref, bigfloat_to_double(bigfloat));
1248}
1249
12501246static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_math,
12511247 LLVMValueRef val1, LLVMValueRef val2,
12521248 TypeTableEntry *type_entry, DivKind div_kind)
......@@ -3455,7 +3451,23 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
34553451 return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref,
34563452 const_val->data.x_pure_err->value, false);
34573453 case TypeTableEntryIdFloat:
3458 return bigfloat_to_llvm_const(type_entry->type_ref, &const_val->data.x_bigfloat);
3454 switch (type_entry->data.floating.bit_count) {
3455 case 32:
3456 return LLVMConstReal(type_entry->type_ref, const_val->data.x_f32);
3457 case 64:
3458 return LLVMConstReal(type_entry->type_ref, const_val->data.x_f64);
3459 case 128:
3460 {
3461 // TODO make sure this is correct on big endian targets too
3462 uint8_t buf[16];
3463 memcpy(buf, &const_val->data.x_f128, 16);
3464 LLVMValueRef as_int = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2,
3465 (uint64_t*)buf);
3466 return LLVMConstBitCast(as_int, type_entry->type_ref);
3467 }
3468 default:
3469 zig_unreachable();
3470 }
34593471 case TypeTableEntryIdBool:
34603472 if (const_val->data.x_bool) {
34613473 return LLVMConstAllOnes(LLVMInt1Type());
......@@ -3937,8 +3949,11 @@ static void do_code_gen(CodeGen *g) {
39373949 // Generate debug info for it but that's it.
39383950 ConstExprValue *const_val = var->value;
39393951 assert(const_val->special != ConstValSpecialRuntime);
3940 TypeTableEntry *var_type = g->builtin_types.entry_f64;
3941 LLVMValueRef init_val = bigfloat_to_llvm_const(var_type->type_ref, &const_val->data.x_bigfloat);
3952 TypeTableEntry *var_type = g->builtin_types.entry_f128;
3953 ConstExprValue coerced_value;
3954 coerced_value.type = var_type;
3955 coerced_value.data.x_f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
3956 LLVMValueRef init_val = gen_const_val(g, &coerced_value);
39423957 gen_global_var(g, var, init_val, var_type);
39433958 continue;
39443959 }
src/ir.cpp+611-41
......@@ -12,6 +12,7 @@
1212#include "ir_print.hpp"
1313#include "os.hpp"
1414#include "parseh.hpp"
15#include "quadmath.hpp"
1516#include "range_set.hpp"
1617
1718struct IrExecContext {
......@@ -6272,6 +6273,546 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry
62726273 (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt)));
62736274}
62746275
6276static bool float_has_fraction(ConstExprValue *const_val) {
6277 if (const_val->type->id == TypeTableEntryIdNumLitFloat) {
6278 return bigfloat_has_fraction(&const_val->data.x_bigfloat);
6279 } else if (const_val->type->id == TypeTableEntryIdFloat) {
6280 switch (const_val->type->data.floating.bit_count) {
6281 case 32:
6282 return floorf(const_val->data.x_f32) != const_val->data.x_f32;
6283 case 64:
6284 return floor(const_val->data.x_f64) != const_val->data.x_f64;
6285 case 128:
6286 return floorq(const_val->data.x_f128) != const_val->data.x_f128;
6287 default:
6288 zig_unreachable();
6289 }
6290 } else {
6291 zig_unreachable();
6292 }
6293}
6294
6295static void float_append_buf(Buf *buf, ConstExprValue *const_val) {
6296 if (const_val->type->id == TypeTableEntryIdNumLitFloat) {
6297 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);
6298 } else if (const_val->type->id == TypeTableEntryIdFloat) {
6299 switch (const_val->type->data.floating.bit_count) {
6300 case 32:
6301 buf_appendf(buf, "%f", const_val->data.x_f32);
6302 break;
6303 case 64:
6304 buf_appendf(buf, "%f", const_val->data.x_f64);
6305 break;
6306 case 128:
6307 {
6308 const size_t extra_len = 100;
6309 size_t old_len = buf_len(buf);
6310 buf_resize(buf, old_len + extra_len);
6311 int len = quadmath_snprintf(buf_ptr(buf) + old_len, extra_len, "%Qf", const_val->data.x_f128);
6312 assert(len > 0);
6313 buf_resize(buf, old_len + len);
6314 break;
6315 }
6316 default:
6317 zig_unreachable();
6318 }
6319 } else {
6320 zig_unreachable();
6321 }
6322}
6323
6324static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {
6325 if (const_val->type->id == TypeTableEntryIdNumLitFloat) {
6326 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat);
6327 } else if (const_val->type->id == TypeTableEntryIdFloat) {
6328 switch (const_val->type->data.floating.bit_count) {
6329 case 32:
6330 if (const_val->data.x_f32 >= 0) {
6331 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32));
6332 } else {
6333 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32));
6334 bigint->is_negative = true;
6335 }
6336 break;
6337 case 64:
6338 if (const_val->data.x_f64 >= 0) {
6339 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64));
6340 } else {
6341 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64));
6342 bigint->is_negative = true;
6343 }
6344 break;
6345 case 128:
6346 if (const_val->data.x_f128 >= 0) {
6347 bigint_init_u128(bigint, (unsigned __int128)(const_val->data.x_f128));
6348 } else {
6349 bigint_init_u128(bigint, (unsigned __int128)(-const_val->data.x_f128));
6350 bigint->is_negative = true;
6351 }
6352 break;
6353 default:
6354 zig_unreachable();
6355 }
6356 } else {
6357 zig_unreachable();
6358 }
6359}
6360
6361static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {
6362 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {
6363 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat);
6364 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
6365 switch (dest_val->type->data.floating.bit_count) {
6366 case 32:
6367 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat);
6368 break;
6369 case 64:
6370 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat);
6371 break;
6372 case 128:
6373 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat);
6374 break;
6375 default:
6376 zig_unreachable();
6377 }
6378 } else {
6379 zig_unreachable();
6380 }
6381}
6382
6383static void float_init_f32(ConstExprValue *dest_val, float x) {
6384 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {
6385 bigfloat_init_32(&dest_val->data.x_bigfloat, x);
6386 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
6387 switch (dest_val->type->data.floating.bit_count) {
6388 case 32:
6389 dest_val->data.x_f32 = x;
6390 break;
6391 case 64:
6392 dest_val->data.x_f64 = x;
6393 break;
6394 case 128:
6395 dest_val->data.x_f128 = x;
6396 break;
6397 default:
6398 zig_unreachable();
6399 }
6400 } else {
6401 zig_unreachable();
6402 }
6403}
6404
6405static void float_init_f64(ConstExprValue *dest_val, double x) {
6406 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {
6407 bigfloat_init_64(&dest_val->data.x_bigfloat, x);
6408 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
6409 switch (dest_val->type->data.floating.bit_count) {
6410 case 32:
6411 dest_val->data.x_f32 = x;
6412 break;
6413 case 64:
6414 dest_val->data.x_f64 = x;
6415 break;
6416 case 128:
6417 dest_val->data.x_f128 = x;
6418 break;
6419 default:
6420 zig_unreachable();
6421 }
6422 } else {
6423 zig_unreachable();
6424 }
6425}
6426
6427static void float_init_f128(ConstExprValue *dest_val, __float128 x) {
6428 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {
6429 bigfloat_init_128(&dest_val->data.x_bigfloat, x);
6430 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
6431 switch (dest_val->type->data.floating.bit_count) {
6432 case 32:
6433 dest_val->data.x_f32 = x;
6434 break;
6435 case 64:
6436 dest_val->data.x_f64 = x;
6437 break;
6438 case 128:
6439 dest_val->data.x_f128 = x;
6440 break;
6441 default:
6442 zig_unreachable();
6443 }
6444 } else {
6445 zig_unreachable();
6446 }
6447}
6448
6449static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) {
6450 if (src_val->type->id == TypeTableEntryIdNumLitFloat) {
6451 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat);
6452 } else if (src_val->type->id == TypeTableEntryIdFloat) {
6453 switch (src_val->type->data.floating.bit_count) {
6454 case 32:
6455 float_init_f32(dest_val, src_val->data.x_f32);
6456 break;
6457 case 64:
6458 float_init_f64(dest_val, src_val->data.x_f64);
6459 break;
6460 case 128:
6461 float_init_f128(dest_val, src_val->data.x_f128);
6462 break;
6463 default:
6464 zig_unreachable();
6465 }
6466 } else {
6467 zig_unreachable();
6468 }
6469}
6470
6471static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) {
6472 assert(op1->type == op2->type);
6473 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6474 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat);
6475 } else if (op1->type->id == TypeTableEntryIdFloat) {
6476 switch (op1->type->data.floating.bit_count) {
6477 case 32:
6478 if (op1->data.x_f32 > op2->data.x_f32) {
6479 return CmpGT;
6480 } else if (op1->data.x_f32 < op2->data.x_f32) {
6481 return CmpLT;
6482 } else {
6483 return CmpEQ;
6484 }
6485 case 64:
6486 if (op1->data.x_f64 > op2->data.x_f64) {
6487 return CmpGT;
6488 } else if (op1->data.x_f64 < op2->data.x_f64) {
6489 return CmpLT;
6490 } else {
6491 return CmpEQ;
6492 }
6493 case 128:
6494 if (op1->data.x_f128 > op2->data.x_f128) {
6495 return CmpGT;
6496 } else if (op1->data.x_f128 < op2->data.x_f128) {
6497 return CmpLT;
6498 } else {
6499 return CmpEQ;
6500 }
6501 default:
6502 zig_unreachable();
6503 }
6504 } else {
6505 zig_unreachable();
6506 }
6507}
6508
6509static Cmp float_cmp_zero(ConstExprValue *op) {
6510 if (op->type->id == TypeTableEntryIdNumLitFloat) {
6511 return bigfloat_cmp_zero(&op->data.x_bigfloat);
6512 } else if (op->type->id == TypeTableEntryIdFloat) {
6513 switch (op->type->data.floating.bit_count) {
6514 case 32:
6515 if (op->data.x_f32 < 0.0) {
6516 return CmpLT;
6517 } else if (op->data.x_f32 > 0.0) {
6518 return CmpGT;
6519 } else {
6520 return CmpEQ;
6521 }
6522 case 64:
6523 if (op->data.x_f64 < 0.0) {
6524 return CmpLT;
6525 } else if (op->data.x_f64 > 0.0) {
6526 return CmpGT;
6527 } else {
6528 return CmpEQ;
6529 }
6530 case 128:
6531 if (op->data.x_f128 < 0.0) {
6532 return CmpLT;
6533 } else if (op->data.x_f128 > 0.0) {
6534 return CmpGT;
6535 } else {
6536 return CmpEQ;
6537 }
6538 default:
6539 zig_unreachable();
6540 }
6541 } else {
6542 zig_unreachable();
6543 }
6544}
6545
6546static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6547 assert(op1->type == op2->type);
6548 out_val->type = op1->type;
6549 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6550 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6551 } else if (op1->type->id == TypeTableEntryIdFloat) {
6552 switch (op1->type->data.floating.bit_count) {
6553 case 32:
6554 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32;
6555 return;
6556 case 64:
6557 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64;
6558 return;
6559 case 128:
6560 out_val->data.x_f128 = op1->data.x_f128 + op2->data.x_f128;
6561 return;
6562 default:
6563 zig_unreachable();
6564 }
6565 } else {
6566 zig_unreachable();
6567 }
6568}
6569
6570static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6571 assert(op1->type == op2->type);
6572 out_val->type = op1->type;
6573 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6574 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6575 } else if (op1->type->id == TypeTableEntryIdFloat) {
6576 switch (op1->type->data.floating.bit_count) {
6577 case 32:
6578 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32;
6579 return;
6580 case 64:
6581 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64;
6582 return;
6583 case 128:
6584 out_val->data.x_f128 = op1->data.x_f128 - op2->data.x_f128;
6585 return;
6586 default:
6587 zig_unreachable();
6588 }
6589 } else {
6590 zig_unreachable();
6591 }
6592}
6593
6594static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6595 assert(op1->type == op2->type);
6596 out_val->type = op1->type;
6597 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6598 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6599 } else if (op1->type->id == TypeTableEntryIdFloat) {
6600 switch (op1->type->data.floating.bit_count) {
6601 case 32:
6602 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32;
6603 return;
6604 case 64:
6605 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64;
6606 return;
6607 case 128:
6608 out_val->data.x_f128 = op1->data.x_f128 * op2->data.x_f128;
6609 return;
6610 default:
6611 zig_unreachable();
6612 }
6613 } else {
6614 zig_unreachable();
6615 }
6616}
6617
6618static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6619 assert(op1->type == op2->type);
6620 out_val->type = op1->type;
6621 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6622 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6623 } else if (op1->type->id == TypeTableEntryIdFloat) {
6624 switch (op1->type->data.floating.bit_count) {
6625 case 32:
6626 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32;
6627 return;
6628 case 64:
6629 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64;
6630 return;
6631 case 128:
6632 out_val->data.x_f128 = op1->data.x_f128 / op2->data.x_f128;
6633 return;
6634 default:
6635 zig_unreachable();
6636 }
6637 } else {
6638 zig_unreachable();
6639 }
6640}
6641
6642static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6643 assert(op1->type == op2->type);
6644 out_val->type = op1->type;
6645 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6646 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6647 } else if (op1->type->id == TypeTableEntryIdFloat) {
6648 switch (op1->type->data.floating.bit_count) {
6649 case 32:
6650 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32;
6651 if (out_val->data.x_f32 >= 0.0) {
6652 out_val->data.x_f32 = floorf(out_val->data.x_f32);
6653 } else {
6654 out_val->data.x_f32 = ceilf(out_val->data.x_f32);
6655 }
6656 return;
6657 case 64:
6658 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64;
6659 if (out_val->data.x_f64 >= 0.0) {
6660 out_val->data.x_f64 = floor(out_val->data.x_f64);
6661 } else {
6662 out_val->data.x_f64 = ceil(out_val->data.x_f64);
6663 }
6664 return;
6665 case 128:
6666 out_val->data.x_f128 = op1->data.x_f128 / op2->data.x_f128;
6667 if (out_val->data.x_f128 >= 0.0) {
6668 out_val->data.x_f128 = floorq(out_val->data.x_f128);
6669 } else {
6670 out_val->data.x_f128 = ceilq(out_val->data.x_f128);
6671 }
6672 return;
6673 default:
6674 zig_unreachable();
6675 }
6676 } else {
6677 zig_unreachable();
6678 }
6679}
6680
6681static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6682 assert(op1->type == op2->type);
6683 out_val->type = op1->type;
6684 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6685 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6686 } else if (op1->type->id == TypeTableEntryIdFloat) {
6687 switch (op1->type->data.floating.bit_count) {
6688 case 32:
6689 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32);
6690 return;
6691 case 64:
6692 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64);
6693 return;
6694 case 128:
6695 out_val->data.x_f128 = floorq(op1->data.x_f128 / op2->data.x_f128);
6696 return;
6697 default:
6698 zig_unreachable();
6699 }
6700 } else {
6701 zig_unreachable();
6702 }
6703}
6704
6705static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6706 assert(op1->type == op2->type);
6707 out_val->type = op1->type;
6708 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6709 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6710 } else if (op1->type->id == TypeTableEntryIdFloat) {
6711 switch (op1->type->data.floating.bit_count) {
6712 case 32:
6713 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32);
6714 return;
6715 case 64:
6716 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64);
6717 return;
6718 case 128:
6719 out_val->data.x_f128 = fmodq(op1->data.x_f128, op2->data.x_f128);
6720 return;
6721 default:
6722 zig_unreachable();
6723 }
6724 } else {
6725 zig_unreachable();
6726 }
6727}
6728
6729static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
6730 assert(op1->type == op2->type);
6731 out_val->type = op1->type;
6732 if (op1->type->id == TypeTableEntryIdNumLitFloat) {
6733 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
6734 } else if (op1->type->id == TypeTableEntryIdFloat) {
6735 switch (op1->type->data.floating.bit_count) {
6736 case 32:
6737 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32);
6738 return;
6739 case 64:
6740 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64);
6741 return;
6742 case 128:
6743 out_val->data.x_f128 = fmodq(fmodq(op1->data.x_f128, op2->data.x_f128) + op2->data.x_f128, op2->data.x_f128);
6744 return;
6745 default:
6746 zig_unreachable();
6747 }
6748 } else {
6749 zig_unreachable();
6750 }
6751}
6752
6753static void float_negate(ConstExprValue *out_val, ConstExprValue *op) {
6754 out_val->type = op->type;
6755 if (op->type->id == TypeTableEntryIdNumLitFloat) {
6756 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat);
6757 } else if (op->type->id == TypeTableEntryIdFloat) {
6758 switch (op->type->data.floating.bit_count) {
6759 case 32:
6760 out_val->data.x_f32 = -op->data.x_f32;
6761 return;
6762 case 64:
6763 out_val->data.x_f64 = -op->data.x_f64;
6764 return;
6765 case 128:
6766 out_val->data.x_f128 = -op->data.x_f128;
6767 return;
6768 default:
6769 zig_unreachable();
6770 }
6771 } else {
6772 zig_unreachable();
6773 }
6774}
6775
6776void float_write_ieee597(ConstExprValue *op, uint8_t *buf, bool is_big_endian) {
6777 if (op->type->id == TypeTableEntryIdFloat) {
6778 switch (op->type->data.floating.bit_count) {
6779 case 32:
6780 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian
6781 return;
6782 case 64:
6783 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian
6784 return;
6785 case 128:
6786 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian
6787 return;
6788 default:
6789 zig_unreachable();
6790 }
6791 } else {
6792 zig_unreachable();
6793 }
6794}
6795
6796void float_read_ieee597(ConstExprValue *val, uint8_t *buf, bool is_big_endian) {
6797 if (val->type->id == TypeTableEntryIdFloat) {
6798 switch (val->type->data.floating.bit_count) {
6799 case 32:
6800 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian
6801 return;
6802 case 64:
6803 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian
6804 return;
6805 case 128:
6806 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian
6807 return;
6808 default:
6809 zig_unreachable();
6810 }
6811 } else {
6812 zig_unreachable();
6813 }
6814}
6815
62756816static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type,
62766817 bool explicit_cast)
62776818{
......@@ -6314,9 +6855,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
63146855 if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) &&
63156856 const_val_is_float)
63166857 {
6317 if (bigfloat_has_fraction(&const_val->data.x_bigfloat)) {
6858 if (float_has_fraction(const_val)) {
63186859 Buf *val_buf = buf_alloc();
6319 bigfloat_write_buf(val_buf, &const_val->data.x_bigfloat);
6860 float_append_buf(val_buf, const_val);
63206861
63216862 ir_add_error(ira, instruction,
63226863 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'",
......@@ -6324,11 +6865,11 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
63246865 buf_ptr(&other_type->name)));
63256866 return false;
63266867 } else {
6327 BigInt bigint;
6328 bigint_init_bigfloat(&bigint, &const_val->data.x_bigfloat);
63296868 if (other_type->id == TypeTableEntryIdNumLitInt) {
63306869 return true;
63316870 } else {
6871 BigInt bigint;
6872 float_init_bigint(&bigint, const_val);
63326873 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count,
63336874 other_type->data.integral.is_signed))
63346875 {
......@@ -6342,10 +6883,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
63426883 Buf *val_buf = buf_alloc();
63436884 if (const_val_is_float) {
63446885 num_lit_str = "float";
6345 bigfloat_write_buf(val_buf, &const_val->data.x_bigfloat);
6886 float_append_buf(val_buf, const_val);
63466887 } else {
63476888 num_lit_str = "integer";
6348 bigint_write_buf(val_buf, &const_val->data.x_bigint, 10);
6889 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10);
63496890 }
63506891
63516892 ir_add_error(ira, instruction,
......@@ -6767,7 +7308,20 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
67677308 }
67687309 case CastOpNumLitToConcrete:
67697310 if (other_val->type->id == TypeTableEntryIdNumLitFloat) {
6770 bigfloat_init_bigfloat(&const_val->data.x_bigfloat, &other_val->data.x_bigfloat);
7311 assert(new_type->id == TypeTableEntryIdFloat);
7312 switch (new_type->data.floating.bit_count) {
7313 case 32:
7314 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat);
7315 break;
7316 case 64:
7317 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat);
7318 break;
7319 case 128:
7320 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat);
7321 break;
7322 default:
7323 zig_unreachable();
7324 }
67717325 } else if (other_val->type->id == TypeTableEntryIdNumLitInt) {
67727326 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint);
67737327 } else {
......@@ -6780,11 +7334,29 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
67807334 // can't do it
67817335 break;
67827336 case CastOpIntToFloat:
6783 bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint);
6784 const_val->special = ConstValSpecialStatic;
6785 break;
7337 {
7338 assert(new_type->id == TypeTableEntryIdFloat);
7339
7340 BigFloat bigfloat;
7341 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint);
7342 switch (new_type->data.floating.bit_count) {
7343 case 32:
7344 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat);
7345 break;
7346 case 64:
7347 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat);
7348 break;
7349 case 128:
7350 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat);
7351 break;
7352 default:
7353 zig_unreachable();
7354 }
7355 const_val->special = ConstValSpecialStatic;
7356 break;
7357 }
67867358 case CastOpFloatToInt:
6787 bigint_init_bigfloat(&const_val->data.x_bigint, &other_val->data.x_bigfloat);
7359 float_init_bigint(&const_val->data.x_bigint, other_val);
67887360 const_val->special = ConstValSpecialStatic;
67897361 break;
67907362 case CastOpBoolToInt:
......@@ -7387,12 +7959,12 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
73877959 }
73887960 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
73897961 source_instr->source_node, wanted_type);
7962 result->value.type = wanted_type;
73907963 if (wanted_type->id == TypeTableEntryIdInt) {
73917964 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);
73927965 } else {
7393 bigfloat_init_bigfloat(&result->value.data.x_bigfloat, &val->data.x_bigfloat);
7966 float_init_float(&result->value, val);
73947967 }
7395 result->value.type = wanted_type;
73967968 return result;
73977969 }
73987970
......@@ -7415,7 +7987,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour
74157987 bigint_init_unsigned(&enum_member_count, wanted_type->data.enumeration.src_field_count);
74167988 if (bigint_cmp(&val->data.x_bigint, &enum_member_count) != CmpLT) {
74177989 Buf *val_buf = buf_alloc();
7418 bigint_write_buf(val_buf, &val->data.x_bigint, 10);
7990 bigint_append_buf(val_buf, &val->data.x_bigint, 10);
74197991 ir_add_error(ira, source_instr,
74207992 buf_sprintf("integer value %s too big for enum '%s' which has %" PRIu32 " fields",
74217993 buf_ptr(val_buf), buf_ptr(&wanted_type->name), wanted_type->data.enumeration.src_field_count));
......@@ -7444,7 +8016,7 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction
74448016 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
74458017 source_instr->source_node, wanted_type);
74468018 if (wanted_type->id == TypeTableEntryIdNumLitFloat) {
7447 bigfloat_init_bigfloat(&result->value.data.x_bigfloat, &val->data.x_bigfloat);
8019 float_init_float(&result->value, val);
74488020 } else if (wanted_type->id == TypeTableEntryIdNumLitInt) {
74498021 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);
74508022 } else {
......@@ -7469,7 +8041,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc
74698041 bigint_init_unsigned(&err_count, ira->codegen->error_decls.length);
74708042 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) {
74718043 Buf *val_buf = buf_alloc();
7472 bigint_write_buf(val_buf, &val->data.x_bigint, 10);
8044 bigint_append_buf(val_buf, &val->data.x_bigint, 10);
74738045 ir_add_error(ira, source_instr,
74748046 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf)));
74758047 return ira->codegen->invalid_instruction;
......@@ -8304,7 +8876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
83048876 if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) {
83058877 bool answer;
83068878 if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) {
8307 Cmp cmp_result = bigfloat_cmp(&op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
8879 Cmp cmp_result = float_cmp(op1_val, op2_val);
83088880 answer = resolve_cmp_op_id(op_id, cmp_result);
83098881 } else if (resolved_type->id == TypeTableEntryIdNumLitInt || resolved_type->id == TypeTableEntryIdInt) {
83108882 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
......@@ -8379,7 +8951,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
83798951 {
83808952 is_int = false;
83818953 is_float = true;
8382 op2_zcmp = bigfloat_cmp_zero(&op2_val->data.x_bigfloat);
8954 op2_zcmp = float_cmp_zero(op2_val);
83838955 } else {
83848956 zig_unreachable();
83858957 }
......@@ -8447,7 +9019,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
84479019 if (is_int) {
84489020 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
84499021 } else {
8450 bigfloat_add(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9022 float_add(out_val, op1_val, op2_val);
84519023 }
84529024 break;
84539025 case IrBinOpAddWrap:
......@@ -8459,7 +9031,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
84599031 if (is_int) {
84609032 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
84619033 } else {
8462 bigfloat_sub(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9034 float_sub(out_val, op1_val, op2_val);
84639035 }
84649036 break;
84659037 case IrBinOpSubWrap:
......@@ -8471,7 +9043,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
84719043 if (is_int) {
84729044 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
84739045 } else {
8474 bigfloat_mul(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9046 float_mul(out_val, op1_val, op2_val);
84759047 }
84769048 break;
84779049 case IrBinOpMultWrap:
......@@ -8481,20 +9053,20 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
84819053 break;
84829054 case IrBinOpDivUnspecified:
84839055 assert(is_float);
8484 bigfloat_div(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9056 float_div(out_val, op1_val, op2_val);
84859057 break;
84869058 case IrBinOpDivTrunc:
84879059 if (is_int) {
84889060 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
84899061 } else {
8490 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9062 float_div_trunc(out_val, op1_val, op2_val);
84919063 }
84929064 break;
84939065 case IrBinOpDivFloor:
84949066 if (is_int) {
84959067 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
84969068 } else {
8497 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9069 float_div_floor(out_val, op1_val, op2_val);
84989070 }
84999071 break;
85009072 case IrBinOpDivExact:
......@@ -8506,10 +9078,10 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
85069078 return ErrorExactDivRemainder;
85079079 }
85089080 } else {
8509 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
8510 BigFloat remainder;
8511 bigfloat_rem(&remainder, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
8512 if (bigfloat_cmp_zero(&remainder) != CmpEQ) {
9081 float_div_trunc(out_val, op1_val, op2_val);
9082 ConstExprValue remainder;
9083 float_rem(&remainder, op1_val, op2_val);
9084 if (float_cmp_zero(&remainder) != CmpEQ) {
85139085 return ErrorExactDivRemainder;
85149086 }
85159087 }
......@@ -8518,14 +9090,14 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
85189090 if (is_int) {
85199091 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
85209092 } else {
8521 bigfloat_rem(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9093 float_rem(out_val, op1_val, op2_val);
85229094 }
85239095 break;
85249096 case IrBinOpRemMod:
85259097 if (is_int) {
85269098 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
85279099 } else {
8528 bigfloat_mod(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);
9100 float_mod(out_val, op1_val, op2_val);
85299101 }
85309102 break;
85319103 }
......@@ -8678,16 +9250,16 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
86789250 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ;
86799251 }
86809252 } else {
8681 if (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) == CmpEQ) {
9253 if (float_cmp_zero(&op2->value) == CmpEQ) {
86829254 // the division by zero error will be caught later, but we don't
86839255 // have a remainder function ambiguity problem
86849256 ok = true;
86859257 } else {
8686 BigFloat rem_result;
8687 BigFloat mod_result;
8688 bigfloat_rem(&rem_result, &op1->value.data.x_bigfloat, &op2->value.data.x_bigfloat);
8689 bigfloat_mod(&mod_result, &op1->value.data.x_bigfloat, &op2->value.data.x_bigfloat);
8690 ok = bigfloat_cmp(&rem_result, &mod_result) == CmpEQ;
9258 ConstExprValue rem_result;
9259 ConstExprValue mod_result;
9260 float_rem(&rem_result, &op1->value, &op2->value);
9261 float_mod(&mod_result, &op1->value, &op2->value);
9262 ok = float_cmp(&rem_result, &mod_result) == CmpEQ;
86919263 }
86929264 }
86939265 }
......@@ -9835,7 +10407,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un
983510407
983610408 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
983710409 if (is_float) {
9838 bigfloat_negate(&out_val->data.x_bigfloat, &target_const_val->data.x_bigfloat);
10410 float_negate(out_val, target_const_val);
983910411 } else if (is_wrap_op) {
984010412 bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint,
984110413 expr_type->data.integral.bit_count);
......@@ -13780,8 +14352,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1378014352 codegen->is_big_endian);
1378114353 return;
1378214354 case TypeTableEntryIdFloat:
13783 bigfloat_write_ieee597(&val->data.x_bigfloat, buf, val->type->data.floating.bit_count,
13784 codegen->is_big_endian);
14355 float_write_ieee597(val, buf, codegen->is_big_endian);
1378514356 return;
1378614357 case TypeTableEntryIdPointer:
1378714358 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
......@@ -13841,8 +14412,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1384114412 codegen->is_big_endian, val->type->data.integral.is_signed);
1384214413 return;
1384314414 case TypeTableEntryIdFloat:
13844 bigfloat_read_ieee597(&val->data.x_bigfloat, buf, val->type->data.floating.bit_count,
13845 codegen->is_big_endian);
14415 float_read_ieee597(val, buf, codegen->is_big_endian);
1384614416 return;
1384714417 case TypeTableEntryIdPointer:
1384814418 {
src/quadmath.hpp created+19
......@@ -0,0 +1,19 @@
1/*
2 * Copyright (c) 2017 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_QUADMATH_HPP
9#define ZIG_QUADMATH_HPP
10
11extern "C" {
12 __float128 fmodq(__float128 a, __float128 b);
13 __float128 ceilq(__float128 a);
14 __float128 floorq(__float128 a);
15 __float128 strtoflt128 (const char *s, char **sp);
16 int quadmath_snprintf (char *s, size_t size, const char *format, ...);
17}
18
19#endif
src/tokenizer.cpp+2-2
......@@ -257,7 +257,7 @@ static void set_token_id(Tokenize *t, Token *token, TokenId id) {
257257 if (id == TokenIdIntLiteral) {
258258 bigint_init_unsigned(&token->data.int_lit.bigint, 0);
259259 } else if (id == TokenIdFloatLiteral) {
260 bigfloat_init_float(&token->data.float_lit.bigfloat, 0.0);
260 bigfloat_init_32(&token->data.float_lit.bigfloat, 0.0f);
261261 token->data.float_lit.overflow = false;
262262 } else if (id == TokenIdStringLiteral || id == TokenIdSymbol) {
263263 memset(&token->data.str_lit.str, 0, sizeof(Buf));
......@@ -345,7 +345,7 @@ static void end_float_token(Tokenize *t) {
345345 uint64_t double_bits = (exponent_bits << 52) | significand_bits;
346346 double dbl_value;
347347 safe_memcpy(&dbl_value, (double *)&double_bits, 1);
348 bigfloat_init_float(&t->cur_tok->data.float_lit.bigfloat, dbl_value);
348 bigfloat_init_64(&t->cur_tok->data.float_lit.bigfloat, dbl_value);
349349}
350350
351351static void end_token(Tokenize *t) {
std/math/atan2.zig+1-1
......@@ -24,7 +24,7 @@ const assert = @import("../debug.zig").assert;
2424pub const atan2 = atan2_workaround;
2525
2626// TODO issue #393
27pub fn atan2_workaround(comptime T: type, x: T, y: T) -> T {
27fn atan2_workaround(comptime T: type, x: T, y: T) -> T {
2828 switch (T) {
2929 f32 => @inlineCall(atan2_32, x, y),
3030 f64 => @inlineCall(atan2_64, x, y),
std/math/sin.zig+1
......@@ -147,6 +147,7 @@ fn sin64(x_: f64) -> f64 {
147147test "math.sin" {
148148 assert(sin(f32(0.0)) == sin32(0.0));
149149 assert(sin(f64(0.0)) == sin64(0.0));
150 assert(comptime {math.sin(f64(2))} == math.sin(f64(2)));
150151}
151152
152153test "math.sin32" {
test/cases/eval.zig+20
......@@ -355,3 +355,23 @@ test "@setEvalBranchQuota" {
355355 assert(sum == 500500);
356356 }
357357}
358
359test "float literal at compile time not lossy" {
360 assert(16777216.0 + 1.0 == 16777217.0);
361 assert(9007199254740992.0 + 1.0 == 9007199254740993.0);
362}
363
364test "f32 at compile time is lossy" {
365 assert(f32(1 << 24) + 1 == 1 << 24);
366}
367
368test "f64 at compile time is lossy" {
369 assert(f64(1 << 53) + 1 == 1 << 53);
370}
371
372test "f128 at compile time is lossy" {
373 assert(f128(10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
374}
375
376// TODO need a better implementation of bigfloat_init_bigint
377// assert(f128(1 << 113) == 10384593717069655257060992658440192);