feat: add scalar fexp support
This commit is contained in:
@@ -37,6 +37,7 @@ extern "C" {
|
||||
|
||||
void dpi_fdiv(bool enable, int dst_fmt, int64_t a, int64_t b, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags);
|
||||
void dpi_fsqrt(bool enable, int dst_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags);
|
||||
void dpi_fexp(bool enable, int dst_fmt, int64_t a, int64_t* result, svBitVecVal* fflags);
|
||||
|
||||
void dpi_ftoi(bool enable, int dst_fmt, int src_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags);
|
||||
void dpi_ftou(bool enable, int dst_fmt, int src_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags);
|
||||
@@ -83,6 +84,22 @@ inline int64_t check_boxing(int64_t a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float bits_to_float(uint32_t value) {
|
||||
union {
|
||||
uint32_t u;
|
||||
float f;
|
||||
} bits = {value};
|
||||
return bits.f;
|
||||
}
|
||||
|
||||
inline uint32_t float_to_bits(float value) {
|
||||
union {
|
||||
float f;
|
||||
uint32_t u;
|
||||
} bits = {value};
|
||||
return bits.u;
|
||||
}
|
||||
|
||||
void dpi_fadd(bool enable, int dst_fmt, int64_t a, int64_t b, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags) {
|
||||
if (!enable)
|
||||
return;
|
||||
@@ -173,6 +190,38 @@ void dpi_fsqrt(bool enable, int dst_fmt, int64_t a, const svBitVecVal* frm, int6
|
||||
}
|
||||
}
|
||||
|
||||
void dpi_fexp(bool enable, int dst_fmt, int64_t a, int64_t* result, svBitVecVal* fflags) {
|
||||
if (!enable)
|
||||
return;
|
||||
*fflags = 0;
|
||||
if (dst_fmt) {
|
||||
double input;
|
||||
static_assert(sizeof(input) == sizeof(a), "unexpected double size");
|
||||
__builtin_memcpy(&input, &a, sizeof(input));
|
||||
double output = exp(input);
|
||||
__builtin_memcpy(result, &output, sizeof(output));
|
||||
if (isinf(output) && isfinite(input)) {
|
||||
*fflags |= 0x05; // OF | NX
|
||||
} else if (output == 0.0 && input < 0.0 && isfinite(input)) {
|
||||
*fflags |= 0x03; // UF | NX
|
||||
} else if (isfinite(input)) {
|
||||
*fflags |= 0x01; // NX
|
||||
}
|
||||
} else {
|
||||
uint32_t boxed = static_cast<uint32_t>(check_boxing(a));
|
||||
float input = bits_to_float(boxed);
|
||||
float output = expf(input);
|
||||
*result = nan_box(float_to_bits(output));
|
||||
if (isinf(output) && isfinite(input)) {
|
||||
*fflags |= 0x05; // OF | NX
|
||||
} else if (output == 0.0f && input < 0.0f && isfinite(input)) {
|
||||
*fflags |= 0x03; // UF | NX
|
||||
} else if (isfinite(input)) {
|
||||
*fflags |= 0x01; // NX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dpi_ftoi(bool enable, int dst_fmt, int src_fmt, int64_t a, const svBitVecVal* frm, int64_t* result, svBitVecVal* fflags) {
|
||||
if (!enable)
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user