authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-15 18:12:11+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-04-15 18:12:11+02:00
logf9481402f0c6f2eb4618bb0385aff18c12912c26
treedec626fa96c0c21c8965bf19ef9fcf497a86adfd
parentc59241bda00376b5a6ee20ca52358329b7482f7f

stage1: Fix negation for zero floating point values

Toggling the sign by computing 0-x doesn't really work for zero values.

4 files changed, 22 insertions(+), 14 deletions(-)

src/stage1/bigfloat.cpp+3-6
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
9#include "bigint.hpp"9#include "bigint.hpp"
10#include "buffer.hpp"10#include "buffer.hpp"
11#include "softfloat.hpp"11#include "softfloat.hpp"
12#include "softfloat_ext.hpp"
12#include "parse_f128.h"13#include "parse_f128.h"
13#include <stdio.h>14#include <stdio.h>
14#include <math.h>15#include <math.h>
...@@ -60,9 +61,7 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {...@@ -60,9 +61,7 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
6061
61 if (i == 0) {62 if (i == 0) {
62 if (op->is_negative) {63 if (op->is_negative) {
63 float128_t zero_f128;64 f128M_neg(&dest->value, &dest->value);
64 ui32_to_f128M(0, &zero_f128);
65 f128M_sub(&zero_f128, &dest->value, &dest->value);
66 }65 }
67 return;66 return;
68 }67 }
...@@ -89,9 +88,7 @@ void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {...@@ -89,9 +88,7 @@ void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
89}88}
9089
91void bigfloat_negate(BigFloat *dest, const BigFloat *op) {90void bigfloat_negate(BigFloat *dest, const BigFloat *op) {
92 float128_t zero_f128;91 f128M_neg(&op->value, &dest->value);
93 ui32_to_f128M(0, &zero_f128);
94 f128M_sub(&zero_f128, &op->value, &dest->value);
95}92}
9693
97void bigfloat_sub(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {94void bigfloat_sub(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
src/stage1/ir.cpp+3-8
...@@ -11363,11 +11363,8 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {...@@ -11363,11 +11363,8 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
11363 } else if (op->type->id == ZigTypeIdFloat) {11363 } else if (op->type->id == ZigTypeIdFloat) {
11364 switch (op->type->data.floating.bit_count) {11364 switch (op->type->data.floating.bit_count) {
11365 case 16:11365 case 16:
11366 {11366 out_val->data.x_f16 = f16_neg(op->data.x_f16);
11367 const float16_t zero = zig_double_to_f16(0);11367 return;
11368 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16);
11369 return;
11370 }
11371 case 32:11368 case 32:
11372 out_val->data.x_f32 = -op->data.x_f32;11369 out_val->data.x_f32 = -op->data.x_f32;
11373 return;11370 return;
...@@ -11375,9 +11372,7 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {...@@ -11375,9 +11372,7 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
11375 out_val->data.x_f64 = -op->data.x_f64;11372 out_val->data.x_f64 = -op->data.x_f64;
11376 return;11373 return;
11377 case 128:11374 case 128:
11378 float128_t zero_f128;11375 f128M_neg(&op->data.x_f128, &out_val->data.x_f128);
11379 ui32_to_f128M(0, &zero_f128);
11380 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128);
11381 return;11376 return;
11382 default:11377 default:
11383 zig_unreachable();11378 zig_unreachable();
src/stage1/softfloat_ext.cpp+13
...@@ -1,6 +1,8 @@...@@ -1,6 +1,8 @@
1#include "softfloat_ext.hpp"1#include "softfloat_ext.hpp"
22
3extern "C" {3extern "C" {
4 #include "platform.h"
5 #include "internals.h"
4 #include "softfloat.h"6 #include "softfloat.h"
5}7}
68
...@@ -22,4 +24,15 @@ void f128M_trunc(const float128_t *aPtr, float128_t *zPtr) {...@@ -22,4 +24,15 @@ void f128M_trunc(const float128_t *aPtr, float128_t *zPtr) {
22 } else {24 } else {
23 f128M_roundToInt(aPtr, softfloat_round_min, false, zPtr);25 f128M_roundToInt(aPtr, softfloat_round_min, false, zPtr);
24 } 26 }
27}
28
29float16_t f16_neg(const float16_t a) {
30 union ui16_f16 uZ;
31 uZ.ui = a.v ^ (UINT16_C(1) << 15);
32 return uZ.f;
33}
34
35void f128M_neg(const float128_t *aPtr, float128_t *zPtr) {
36 zPtr->v[indexWord(2,1)] = aPtr->v[indexWord(2,1)] ^ (UINT64_C(1) << 63);
37 zPtr->v[indexWord(2,0)] = aPtr->v[indexWord(2,0)];
25}38}
\ No newline at end of file
src/stage1/softfloat_ext.hpp+3
...@@ -5,5 +5,8 @@...@@ -5,5 +5,8 @@
55
6void f128M_abs(const float128_t *aPtr, float128_t *zPtr);6void f128M_abs(const float128_t *aPtr, float128_t *zPtr);
7void f128M_trunc(const float128_t *aPtr, float128_t *zPtr);7void f128M_trunc(const float128_t *aPtr, float128_t *zPtr);
8void f128M_neg(const float128_t *aPtr, float128_t *zPtr);
9
10float16_t f16_neg(const float16_t a);
811
9#endif12#endif
\ No newline at end of file