fixes concerning FMADD_S, FMSUB_S, FNMADD_S, and FNSUB_S

mostly about ensuring correct sign
This commit is contained in:
Eyck-Alexander Jentzsch 2024-07-29 21:07:54 +02:00
parent 93d89e07ca
commit 7ffa7667b6
2 changed files with 13 additions and 3 deletions

View File

@ -92,11 +92,14 @@ float32_t
goto infProdArg; goto infProdArg;
} }
if ( expC == 0xFF ) { if ( expC == 0xFF ) {
// expC indicates special value
if ( sigC ) { if ( sigC ) {
//uiC is quiet NaN
uiZ = 0; uiZ = 0;
goto propagateNaN_ZC; goto propagateNaN_ZC;
} }
uiZ = uiC; //uiC is +- infinity
uiZ = (uiC & ~(1UL << 31)) | ((unsigned long)signC << 31); //set sign bit
goto uiZ; goto uiZ;
} }
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
@ -209,12 +212,13 @@ float32_t
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
*------------------------------------------------------------------------*/ *------------------------------------------------------------------------*/
zeroProd: zeroProd:
uiZ = uiC; uiZ = (uiC & ~(1UL << 31)) | ((unsigned long)signC << 31); //set sign bit
if ( ! (expC | sigC) && (signProd != signC) ) { if ( ! (expC | sigC) && (signProd != signC) ) {
completeCancellation: completeCancellation:
uiZ = uiZ =
packToF32UI( packToF32UI(
(softfloat_roundingMode == softfloat_round_min), 0, 0 ); (softfloat_roundingMode == softfloat_round_min), 0, 0 );
uiZ = (uiZ & ~(1UL << 31)) | ((unsigned long)(signC|signProd) << 31); //set sign bit
} }
uiZ: uiZ:
uZ.ui = uiZ; uZ.ui = uiZ;

View File

@ -149,11 +149,17 @@ uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode) {
} }
uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode) { uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode) {
// Used values for op are:
// FMADD_S: 0b00
// FMSUB_S: 0b01
// FNMADD_S: 0b10
// FNMSUB_S: 0b11
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)} // op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
softfloat_roundingMode = rmm_map[mode & 0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0; softfloat_exceptionFlags = 0;
float32_t res = softfloat_mulAddF32(v1, v2, v3, op & 0x1); float32_t res = softfloat_mulAddF32(v1, v2, v3, op & 0x1);
if(op > 1) // Do not invert quiet NaN
if((op & 0b10) && (res.v != quiet_nan32))
res.v ^= 1ULL << 31; res.v ^= 1ULL << 31;
return res.v; return res.v;
} }