1

I know 1/2/4-byte integers are returned in eax, and 8-byte integers are returned in eax:edx.

By the way, how are 4/8/16-byte floating-point values (Maybe I remember long double might be 16 bytes..) returned in cdecl/stdcall?


Thanks to @MatteoItalia, I know that VC++'s long double is 8-byte; Then, how can I use 16-byte floating-point?

(Don't say me "just use 8 byte!". I really need it.)

Um, I think I should be satisfied with 10-byte floating point...

phuclv
  • 37,963
  • 15
  • 156
  • 475
ikh
  • 10,119
  • 1
  • 31
  • 70

2 Answers2

4

FP return values are returned in the ST0 x87 register (see e.g. here).

By the way, in VC++ long double (which in x87 is 80 bit) is effectively a synonym for double.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • @ikh: there's no native 128 bit FP support on x86 (or on any widespread platform that I know of), you probably have to look for some library that implements it in software (but it's going to be significantly slower than hardware-based FP). By the way, why do you need such a precise type? – Matteo Italia Jan 26 '14 at 11:46
  • @MetteoItalia um, I should be satisfied with 10 byte floating point.. I'm writing a tiny byte-code, interpreted language and there's some need for 16byte floating-point..., but I should use 10byte one as 16byte – ikh Jan 26 '14 at 11:50
  • @ikh: x87 does support 80 bit (=10 byte) FP, but VC++ does not expose this functionality. g++ OTOH does provide it (at least on Linux) via the type `long double`. I think that even in that case the return value will stay in ST0. – Matteo Italia Jan 26 '14 at 12:05
1

You didn't provide the architecture but x86 returns floating-point values in ST(0) and x86_64 return in XMM0. See x86 calling conventions

But long double in VC for x86 and x86_64 is the same as double and won't provide you any more precision. So on Windows to do 80-bit floating-point operations you need to use another compiler such as GCC, Clang or ICC. Also, 80-bit long double is calculated by x87 so it may perform worse than a good SSE library.

If you need more than 10-byte long double then you must implement your own floating-point library or use some external libraries. GCC 4.3 and above have built-in support for __float128 through a soft library. See long double (GCC specific) and __float128

Another approach is using double-double to implement near-quadruple precision values like in PowerPC or SPARC. It's not IEEE compatible but you can utilize hardware double suport to speedup so it'll be faster than soft __float128

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • 1
    Also on Windows, the MSVCRT code sets the x87 significand precision to 53-bit (`double`) before `main`, so if your GCC/Clang code is linked with that then you need to manually set it back to the default 64-bit significand full precision. https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/ – Peter Cordes May 31 '19 at 06:13