aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMateusz Radomski <33978857+m-radomski@users.noreply.github.com>2022-02-13 14:37:38 +0100
committerGitHub <noreply@github.com>2022-02-13 15:37:38 +0200
commitb5f8fb85e64022ed1ee59ff70753577839ad41b6 (patch)
tree79972cc2e52fe9c9b54a265434148110debe6d04 /src
parentf22443bb05a6be6c3ade08254f52fdd05eeb2910 (diff)
downloadzig-b5f8fb85e64022ed1ee59ff70753577839ad41b6.tar.gz
zig-b5f8fb85e64022ed1ee59ff70753577839ad41b6.zip
Implement f128 `@rem`
Diffstat (limited to 'src')
-rw-r--r--src/stage1/ir.cpp32
-rw-r--r--src/value.zig9
2 files changed, 30 insertions, 11 deletions
diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp
index 0b6332f480..63466849a4 100644
--- a/src/stage1/ir.cpp
+++ b/src/stage1/ir.cpp
@@ -3338,6 +3338,32 @@ static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
}
}
+// c = a - b * trunc(a / b)
+static float16_t zig_f16_rem(float16_t a, float16_t b) {
+ float16_t c;
+ c = f16_div(a, b);
+ c = f16_roundToInt(c, softfloat_round_minMag, false);
+ c = f16_mul(b, c);
+ c = f16_sub(a, c);
+ return c;
+}
+
+// c = a - b * trunc(a / b)
+static void zig_f128M_rem(const float128_t* a, const float128_t* b, float128_t* c) {
+ f128M_div(a, b, c);
+ f128M_roundToInt(c, softfloat_round_minMag, false, c);
+ f128M_mul(b, c, c);
+ f128M_sub(a, c, c);
+}
+
+// c = a - b * trunc(a / b)
+static void zig_extF80M_rem(const extFloat80_t* a, const extFloat80_t* b, extFloat80_t* c) {
+ extF80M_div(a, b, c);
+ extF80M_roundToInt(c, softfloat_round_minMag, false, c);
+ extF80M_mul(b, c, c);
+ extF80M_sub(a, c, c);
+}
+
static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
assert(op1->type == op2->type);
out_val->type = op1->type;
@@ -3346,7 +3372,7 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
} else if (op1->type->id == ZigTypeIdFloat) {
switch (op1->type->data.floating.bit_count) {
case 16:
- out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16);
+ out_val->data.x_f16 = zig_f16_rem(op1->data.x_f16, op2->data.x_f16);
return;
case 32:
out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32);
@@ -3355,10 +3381,10 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64);
return;
case 80:
- extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+ zig_extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
return;
case 128:
- f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
+ zig_f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
diff --git a/src/value.zig b/src/value.zig
index 1f93a828aa..89c57ad53d 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -1482,8 +1482,7 @@ pub const Value = extern union {
.float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0,
//.float_80 => @rem(self.castTag(.float_80).?.data, 1) != 0,
.float_80 => @panic("TODO implement __remx in compiler-rt"),
- //.float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0,
- .float_128 => @panic("TODO implement fmodl in compiler-rt"),
+ .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0,
else => unreachable,
};
@@ -2888,9 +2887,6 @@ pub const Value = extern union {
return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val));
},
128 => {
- if (true) {
- @panic("TODO implement compiler_rt fmodl");
- }
const lhs_val = lhs.toFloat(f128);
const rhs_val = rhs.toFloat(f128);
return Value.Tag.float_128.create(arena, @rem(lhs_val, rhs_val));
@@ -2925,9 +2921,6 @@ pub const Value = extern union {
return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val));
},
128 => {
- if (true) {
- @panic("TODO implement compiler_rt fmodl");
- }
const lhs_val = lhs.toFloat(f128);
const rhs_val = rhs.toFloat(f128);
return Value.Tag.float_128.create(arena, @mod(lhs_val, rhs_val));