diff options
| author | Mateusz Radomski <33978857+m-radomski@users.noreply.github.com> | 2022-02-13 14:37:38 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-13 15:37:38 +0200 |
| commit | b5f8fb85e64022ed1ee59ff70753577839ad41b6 (patch) | |
| tree | 79972cc2e52fe9c9b54a265434148110debe6d04 /src | |
| parent | f22443bb05a6be6c3ade08254f52fdd05eeb2910 (diff) | |
| download | zig-b5f8fb85e64022ed1ee59ff70753577839ad41b6.tar.gz zig-b5f8fb85e64022ed1ee59ff70753577839ad41b6.zip | |
Implement f128 `@rem`
Diffstat (limited to 'src')
| -rw-r--r-- | src/stage1/ir.cpp | 32 | ||||
| -rw-r--r-- | src/value.zig | 9 |
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)); |
