coreboot-libre-fam15h-rdimm/3rdparty/chromeec/core/nds32/math.c

117 lines
1.9 KiB
C

/* Copyright 2017 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "common.h"
#ifdef CONFIG_FPU
union ieee_float_shape_type {
float value;
uint32_t word;
};
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i, d) \
do { \
union ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d, i) \
do { \
union ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
} while (0)
float fabsf(float x)
{
uint32_t ix;
GET_FLOAT_WORD(ix, x);
SET_FLOAT_WORD(x, (ix & 0x7fffffff));
return x;
}
#define FLT_UWORD_IS_ZERO(x) ((x) == 0)
#define FLT_UWORD_IS_SUBNORMAL(x) ((x) < 0x00800000L)
#define FLT_UWORD_IS_FINITE(x) ((x) < 0x7f800000L)
static const float one = 1.0f, tiny = 1.0e-30f;
static float __ieee754_sqrtf(float x)
{
float z;
uint32_t r, hx;
int32_t ix, s, q, m, t, i;
GET_FLOAT_WORD(ix, x);
hx = ix & 0x7fffffff;
/*
* take care of Inf and NaN
* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN
*/
if (!FLT_UWORD_IS_FINITE(hx))
return x * x + x;
/* take care of zero and -ves */
if (FLT_UWORD_IS_ZERO(hx))
return x;
if (ix < 0)
return (x - x) / (x - x);
m = (ix >> 23);
if (FLT_UWORD_IS_SUBNORMAL(hx)) {
for (i = 0; (ix & 0x00800000L) == 0; i++)
ix <<= 1;
m -= i - 1;
}
m -= 127;
ix = (ix & 0x007fffffL) | 0x00800000L;
if (m & 1)
ix += ix;
m >>= 1;
ix += ix;
q = s = 0;
r = 0x01000000L;
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
if (ix != 0) {
z = one - tiny;
if (z >= one) {
z = one + tiny;
if (z > one)
q += 2;
else
q += (q & 1);
}
}
ix = (q >> 1) + 0x3f000000L;
ix += (m << 23);
SET_FLOAT_WORD(z, ix);
return z;
}
float sqrtf(float x)
{
return __ieee754_sqrtf(x);
}
#endif