Mercurial > pub > dyncall > dyncall
diff dyncall/dyncall_callvm_ppc64.c @ 83:54930a037e8a
- PPC64 single-precision float fixes for more than 13 float args (thanks Masanori!)
- changelog and todo update
author | cslag |
---|---|
date | Mon, 28 Mar 2016 23:46:59 +0200 |
parents | 7ca57dbefed4 |
children | 67961454902b |
line wrap: on
line diff
--- a/dyncall/dyncall_callvm_ppc64.c Thu Mar 24 23:53:03 2016 +0100 +++ b/dyncall/dyncall_callvm_ppc64.c Mon Mar 28 23:46:59 2016 +0200 @@ -74,7 +74,7 @@ { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; - if (self->mFloatRegs < 13) { + if (self->mFloatRegs < 13) { self->mRegData.mFloatData[self->mFloatRegs++] = d; if (self->mIntRegs < 8) { self->mRegData.mIntData[self->mIntRegs++] = *( (DClonglong*) &d ); @@ -82,7 +82,7 @@ return; #endif } - } + } #if DC__ABI_PPC64_ELF_V == 2 if (dcVecSize(&self->mVecHead) == 0) { @@ -99,10 +99,10 @@ { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; - if (dcVecSize(&self->mVecHead) == 0) + if (dcVecSize(&self->mVecHead) == 0) dcVecSkip(&self->mVecHead,(sizeof(DClonglong))*(self->mIntRegs)); - if (self->mFloatRegs < 13) { + if (self->mFloatRegs < 13) { self->mRegData.mFloatData[self->mFloatRegs++] = d; if (self->mIntRegs < 8) { self->mRegData.mIntData[self->mIntRegs++] = *( (DClonglong*) &d ); @@ -116,19 +116,55 @@ /* Floating-point */ - + static void dc_callvm_argFloat_ppc64(DCCallVM* in_self, DCfloat f) { + DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; + + DCdouble d; +#if defined(DC__Endian_BIG) + struct { DCfloat f_pad; DCfloat f; } sf; +#else /* Endian_LITTLE */ + struct { DCfloat f; DCfloat f_pad; } sf; +#endif + + if (self->mFloatRegs < 13) { + d = (DCdouble)f; + self->mRegData.mFloatData[self->mFloatRegs++] = d; + if (self->mIntRegs < 8) { + self->mRegData.mIntData[self->mIntRegs++] = *( (DClonglong*) &d ); +#if DC__ABI_PPC64_ELF_V == 2 + return; +#endif + } + } + +#if DC__ABI_PPC64_ELF_V == 2 + if (dcVecSize(&self->mVecHead) == 0) { + dcVecSkip(&self->mVecHead,sizeof(DClonglong)*8); + } +#endif + + /* push on stack */ + sf.f = f; + dcVecAppend(&self->mVecHead,(DCpointer) &sf,sizeof(DCdouble)); +} + +#if DC__ABI_PPC64_ELF_V == 2 +static void dc_callvm_argFloat_ppc64_ellipsis(DCCallVM* in_self, DCfloat f) +{ /* promote to double */ dcArgDouble(in_self, (DCdouble) f ); } +#endif + /* long long integer */ static void dc_callvm_argLongLong_ppc64(DCCallVM* in_self, DClonglong L) { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; - + /* fillup integer register file */ if (self->mIntRegs < 8) { self->mRegData.mIntData[self->mIntRegs++] = L; @@ -259,7 +295,7 @@ , &dc_callvm_argInt_ppc64 , &dc_callvm_argLong_ppc64 , &dc_callvm_argLongLong_ppc64_ellipsis -, &dc_callvm_argFloat_ppc64 +, &dc_callvm_argFloat_ppc64_ellipsis , &dc_callvm_argDouble_ppc64_ellipsis , &dc_callvm_argPointer_ppc64 , NULL /* argStruct */