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
?
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.