1

Does anybody know the difference of "fadd" and "fadds" in Power ISA? As I got, it should be for single precision, but the results are like this:

In a floating point register I have {0,0,1,0}

When I use fadd with itself, the result is 1.7014 that makes sense. But when I use fadds the result is "0". And I don't get why.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
shb8086
  • 31
  • 5
  • 1
    It seems like `fadd` is for double precision, `fadds` for single precision. – fuz Jul 29 '22 at 14:45
  • 3
    Are you looking at the result with a debugger, or passing it to printf? Note that printf is a variadic function in C, so it expects the caller to promote float to double. The `"%f\n"` format string expects a `double`. I don't see how `1.7014` is a sensible result from adding a vector of 0.0 and 1.0 to itself, so this doesn't seem like a [mcve]. – Peter Cordes Jul 29 '22 at 17:56
  • @PeterCordes fadd is a bitwise add, so if you add two ones together (0011111110...0) in floating point representation you will get (0111111100...0). That is 1.7014.. in decimal representation. – shb8086 Aug 02 '22 at 11:38

1 Answers1

2

https://www.ibm.com/docs/en/aix/7.2?topic=set-fadd-fa-floating-add-instruction says fadd is double-precision FP addition, not integer.

But note that adding two subnormal (all-zero exponent field) doubles of the same sign just adds their mantissas, like integer addition, if the result is also subnormal double. (And at least when adding to itself the whole bit-pattern does just shift left by 1, even if the result becomes normalized, as long as it started subnormal. Otherwise the mantissa stays the same and the exponent increments by 1.)

It looks like you have a single-precision bit-pattern like 0x3f800000 (which represents 1.0f) in the low half of a double, and all-zero in the high half. So you have a double with bit-pattern 0x000000003f800000. Adding it to itself doubles it to 0x000000007f000000, left-shifting the mantissa because the result is still subnormal, no change in the exponent. (Representing the value 2.056...E-317)

Taking the low half of that double bit-pattern as a single-precision float with bit-pattern 0x7f000000, it represents a value of 1.7014118346e+38. (https://www.h-schmidt.net/FloatConverter/IEEE754.html)

That's 38 orders of magnitude larger than the 1.7014 result you claimed you got, but those 5 matching digits can't be a concidence. I'm pretty sure this must be what you did. Check how you're printing or viewing your single-precision floating-point numbers to make sure you're not somehow truncating strings to lose the exponent from scientific notation.


IDK what your {0,0,1,0} notation is supposed to mean; the manual says fadd and fadds operate on 64-bit or 32-bit FP registers, not vectors. OTOH I don't know much about POWER / PowerPC or Altivec.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847