bowl
bowl

Reputation: 559

How can I move an 80-bit floating point number with double precision from memory to XMM0 in AT&T assembly

I've written an AT&T assembly function to calculate an integral. I need to pass it as a return value as it's called by code written in C. I've successfully managed to return it as a single precision float and a double precision double. But I know I can calculate it in 80-bit double extended precision and I'd love to pass it to C.

Let's assume the value I want to pass is pointed to in an FPU register pointed by TOP. Here's how I call functions.

For float:

//C
double  integ_fo=integ_asm_fpu_fl();

#asm
...  
fstps   max        # Fpu STore and Pop Short <- short for 32-bit
movss   max, %xmm0 # MOVe Scalar Single precision   

For double:

//C
double  integ_do=integ_asm_fpu_do();

#asm
...  
fstpl   max        # Fpu STore and Pop Long <- long for 64-bit
movsd   max, %xmm0 # MOVe Scalar Dingle precision 

My question is now: how can I complete following code, so that C can read long double from the %XMM0 register.

For long double:

//C
long double  integ_lo=integ_asm_fpu_lo();

#asm
...  
fstpt   max        # FPU Store and Pop exTended <- extended for 80-bit

What should I do after that? How would I move 80 bits from max to %XMM0?

Upvotes: 2

Views: 623

Answers (1)

Jester
Jester

Reputation: 58792

Your premise is wrong:

how can I complete following code, so that C can read long double from the %XMM0 register.

The sysv abi does not return long double in xmm0 register, but st0. The relevant part of the documentation:

The 64-bit mantissa of arguments of type long double belongs to class X87, the 16-bit exponent plus 6 bytes of padding belongs to class X87UP.

If the class is X87UP, the value is returned together with the previous X87 value in %st0.

Apparently you already have the value in st0 so you don't have to do anything just leave it there, meaning delete the fstpt in your example.

Upvotes: 4

Related Questions