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 {...@@ -225,6 +225,9 @@ struct ConstExprValue {
225 // populated if special == ConstValSpecialStatic225 // populated if special == ConstValSpecialStatic
226 BigInt x_bigint;226 BigInt x_bigint;
227 BigFloat x_bigfloat;227 BigFloat x_bigfloat;
228 float x_f32;
229 double x_f64;
230 __float128 x_f128;
228 bool x_bool;231 bool x_bool;
229 ConstFn x_fn;232 ConstFn x_fn;
230 ConstBoundFnValue x_bound_fn;233 ConstBoundFnValue x_bound_fn;
src/analyze.cpp+82-5
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13#include "ir_print.hpp"13#include "ir_print.hpp"
14#include "os.hpp"14#include "os.hpp"
15#include "parser.hpp"15#include "parser.hpp"
16#include "quadmath.hpp"
16#include "zig_llvm.hpp"17#include "zig_llvm.hpp"
1718
18static const size_t default_backward_branch_quota = 1000;19static const size_t default_backward_branch_quota = 1000;
...@@ -3273,8 +3274,35 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -3273,8 +3274,35 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
3273 return result;3274 return result;
3274 }3275 }
3275 case TypeTableEntryIdFloat:3276 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 }
3276 case TypeTableEntryIdNumLitFloat:3299 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 }
3278 case TypeTableEntryIdArgTuple:3306 case TypeTableEntryIdArgTuple:
3279 return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +3307 return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +
3280 (uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768;3308 (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) {...@@ -3575,7 +3603,25 @@ ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {
3575void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) {3603void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) {
3576 const_val->special = ConstValSpecialStatic;3604 const_val->special = ConstValSpecialStatic;
3577 const_val->type = type;3605 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 }
3579}3625}
35803626
3581ConstExprValue *create_const_float(TypeTableEntry *type, double value) {3627ConstExprValue *create_const_float(TypeTableEntry *type, double value) {
...@@ -3816,6 +3862,17 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -3816,6 +3862,17 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
3816 case TypeTableEntryIdBool:3862 case TypeTableEntryIdBool:
3817 return a->data.x_bool == b->data.x_bool;3863 return a->data.x_bool == b->data.x_bool;
3818 case TypeTableEntryIdFloat:3864 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 }
3819 case TypeTableEntryIdNumLitFloat:3876 case TypeTableEntryIdNumLitFloat:
3820 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;3877 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;
3821 case TypeTableEntryIdInt:3878 case TypeTableEntryIdInt:
...@@ -3984,12 +4041,32 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -3984,12 +4041,32 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
3984 buf_appendf(buf, "{}");4041 buf_appendf(buf, "{}");
3985 return;4042 return;
3986 case TypeTableEntryIdNumLitFloat:4043 case TypeTableEntryIdNumLitFloat:
3987 case TypeTableEntryIdFloat:4044 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);
3988 bigfloat_write_buf(buf, &const_val->data.x_bigfloat);
3989 return;4045 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 }
3990 case TypeTableEntryIdNumLitInt:4067 case TypeTableEntryIdNumLitInt:
3991 case TypeTableEntryIdInt:4068 case TypeTableEntryIdInt:
3992 bigint_write_buf(buf, &const_val->data.x_bigint, 10);4069 bigint_append_buf(buf, &const_val->data.x_bigint, 10);
3993 return;4070 return;
3994 case TypeTableEntryIdMetaType:4071 case TypeTableEntryIdMetaType:
3995 buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name));4072 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) {...@@ -540,7 +540,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
540 {540 {
541 Buf rendered_buf = BUF_INIT;541 Buf rendered_buf = BUF_INIT;
542 buf_resize(&rendered_buf, 0);542 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);
544 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));544 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));
545 }545 }
546 break;546 break;
...@@ -548,7 +548,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -548,7 +548,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
548 {548 {
549 Buf rendered_buf = BUF_INIT;549 Buf rendered_buf = BUF_INIT;
550 buf_resize(&rendered_buf, 0);550 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);
552 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));552 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));
553 }553 }
554 break;554 break;
src/bigfloat.cpp+18-43
...@@ -8,19 +8,19 @@...@@ -8,19 +8,19 @@
8#include "bigfloat.hpp"8#include "bigfloat.hpp"
9#include "bigint.hpp"9#include "bigint.hpp"
10#include "buffer.hpp"10#include "buffer.hpp"
11#include "quadmath.hpp"
11#include <math.h>12#include <math.h>
12#include <errno.h>13#include <errno.h>
1314
14extern "C" {15void bigfloat_init_128(BigFloat *dest, __float128 x) {
15 __float128 fmodq(__float128 a, __float128 b);16 dest->value = x;
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, ...);
20}17}
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) {
24 dest->value = x;24 dest->value = x;
25}25}
2626
...@@ -104,11 +104,13 @@ void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {...@@ -104,11 +104,13 @@ void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
104 dest->value = fmodq(fmodq(op1->value, op2->value) + op2->value, op2->value);104 dest->value = fmodq(fmodq(op1->value, op2->value) + op2->value, op2->value);
105}105}
106106
107void bigfloat_write_buf(Buf *buf, const BigFloat *op) {107void bigfloat_append_buf(Buf *buf, const BigFloat *op) {
108 buf_resize(buf, 256);108 const size_t extra_len = 100;
109 int len = quadmath_snprintf(buf_ptr(buf), buf_len(buf), "%Qf", op->value);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);
110 assert(len > 0);112 assert(len > 0);
111 buf_resize(buf, len);113 buf_resize(buf, old_len + len);
112}114}
113115
114Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {116Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
...@@ -121,42 +123,15 @@ Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {...@@ -121,42 +123,15 @@ Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
121 }123 }
122}124}
123125
124// TODO this is wrong when compiler running on big endian systems. caught by tests126float bigfloat_to_f32(const BigFloat *bigfloat) {
125void bigfloat_write_ieee597(const BigFloat *op, uint8_t *buf, size_t bit_count, bool is_big_endian) {127 return (float)bigfloat->value;
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 }
138}128}
139129
140// TODO this is wrong when compiler running on big endian systems. caught by tests130double bigfloat_to_f64(const BigFloat *bigfloat) {
141void bigfloat_read_ieee597(BigFloat *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian) {131 return (double)bigfloat->value;
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 }
157}132}
158133
159double bigfloat_to_double(const BigFloat *bigfloat) {134__float128 bigfloat_to_f128(const BigFloat *bigfloat) {
160 return bigfloat->value;135 return bigfloat->value;
161}136}
162137
src/bigfloat.hpp+7-5
...@@ -19,12 +19,16 @@ struct BigFloat {...@@ -19,12 +19,16 @@ struct BigFloat {
1919
20struct Buf;20struct 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);
23void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);25void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);
24void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);26void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);
25int bigfloat_init_buf_base10(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len);27int 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
29void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);33void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
30void bigfloat_negate(BigFloat *dest, const BigFloat *op);34void bigfloat_negate(BigFloat *dest, const BigFloat *op);
...@@ -35,10 +39,8 @@ void bigfloat_div_trunc(BigFloat *dest, const BigFloat *op1, const BigFloat *op2...@@ -35,10 +39,8 @@ void bigfloat_div_trunc(BigFloat *dest, const BigFloat *op1, const BigFloat *op2
35void bigfloat_div_floor(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);39void bigfloat_div_floor(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
36void bigfloat_rem(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);40void bigfloat_rem(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);
37void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2);41void 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);
39Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2);43Cmp 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
44// convenience functions46// convenience functions
src/bigint.cpp+18-3
...@@ -141,6 +141,21 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {...@@ -141,6 +141,21 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {
141 dest->is_negative = false;141 dest->is_negative = false;
142}142}
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
144void bigint_init_signed(BigInt *dest, int64_t x) {159void bigint_init_signed(BigInt *dest, int64_t x) {
145 if (x >= 0) {160 if (x >= 0) {
146 return bigint_init_unsigned(dest, x);161 return bigint_init_unsigned(dest, x);
...@@ -167,9 +182,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {...@@ -167,9 +182,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {
167182
168void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {183void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
169 if (op->value >= 0) {184 if (op->value >= 0) {
170 bigint_init_unsigned(dest, op->value);185 bigint_init_u128(dest, (unsigned __int128)(op->value));
171 } else {186 } else {
172 bigint_init_unsigned(dest, -op->value);187 bigint_init_u128(dest, (unsigned __int128)(-op->value));
173 dest->is_negative = true;188 dest->is_negative = true;
174 }189 }
175}190}
...@@ -1023,7 +1038,7 @@ Cmp bigint_cmp(const BigInt *op1, const BigInt *op2) {...@@ -1023,7 +1038,7 @@ Cmp bigint_cmp(const BigInt *op1, const BigInt *op2) {
1023 }1038 }
1024}1039}
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) {
1027 if (op->digit_count == 0) {1042 if (op->digit_count == 0) {
1028 buf_append_char(buf, '0');1043 buf_append_char(buf, '0');
1029 return;1044 return;
src/bigint.hpp+2-1
...@@ -30,6 +30,7 @@ enum Cmp {...@@ -30,6 +30,7 @@ enum Cmp {
30};30};
3131
32void bigint_init_unsigned(BigInt *dest, uint64_t x);32void bigint_init_unsigned(BigInt *dest, uint64_t x);
33void bigint_init_u128(BigInt *dest, unsigned __int128 x);
33void bigint_init_signed(BigInt *dest, int64_t x);34void bigint_init_signed(BigInt *dest, int64_t x);
34void bigint_init_bigint(BigInt *dest, const BigInt *src);35void bigint_init_bigint(BigInt *dest, const BigInt *src);
35void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);36void 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...@@ -76,7 +77,7 @@ void bigint_truncate(BigInt *dest, const BigInt *op, size_t bit_count, bool is_s
7677
77Cmp bigint_cmp(const BigInt *op1, const BigInt *op2);78Cmp 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
81size_t bigint_ctz(const BigInt *bi, size_t bit_count);82size_t bigint_ctz(const BigInt *bi, size_t bit_count);
82size_t bigint_clz(const BigInt *bi, size_t bit_count);83size_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) {...@@ -1243,10 +1243,6 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
1243 }1243 }
1244}1244}
12451245
1246static LLVMValueRef bigfloat_to_llvm_const(LLVMTypeRef type_ref, BigFloat *bigfloat) {
1247 return LLVMConstReal(type_ref, bigfloat_to_double(bigfloat));
1248}
1249
1250static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_math,1246static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_math,
1251 LLVMValueRef val1, LLVMValueRef val2,1247 LLVMValueRef val1, LLVMValueRef val2,
1252 TypeTableEntry *type_entry, DivKind div_kind)1248 TypeTableEntry *type_entry, DivKind div_kind)
...@@ -3455,7 +3451,23 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3455,7 +3451,23 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3455 return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref,3451 return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref,
3456 const_val->data.x_pure_err->value, false);3452 const_val->data.x_pure_err->value, false);
3457 case TypeTableEntryIdFloat:3453 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 }
3459 case TypeTableEntryIdBool:3471 case TypeTableEntryIdBool:
3460 if (const_val->data.x_bool) {3472 if (const_val->data.x_bool) {
3461 return LLVMConstAllOnes(LLVMInt1Type());3473 return LLVMConstAllOnes(LLVMInt1Type());
...@@ -3937,8 +3949,11 @@ static void do_code_gen(CodeGen *g) {...@@ -3937,8 +3949,11 @@ static void do_code_gen(CodeGen *g) {
3937 // Generate debug info for it but that's it.3949 // Generate debug info for it but that's it.
3938 ConstExprValue *const_val = var->value;3950 ConstExprValue *const_val = var->value;
3939 assert(const_val->special != ConstValSpecialRuntime);3951 assert(const_val->special != ConstValSpecialRuntime);
3940 TypeTableEntry *var_type = g->builtin_types.entry_f64;3952 TypeTableEntry *var_type = g->builtin_types.entry_f128;
3941 LLVMValueRef init_val = bigfloat_to_llvm_const(var_type->type_ref, &const_val->data.x_bigfloat);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);
3942 gen_global_var(g, var, init_val, var_type);3957 gen_global_var(g, var, init_val, var_type);
3943 continue;3958 continue;
3944 }3959 }
src/ir.cpp+611-41
...@@ -12,6 +12,7 @@...@@ -12,6 +12,7 @@
12#include "ir_print.hpp"12#include "ir_print.hpp"
13#include "os.hpp"13#include "os.hpp"
14#include "parseh.hpp"14#include "parseh.hpp"
15#include "quadmath.hpp"
15#include "range_set.hpp"16#include "range_set.hpp"
1617
17struct IrExecContext {18struct IrExecContext {
...@@ -6272,6 +6273,546 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry...@@ -6272,6 +6273,546 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry
6272 (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt)));6273 (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt)));
6273}6274}
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
6275static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type,6816static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type,
6276 bool explicit_cast)6817 bool explicit_cast)
6277{6818{
...@@ -6314,9 +6855,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -6314,9 +6855,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
6314 if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) &&6855 if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) &&
6315 const_val_is_float)6856 const_val_is_float)
6316 {6857 {
6317 if (bigfloat_has_fraction(&const_val->data.x_bigfloat)) {6858 if (float_has_fraction(const_val)) {
6318 Buf *val_buf = buf_alloc();6859 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
6321 ir_add_error(ira, instruction,6862 ir_add_error(ira, instruction,
6322 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'",6863 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...@@ -6324,11 +6865,11 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
6324 buf_ptr(&other_type->name)));6865 buf_ptr(&other_type->name)));
6325 return false;6866 return false;
6326 } else {6867 } else {
6327 BigInt bigint;
6328 bigint_init_bigfloat(&bigint, &const_val->data.x_bigfloat);
6329 if (other_type->id == TypeTableEntryIdNumLitInt) {6868 if (other_type->id == TypeTableEntryIdNumLitInt) {
6330 return true;6869 return true;
6331 } else {6870 } else {
6871 BigInt bigint;
6872 float_init_bigint(&bigint, const_val);
6332 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count,6873 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count,
6333 other_type->data.integral.is_signed))6874 other_type->data.integral.is_signed))
6334 {6875 {
...@@ -6342,10 +6883,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -6342,10 +6883,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
6342 Buf *val_buf = buf_alloc();6883 Buf *val_buf = buf_alloc();
6343 if (const_val_is_float) {6884 if (const_val_is_float) {
6344 num_lit_str = "float";6885 num_lit_str = "float";
6345 bigfloat_write_buf(val_buf, &const_val->data.x_bigfloat);6886 float_append_buf(val_buf, const_val);
6346 } else {6887 } else {
6347 num_lit_str = "integer";6888 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);
6349 }6890 }
63506891
6351 ir_add_error(ira, instruction,6892 ir_add_error(ira, instruction,
...@@ -6767,7 +7308,20 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -6767,7 +7308,20 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
6767 }7308 }
6768 case CastOpNumLitToConcrete:7309 case CastOpNumLitToConcrete:
6769 if (other_val->type->id == TypeTableEntryIdNumLitFloat) {7310 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 }
6771 } else if (other_val->type->id == TypeTableEntryIdNumLitInt) {7325 } else if (other_val->type->id == TypeTableEntryIdNumLitInt) {
6772 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint);7326 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint);
6773 } else {7327 } else {
...@@ -6780,11 +7334,29 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -6780,11 +7334,29 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
6780 // can't do it7334 // can't do it
6781 break;7335 break;
6782 case CastOpIntToFloat:7336 case CastOpIntToFloat:
6783 bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint);7337 {
6784 const_val->special = ConstValSpecialStatic;7338 assert(new_type->id == TypeTableEntryIdFloat);
6785 break;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 }
6786 case CastOpFloatToInt:7358 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);
6788 const_val->special = ConstValSpecialStatic;7360 const_val->special = ConstValSpecialStatic;
6789 break;7361 break;
6790 case CastOpBoolToInt:7362 case CastOpBoolToInt:
...@@ -7387,12 +7959,12 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction...@@ -7387,12 +7959,12 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
7387 }7959 }
7388 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,7960 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
7389 source_instr->source_node, wanted_type);7961 source_instr->source_node, wanted_type);
7962 result->value.type = wanted_type;
7390 if (wanted_type->id == TypeTableEntryIdInt) {7963 if (wanted_type->id == TypeTableEntryIdInt) {
7391 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);7964 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);
7392 } else {7965 } else {
7393 bigfloat_init_bigfloat(&result->value.data.x_bigfloat, &val->data.x_bigfloat);7966 float_init_float(&result->value, val);
7394 }7967 }
7395 result->value.type = wanted_type;
7396 return result;7968 return result;
7397 }7969 }
73987970
...@@ -7415,7 +7987,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour...@@ -7415,7 +7987,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour
7415 bigint_init_unsigned(&enum_member_count, wanted_type->data.enumeration.src_field_count);7987 bigint_init_unsigned(&enum_member_count, wanted_type->data.enumeration.src_field_count);
7416 if (bigint_cmp(&val->data.x_bigint, &enum_member_count) != CmpLT) {7988 if (bigint_cmp(&val->data.x_bigint, &enum_member_count) != CmpLT) {
7417 Buf *val_buf = buf_alloc();7989 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);
7419 ir_add_error(ira, source_instr,7991 ir_add_error(ira, source_instr,
7420 buf_sprintf("integer value %s too big for enum '%s' which has %" PRIu32 " fields",7992 buf_sprintf("integer value %s too big for enum '%s' which has %" PRIu32 " fields",
7421 buf_ptr(val_buf), buf_ptr(&wanted_type->name), wanted_type->data.enumeration.src_field_count));7993 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...@@ -7444,7 +8016,7 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction
7444 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,8016 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
7445 source_instr->source_node, wanted_type);8017 source_instr->source_node, wanted_type);
7446 if (wanted_type->id == TypeTableEntryIdNumLitFloat) {8018 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);
7448 } else if (wanted_type->id == TypeTableEntryIdNumLitInt) {8020 } else if (wanted_type->id == TypeTableEntryIdNumLitInt) {
7449 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);8021 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);
7450 } else {8022 } else {
...@@ -7469,7 +8041,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc...@@ -7469,7 +8041,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc
7469 bigint_init_unsigned(&err_count, ira->codegen->error_decls.length);8041 bigint_init_unsigned(&err_count, ira->codegen->error_decls.length);
7470 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) {8042 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) {
7471 Buf *val_buf = buf_alloc();8043 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);
7473 ir_add_error(ira, source_instr,8045 ir_add_error(ira, source_instr,
7474 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf)));8046 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf)));
7475 return ira->codegen->invalid_instruction;8047 return ira->codegen->invalid_instruction;
...@@ -8304,7 +8876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -8304,7 +8876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
8304 if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) {8876 if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) {
8305 bool answer;8877 bool answer;
8306 if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) {8878 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);
8308 answer = resolve_cmp_op_id(op_id, cmp_result);8880 answer = resolve_cmp_op_id(op_id, cmp_result);
8309 } else if (resolved_type->id == TypeTableEntryIdNumLitInt || resolved_type->id == TypeTableEntryIdInt) {8881 } else if (resolved_type->id == TypeTableEntryIdNumLitInt || resolved_type->id == TypeTableEntryIdInt) {
8310 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);8882 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,...@@ -8379,7 +8951,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8379 {8951 {
8380 is_int = false;8952 is_int = false;
8381 is_float = true;8953 is_float = true;
8382 op2_zcmp = bigfloat_cmp_zero(&op2_val->data.x_bigfloat);8954 op2_zcmp = float_cmp_zero(op2_val);
8383 } else {8955 } else {
8384 zig_unreachable();8956 zig_unreachable();
8385 }8957 }
...@@ -8447,7 +9019,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -8447,7 +9019,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8447 if (is_int) {9019 if (is_int) {
8448 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9020 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8449 } else {9021 } 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);
8451 }9023 }
8452 break;9024 break;
8453 case IrBinOpAddWrap:9025 case IrBinOpAddWrap:
...@@ -8459,7 +9031,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -8459,7 +9031,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8459 if (is_int) {9031 if (is_int) {
8460 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9032 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8461 } else {9033 } 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);
8463 }9035 }
8464 break;9036 break;
8465 case IrBinOpSubWrap:9037 case IrBinOpSubWrap:
...@@ -8471,7 +9043,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -8471,7 +9043,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8471 if (is_int) {9043 if (is_int) {
8472 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9044 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8473 } else {9045 } 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);
8475 }9047 }
8476 break;9048 break;
8477 case IrBinOpMultWrap:9049 case IrBinOpMultWrap:
...@@ -8481,20 +9053,20 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -8481,20 +9053,20 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8481 break;9053 break;
8482 case IrBinOpDivUnspecified:9054 case IrBinOpDivUnspecified:
8483 assert(is_float);9055 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);
8485 break;9057 break;
8486 case IrBinOpDivTrunc:9058 case IrBinOpDivTrunc:
8487 if (is_int) {9059 if (is_int) {
8488 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9060 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8489 } else {9061 } 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);
8491 }9063 }
8492 break;9064 break;
8493 case IrBinOpDivFloor:9065 case IrBinOpDivFloor:
8494 if (is_int) {9066 if (is_int) {
8495 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9067 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8496 } else {9068 } 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);
8498 }9070 }
8499 break;9071 break;
8500 case IrBinOpDivExact:9072 case IrBinOpDivExact:
...@@ -8506,10 +9078,10 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -8506,10 +9078,10 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8506 return ErrorExactDivRemainder;9078 return ErrorExactDivRemainder;
8507 }9079 }
8508 } else {9080 } else {
8509 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);9081 float_div_trunc(out_val, op1_val, op2_val);
8510 BigFloat remainder;9082 ConstExprValue remainder;
8511 bigfloat_rem(&remainder, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat);9083 float_rem(&remainder, op1_val, op2_val);
8512 if (bigfloat_cmp_zero(&remainder) != CmpEQ) {9084 if (float_cmp_zero(&remainder) != CmpEQ) {
8513 return ErrorExactDivRemainder;9085 return ErrorExactDivRemainder;
8514 }9086 }
8515 }9087 }
...@@ -8518,14 +9090,14 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -8518,14 +9090,14 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
8518 if (is_int) {9090 if (is_int) {
8519 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9091 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8520 } else {9092 } 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);
8522 }9094 }
8523 break;9095 break;
8524 case IrBinOpRemMod:9096 case IrBinOpRemMod:
8525 if (is_int) {9097 if (is_int) {
8526 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);9098 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
8527 } else {9099 } 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);
8529 }9101 }
8530 break;9102 break;
8531 }9103 }
...@@ -8678,16 +9250,16 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp...@@ -8678,16 +9250,16 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
8678 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ;9250 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ;
8679 }9251 }
8680 } else {9252 } else {
8681 if (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) == CmpEQ) {9253 if (float_cmp_zero(&op2->value) == CmpEQ) {
8682 // the division by zero error will be caught later, but we don't9254 // the division by zero error will be caught later, but we don't
8683 // have a remainder function ambiguity problem9255 // have a remainder function ambiguity problem
8684 ok = true;9256 ok = true;
8685 } else {9257 } else {
8686 BigFloat rem_result;9258 ConstExprValue rem_result;
8687 BigFloat mod_result;9259 ConstExprValue mod_result;
8688 bigfloat_rem(&rem_result, &op1->value.data.x_bigfloat, &op2->value.data.x_bigfloat);9260 float_rem(&rem_result, &op1->value, &op2->value);
8689 bigfloat_mod(&mod_result, &op1->value.data.x_bigfloat, &op2->value.data.x_bigfloat);9261 float_mod(&mod_result, &op1->value, &op2->value);
8690 ok = bigfloat_cmp(&rem_result, &mod_result) == CmpEQ;9262 ok = float_cmp(&rem_result, &mod_result) == CmpEQ;
8691 }9263 }
8692 }9264 }
8693 }9265 }
...@@ -9835,7 +10407,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un...@@ -9835,7 +10407,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un
983510407
9836 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);10408 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
9837 if (is_float) {10409 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);
9839 } else if (is_wrap_op) {10411 } else if (is_wrap_op) {
9840 bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint,10412 bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint,
9841 expr_type->data.integral.bit_count);10413 expr_type->data.integral.bit_count);
...@@ -13780,8 +14352,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -13780,8 +14352,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
13780 codegen->is_big_endian);14352 codegen->is_big_endian);
13781 return;14353 return;
13782 case TypeTableEntryIdFloat:14354 case TypeTableEntryIdFloat:
13783 bigfloat_write_ieee597(&val->data.x_bigfloat, buf, val->type->data.floating.bit_count,14355 float_write_ieee597(val, buf, codegen->is_big_endian);
13784 codegen->is_big_endian);
13785 return;14356 return;
13786 case TypeTableEntryIdPointer:14357 case TypeTableEntryIdPointer:
13787 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {14358 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
...@@ -13841,8 +14412,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -13841,8 +14412,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
13841 codegen->is_big_endian, val->type->data.integral.is_signed);14412 codegen->is_big_endian, val->type->data.integral.is_signed);
13842 return;14413 return;
13843 case TypeTableEntryIdFloat:14414 case TypeTableEntryIdFloat:
13844 bigfloat_read_ieee597(&val->data.x_bigfloat, buf, val->type->data.floating.bit_count,14415 float_read_ieee597(val, buf, codegen->is_big_endian);
13845 codegen->is_big_endian);
13846 return;14416 return;
13847 case TypeTableEntryIdPointer:14417 case TypeTableEntryIdPointer:
13848 {14418 {
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) {...@@ -257,7 +257,7 @@ static void set_token_id(Tokenize *t, Token *token, TokenId id) {
257 if (id == TokenIdIntLiteral) {257 if (id == TokenIdIntLiteral) {
258 bigint_init_unsigned(&token->data.int_lit.bigint, 0);258 bigint_init_unsigned(&token->data.int_lit.bigint, 0);
259 } else if (id == TokenIdFloatLiteral) {259 } 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);
261 token->data.float_lit.overflow = false;261 token->data.float_lit.overflow = false;
262 } else if (id == TokenIdStringLiteral || id == TokenIdSymbol) {262 } else if (id == TokenIdStringLiteral || id == TokenIdSymbol) {
263 memset(&token->data.str_lit.str, 0, sizeof(Buf));263 memset(&token->data.str_lit.str, 0, sizeof(Buf));
...@@ -345,7 +345,7 @@ static void end_float_token(Tokenize *t) {...@@ -345,7 +345,7 @@ static void end_float_token(Tokenize *t) {
345 uint64_t double_bits = (exponent_bits << 52) | significand_bits;345 uint64_t double_bits = (exponent_bits << 52) | significand_bits;
346 double dbl_value;346 double dbl_value;
347 safe_memcpy(&dbl_value, (double *)&double_bits, 1);347 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);
349}349}
350350
351static void end_token(Tokenize *t) {351static void end_token(Tokenize *t) {
std/math/atan2.zig+1-1
...@@ -24,7 +24,7 @@ const assert = @import("../debug.zig").assert;...@@ -24,7 +24,7 @@ const assert = @import("../debug.zig").assert;
24pub const atan2 = atan2_workaround;24pub const atan2 = atan2_workaround;
2525
26// TODO issue #39326// 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 {
28 switch (T) {28 switch (T) {
29 f32 => @inlineCall(atan2_32, x, y),29 f32 => @inlineCall(atan2_32, x, y),
30 f64 => @inlineCall(atan2_64, x, y),30 f64 => @inlineCall(atan2_64, x, y),
std/math/sin.zig+1
...@@ -147,6 +147,7 @@ fn sin64(x_: f64) -> f64 {...@@ -147,6 +147,7 @@ fn sin64(x_: f64) -> f64 {
147test "math.sin" {147test "math.sin" {
148 assert(sin(f32(0.0)) == sin32(0.0));148 assert(sin(f32(0.0)) == sin32(0.0));
149 assert(sin(f64(0.0)) == sin64(0.0));149 assert(sin(f64(0.0)) == sin64(0.0));
150 assert(comptime {math.sin(f64(2))} == math.sin(f64(2)));
150}151}
151152
152test "math.sin32" {153test "math.sin32" {
test/cases/eval.zig+20
...@@ -355,3 +355,23 @@ test "@setEvalBranchQuota" {...@@ -355,3 +355,23 @@ test "@setEvalBranchQuota" {
355 assert(sum == 500500);355 assert(sum == 500500);
356 }356 }
357}357}
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);