initial RISC-V support (#2614)

Unlike related PR #2344 that simply warns about unsupported FTZ, this PR
attempts to correctly handle FTZ on RISC-V.
RISC-V 'f' extension does not support any way to enable/disable flushing
subnormals to zero, implementations are required to always support
subnormals. Therefore this PR re-uses FTZ handling code from PPC, where
flushing also has to be explicitly performed.
This commit is contained in:
Michal Babej
2026-03-17 18:25:59 +02:00
committed by GitHub
parent 6506421614
commit 4e3f16b2b9
7 changed files with 32 additions and 18 deletions

View File

@@ -859,7 +859,9 @@ double reference_add(double x, double y)
__m128 vb = _mm_set_ss((float)b);
va = _mm_add_ss(va, vb);
_mm_store_ss((float *)&a, va);
#elif defined(__PPC__)
#elif defined(__PPC__) || defined(__riscv)
// RISC-V CPUs with default 'f' fp32 extension do not support any way to
// enable/disable FTZ mode, subnormals are always handled without flushing.
// Most Power host CPUs do not support the non-IEEE mode (NI) which flushes
// denorm's to zero. As such, the reference add with FTZ must be emulated in
// sw.
@@ -876,7 +878,7 @@ double reference_add(double x, double y)
} ub;
ub.d = b;
cl_uint mantA, mantB;
cl_ulong addendA, addendB, sum;
cl_ulong addendA, addendB;
int expA = extractf(a, &mantA);
int expB = extractf(b, &mantB);
cl_uint signA = ua.u & 0x80000000U;
@@ -972,7 +974,7 @@ double reference_multiply(double x, double y)
__m128 vb = _mm_set_ss((float)b);
va = _mm_mul_ss(va, vb);
_mm_store_ss((float *)&a, va);
#elif defined(__PPC__)
#elif defined(__PPC__) || defined(__riscv)
// Most Power host CPUs do not support the non-IEEE mode (NI) which flushes
// denorm's to zero. As such, the reference multiply with FTZ must be
// emulated in sw.
@@ -3351,7 +3353,7 @@ long double reference_cbrtl(long double x)
long double reference_rintl(long double x)
{
#if defined(__PPC__)
#if defined(__PPC__) || defined(__riscv)
// On PPC, long doubles are maintained as 2 doubles. Therefore, the combined
// mantissa can represent more than LDBL_MANT_DIG binary digits.
x = rintl(x);