On 5/6/22 07:18, Lucas Mateus Castro(alqotel) wrote:
+static inline float32 float32_neg(float32 a)
+{
+ if (((a & 0x7f800000) == 0x7f800000) && (a & 0x007fffff)) {
+ return a;
+ } else {
+ return float32_chs(a);
+ }
+}
This is wrong -- even NaNs get their signs changed.
Negation and absolute value are non-arithmetic operations.
If you're matching hardware results, this suggests...
+ if (neg_mul) {
+ msum = float32_neg(msum);
+ }
+ if (neg_acc) {
+ aux_acc = float32_neg(at[i].VsrSF(j));
+ } else {
+ aux_acc = at[i].VsrSF(j);
+ }
+ at[i].VsrSF(j) = float32_add(msum, aux_acc, excp_ptr);
This "add" should be "sub" instead of using a separate negation, when required.
I do wonder about the double-negation vs nans.
It looks like this could be
float32_muladd(float32_one, msum, aux_acc, flags, &status)
with flags set to float_muladd_negate_* for neg_mul and neg_acc. Any NaNs would go
through pick_nan_muladd and fail to be altered.
I'm not sure if I'm suggesting actual use of muladd, for the simplicity, or if you should
have an inline check for nans. I might need to think about this in the morning.
r~