stage1: Fix negation for zero floating point values
Toggling the sign by computing 0-x doesn't really work for zero values.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "bigint.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "softfloat.hpp"
|
||||
#include "softfloat_ext.hpp"
|
||||
#include "parse_f128.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
@@ -60,9 +61,7 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
|
||||
|
||||
if (i == 0) {
|
||||
if (op->is_negative) {
|
||||
float128_t zero_f128;
|
||||
ui32_to_f128M(0, &zero_f128);
|
||||
f128M_sub(&zero_f128, &dest->value, &dest->value);
|
||||
f128M_neg(&dest->value, &dest->value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -89,9 +88,7 @@ void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
|
||||
}
|
||||
|
||||
void bigfloat_negate(BigFloat *dest, const BigFloat *op) {
|
||||
float128_t zero_f128;
|
||||
ui32_to_f128M(0, &zero_f128);
|
||||
f128M_sub(&zero_f128, &op->value, &dest->value);
|
||||
f128M_neg(&op->value, &dest->value);
|
||||
}
|
||||
|
||||
void bigfloat_sub(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
|
||||
|
||||
@@ -11363,11 +11363,8 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
|
||||
} else if (op->type->id == ZigTypeIdFloat) {
|
||||
switch (op->type->data.floating.bit_count) {
|
||||
case 16:
|
||||
{
|
||||
const float16_t zero = zig_double_to_f16(0);
|
||||
out_val->data.x_f16 = f16_sub(zero, op->data.x_f16);
|
||||
return;
|
||||
}
|
||||
out_val->data.x_f16 = f16_neg(op->data.x_f16);
|
||||
return;
|
||||
case 32:
|
||||
out_val->data.x_f32 = -op->data.x_f32;
|
||||
return;
|
||||
@@ -11375,9 +11372,7 @@ static void float_negate(ZigValue *out_val, ZigValue *op) {
|
||||
out_val->data.x_f64 = -op->data.x_f64;
|
||||
return;
|
||||
case 128:
|
||||
float128_t zero_f128;
|
||||
ui32_to_f128M(0, &zero_f128);
|
||||
f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128);
|
||||
f128M_neg(&op->data.x_f128, &out_val->data.x_f128);
|
||||
return;
|
||||
default:
|
||||
zig_unreachable();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "softfloat_ext.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "platform.h"
|
||||
#include "internals.h"
|
||||
#include "softfloat.h"
|
||||
}
|
||||
|
||||
@@ -22,4 +24,15 @@ void f128M_trunc(const float128_t *aPtr, float128_t *zPtr) {
|
||||
} else {
|
||||
f128M_roundToInt(aPtr, softfloat_round_min, false, zPtr);
|
||||
}
|
||||
}
|
||||
|
||||
float16_t f16_neg(const float16_t a) {
|
||||
union ui16_f16 uZ;
|
||||
uZ.ui = a.v ^ (UINT16_C(1) << 15);
|
||||
return uZ.f;
|
||||
}
|
||||
|
||||
void f128M_neg(const float128_t *aPtr, float128_t *zPtr) {
|
||||
zPtr->v[indexWord(2,1)] = aPtr->v[indexWord(2,1)] ^ (UINT64_C(1) << 63);
|
||||
zPtr->v[indexWord(2,0)] = aPtr->v[indexWord(2,0)];
|
||||
}
|
||||
@@ -5,5 +5,8 @@
|
||||
|
||||
void f128M_abs(const float128_t *aPtr, float128_t *zPtr);
|
||||
void f128M_trunc(const float128_t *aPtr, float128_t *zPtr);
|
||||
void f128M_neg(const float128_t *aPtr, float128_t *zPtr);
|
||||
|
||||
float16_t f16_neg(const float16_t a);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user