changeset 126:be08b699dca5

- mips64 n64 float fixes (big endian), now mips64 n64 is fully supported (for at least big-endian platforms, still need to test little endian)
author cslag
date Tue, 05 Jul 2016 14:20:57 +0200
parents f1fc1c836baf
children 645443fcfb47
files dyncall/dyncall_value.h dyncallback/dyncall_args_mips64.c
diffstat 2 files changed, 35 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/dyncall/dyncall_value.h	Tue Jul 05 14:15:56 2016 +0200
+++ b/dyncall/dyncall_value.h	Tue Jul 05 14:20:57 2016 +0200
@@ -48,14 +48,16 @@
 
 union DCValue_
 {
+/* dyncallback assembly pulls value directly from DCValue structs, without   */
+/* knowledge about types used, so lay it out as needed at compile time, here */
 #if (defined(DC__Arch_PPC32) || defined(DC__Arch_MIPS)) && defined(DC__Endian_BIG)
-  DCbool        B;
+  DCbool      B;
   struct { DCchar  c_pad[3]; DCchar  c; };
   struct { DCuchar C_pad[3]; DCuchar C; };
   struct { DCshort s_pad;    DCshort s; };
   struct { DCshort S_pad;    DCshort S; };
-  DCint         i;
-  DCuint        I;
+  DCint       i;
+  DCuint      I;
 #elif (defined(DC__Arch_PPC64) || defined(DC__Arch_MIPS64)) && defined(DC__Endian_BIG)
   struct { DCbool  B_pad;    DCbool  B; };
   struct { DCchar  c_pad[7]; DCchar  c; };
@@ -65,22 +67,26 @@
   struct { DCint   i_pad;    DCint   i; };
   struct { DCint   I_pad;    DCuint  I; };
 #else
-  DCbool        B;
-  DCchar        c;
-  DCuchar       C;
-  DCshort       s;
-  DCushort      S;
-  DCint         i;
-  DCuint        I;
+  DCbool      B;
+  DCchar      c;
+  DCuchar     C;
+  DCshort     s;
+  DCushort    S;
+  DCint       i;
+  DCuint      I;
 #endif
-  DClong        j;
-  DCulong       J;
-  DClonglong    l;
-  DCulonglong   L;
-  DCfloat       f;
-  DCdouble      d;
-  DCpointer     p;
-  DCstring      Z;
+  DClong      j;
+  DCulong     J;
+  DClonglong  l;
+  DCulonglong L;
+#if defined(DC__Arch_MIPS64) && defined(DC__Endian_BIG)
+  struct { DCfloat f_pad; DCfloat f; };
+#else
+  DCfloat     f;
+#endif
+  DCdouble    d;
+  DCpointer   p;
+  DCstring    Z;
 };
 
 #ifdef __cplusplus
--- a/dyncallback/dyncall_args_mips64.c	Tue Jul 05 14:15:56 2016 +0200
+++ b/dyncallback/dyncall_args_mips64.c	Tue Jul 05 14:20:57 2016 +0200
@@ -62,13 +62,20 @@
   }
   return result;
 }
-DCfloat dcbArgFloat(DCArgs* p) {
-    DCdouble d = dcbArgDouble(p);
-	return ((DCfloat*)&d) // single precision are stored in double slots, but not promoted
+DCfloat dcbArgFloat(DCArgs* p)
+{
+  DCfloat result;
+  if(p->reg_count < DCARGS_MIPS_NUM_FREGS) {
+    result = ((DCfloat*)&p->freg_data[p->reg_count++])
 #if defined(DC__Endian_LITTLE)
       [0];
 #else
-      [1];
+      [1]; /* single precision floats are right-justified in big-endian registers */
 #endif
+  } else {
+    result = *((DCfloat*)p->stackptr); /* single precision floats are left-justified on stack in 64bit slots */
+    p->stackptr += sizeof(DCdouble);
+  }
+  return result;
 }