aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-09-14 01:44:22 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-09-14 01:46:47 -0400
commit14cda27b640651829b1d8af996392b650c7835a5 (patch)
tree9aaa94dece961979989e00d40a36a396fe5ea079 /src/ir.cpp
parent7ddc259acc2c66057cf8f977e80b971c6375d8af (diff)
downloadzig-14cda27b640651829b1d8af996392b650c7835a5.tar.gz
zig-14cda27b640651829b1d8af996392b650c7835a5.zip
depend on embedded SoftFloat-3d instead of __float128
See #302 See #467
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp110
1 files changed, 69 insertions, 41 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 6b887a6d83..ffe49179ca 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -12,8 +12,8 @@
#include "ir_print.hpp"
#include "os.hpp"
#include "parsec.hpp"
-#include "quadmath.hpp"
#include "range_set.hpp"
+#include "softfloat.hpp"
struct IrExecContext {
ConstExprValue *mem_slot_list;
@@ -6439,7 +6439,11 @@ static bool float_has_fraction(ConstExprValue *const_val) {
case 64:
return floor(const_val->data.x_f64) != const_val->data.x_f64;
case 128:
- return floorq(const_val->data.x_f128) != const_val->data.x_f128;
+ {
+ float128_t floored;
+ f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored);
+ return !f128M_eq(&floored, &const_val->data.x_f128);
+ }
default:
zig_unreachable();
}
@@ -6461,10 +6465,16 @@ static void float_append_buf(Buf *buf, ConstExprValue *const_val) {
break;
case 128:
{
+ // TODO actual implementation
const size_t extra_len = 100;
size_t old_len = buf_len(buf);
buf_resize(buf, old_len + extra_len);
- int len = quadmath_snprintf(buf_ptr(buf) + old_len, extra_len, "%Qf", const_val->data.x_f128);
+
+ float64_t f64_value = f128M_to_f64(&const_val->data.x_f128);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+
+ int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value);
assert(len > 0);
buf_resize(buf, old_len + len);
break;
@@ -6499,11 +6509,10 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {
}
break;
case 128:
- if (const_val->data.x_f128 >= 0) {
- bigint_init_u128(bigint, (uint128_t)(const_val->data.x_f128));
- } else {
- bigint_init_u128(bigint, (uint128_t)(-const_val->data.x_f128));
- bigint->is_negative = true;
+ {
+ BigFloat tmp_float;
+ bigfloat_init_128(&tmp_float, const_val->data.x_f128);
+ bigint_init_bigfloat(bigint, &tmp_float);
}
break;
default:
@@ -6548,8 +6557,12 @@ static void float_init_f32(ConstExprValue *dest_val, float x) {
dest_val->data.x_f64 = x;
break;
case 128:
- dest_val->data.x_f128 = x;
- break;
+ {
+ float32_t x_f32;
+ memcpy(&x_f32, &x, sizeof(float));
+ f32_to_f128M(x_f32, &dest_val->data.x_f128);
+ break;
+ }
default:
zig_unreachable();
}
@@ -6570,8 +6583,12 @@ static void float_init_f64(ConstExprValue *dest_val, double x) {
dest_val->data.x_f64 = x;
break;
case 128:
- dest_val->data.x_f128 = x;
- break;
+ {
+ float64_t x_f64;
+ memcpy(&x_f64, &x, sizeof(double));
+ f64_to_f128M(x_f64, &dest_val->data.x_f128);
+ break;
+ }
default:
zig_unreachable();
}
@@ -6580,20 +6597,28 @@ static void float_init_f64(ConstExprValue *dest_val, double x) {
}
}
-static void float_init_f128(ConstExprValue *dest_val, __float128 x) {
+static void float_init_f128(ConstExprValue *dest_val, float128_t x) {
if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {
bigfloat_init_128(&dest_val->data.x_bigfloat, x);
} else if (dest_val->type->id == TypeTableEntryIdFloat) {
switch (dest_val->type->data.floating.bit_count) {
case 32:
- dest_val->data.x_f32 = x;
- break;
+ {
+ float32_t f32_val = f128M_to_f32(&x);
+ memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float));
+ break;
+ }
case 64:
- dest_val->data.x_f64 = x;
- break;
+ {
+ float64_t f64_val = f128M_to_f64(&x);
+ memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double));
+ break;
+ }
case 128:
- dest_val->data.x_f128 = x;
- break;
+ {
+ memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t));
+ break;
+ }
default:
zig_unreachable();
}
@@ -6647,12 +6672,12 @@ static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) {
return CmpEQ;
}
case 128:
- if (op1->data.x_f128 > op2->data.x_f128) {
- return CmpGT;
- } else if (op1->data.x_f128 < op2->data.x_f128) {
+ if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) {
return CmpLT;
- } else {
+ } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) {
return CmpEQ;
+ } else {
+ return CmpGT;
}
default:
zig_unreachable();
@@ -6684,12 +6709,14 @@ static Cmp float_cmp_zero(ConstExprValue *op) {
return CmpEQ;
}
case 128:
- if (op->data.x_f128 < 0.0) {
+ float128_t zero_float;
+ ui32_to_f128M(0, &zero_float);
+ if (f128M_lt(&op->data.x_f128, &zero_float)) {
return CmpLT;
- } else if (op->data.x_f128 > 0.0) {
- return CmpGT;
- } else {
+ } else if (f128M_eq(&op->data.x_f128, &zero_float)) {
return CmpEQ;
+ } else {
+ return CmpGT;
}
default:
zig_unreachable();
@@ -6713,7 +6740,7 @@ static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64;
return;
case 128:
- out_val->data.x_f128 = op1->data.x_f128 + op2->data.x_f128;
+ f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6737,7 +6764,7 @@ static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64;
return;
case 128:
- out_val->data.x_f128 = op1->data.x_f128 - op2->data.x_f128;
+ f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6761,7 +6788,7 @@ static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64;
return;
case 128:
- out_val->data.x_f128 = op1->data.x_f128 * op2->data.x_f128;
+ f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6785,7 +6812,7 @@ static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64;
return;
case 128:
- out_val->data.x_f128 = op1->data.x_f128 / op2->data.x_f128;
+ f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6819,12 +6846,8 @@ static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstE
}
return;
case 128:
- out_val->data.x_f128 = op1->data.x_f128 / op2->data.x_f128;
- if (out_val->data.x_f128 >= 0.0) {
- out_val->data.x_f128 = floorq(out_val->data.x_f128);
- } else {
- out_val->data.x_f128 = ceilq(out_val->data.x_f128);
- }
+ f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
+ f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6848,7 +6871,8 @@ static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstE
out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64);
return;
case 128:
- out_val->data.x_f128 = floorq(op1->data.x_f128 / op2->data.x_f128);
+ f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
+ f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6872,7 +6896,7 @@ static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64);
return;
case 128:
- out_val->data.x_f128 = fmodq(op1->data.x_f128, op2->data.x_f128);
+ f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6896,7 +6920,9 @@ static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64);
return;
case 128:
- out_val->data.x_f128 = fmodq(fmodq(op1->data.x_f128, op2->data.x_f128) + op2->data.x_f128, op2->data.x_f128);
+ f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
+ f128M_add(&out_val->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
+ f128M_rem(&out_val->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -6919,7 +6945,9 @@ static void float_negate(ConstExprValue *out_val, ConstExprValue *op) {
out_val->data.x_f64 = -op->data.x_f64;
return;
case 128:
- out_val->data.x_f128 = -op->data.x_f128;
+ float128_t zero_f128;
+ ui32_to_f128M(0, &zero_f128);
+ f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();