changeset 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 186af66ae67f
children 67961454902b
files ChangeLog ToDo dyncall/dyncall_callvm_ppc64.c dyncallback/dyncall_args_ppc64.c
diffstat 4 files changed, 75 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Mar 24 23:53:03 2016 +0100
+++ b/ChangeLog	Mon Mar 28 23:46:59 2016 +0200
@@ -3,10 +3,13 @@
 Version 1.0 (upcoming)
 dyncall:
   o better C++ compiler support (for pointer conversions)
-  o fix for PPC64 single-precision floating point args (thanks Masanori!)
+  o PPC64 single-precision float fixes for more than 13 float args (thanks Masanori!)
 dyncallback:
+  o PPC64 single-precision float fixes for more than 13 float args (thanks Masanori!)
 doc:
   o working html doc generation from TEX sources
+bindings:
+  o python: updated to latest signature format (was still on 0.1), cleanup
 
 Version 0.9 (2015/12/31)
 dyncall:
@@ -42,6 +45,7 @@
   o erldc: Erlang binding (thanks Erik!)
 infrastructure:
   o moved to hg
+  o moved bindings to own repository
 
 Version 0.8 (2014/03/24)
 buildsys:
--- a/ToDo	Thu Mar 24 23:53:03 2016 +0100
+++ b/ToDo	Mon Mar 28 23:46:59 2016 +0200
@@ -25,6 +25,9 @@
 - make sure selinux works (esp. regarding NX bits, asm might need (or similar): .section .note.GNU-stack,"",@progbits)
   Daniel has a patch for it, if needed, implementing allocwx with two memory blocks, one for w^x, mmaped to one for r|x
 - support /SAFESEH on cl/win32
+- test code functions should be in .so files, optionally, so the suites can directly
+  be used to test dycnall bindings
+- pkg-config support?
 
 portasm:
 --------
--- 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 */
--- a/dyncallback/dyncall_args_ppc64.c	Thu Mar 24 23:53:03 2016 +0100
+++ b/dyncallback/dyncall_args_ppc64.c	Mon Mar 28 23:46:59 2016 +0200
@@ -50,8 +50,8 @@
 
 DCpointer   dcbArgPointer  (DCArgs* p) { return (DCpointer)dcbArgLongLong(p); }
 
-DCdouble    dcbArgDouble   (DCArgs* p) 
-{ 
+DCdouble    dcbArgDouble   (DCArgs* p)
+{
   DCdouble result;
 
   if (p->freg_count < 13) {
@@ -67,5 +67,26 @@
   return result;
 }
 
-DCfloat     dcbArgFloat    (DCArgs* p) { return (DCfloat)dcbArgDouble(p); }
+DCfloat    dcbArgFloat   (DCArgs* p)
+{
+  DCfloat result;
+
+#if defined(DC__Endian_BIG)
+  struct sf { DCfloat f_pad; DCfloat f; } sf;
+#else /* Endian_LITTLE */
+  struct sf { DCfloat f; DCfloat f_pad; } sf;
+#endif
 
+  if (p->freg_count < 13) {
+    result = (float)p->freg_data[p->freg_count++];
+    if (p->ireg_count < 8) {
+      p->ireg_count++;
+    }
+  } else {
+    sf = * ( (struct sf*) p->stackptr );
+    result = sf.f;
+  }
+
+  p->stackptr += sizeof(double);
+  return result;
+}