diff dyncallback/dyncall_args_mips_o32.c @ 104:dbca6763f2be

- complete, working mips o32 callback (using hardware fp); fixes error from last commit, which ignored first 2 float args * currently tested on little endian, only * todo update, manual update, cleanups
author cslag
date Thu, 09 Jun 2016 15:13:53 +0200
parents b7a9b524f0c3
children 9e677d4c0b6b
line wrap: on
line diff
--- a/dyncallback/dyncall_args_mips_o32.c	Wed Jun 08 02:27:12 2016 +0200
+++ b/dyncallback/dyncall_args_mips_o32.c	Thu Jun 09 15:13:53 2016 +0200
@@ -29,6 +29,7 @@
 DCint dcbArgInt(DCArgs* p)
 {
   DCint value;
+  p->freg_count = 2; // first int will disable float reg use.
   value = *((int*)p->stackptr);
   p->stackptr += sizeof(int);
   return value;
@@ -62,8 +63,22 @@
 DCfloat dcbArgFloat(DCArgs* p)
 {
   DCfloat result;
-  result = *((float*)p->stackptr);
-  p->stackptr += sizeof(float);
+  if(p->freg_count < 2) {
+	// Stored float regs (max 2) are always 8b aligned. The way we look them up,
+	// relative to a diverging p->stackptr, we need consider this. Only works
+	// with up to two float args, which is all we need. Hacky, but saves us
+	// from one more variable and more bookkeeping in DCArgs.
+    result = ((DCfloat*)(p->stackptr + ((int)p->stackptr & 4)) - 4) // '-4' b/c those regs are stored right before the args
+#if defined(DC__Endian_LITTLE)
+      [0];
+#else
+      [1];
+#endif
+	++p->freg_count;
+  } else {
+    result = *((DCfloat*)p->stackptr);
+  }
+  p->stackptr += sizeof(DCfloat);
   return result;
 }
 DCdouble dcbArgDouble(DCArgs* p)
@@ -73,13 +88,17 @@
     DCfloat f[2];
   } d;
   p->stackptr += ((int)p->stackptr & 4); // Skip one slot if not aligned.
-#if defined(DC__Endian_LITTLE)
-  d.f[0] = dcbArgFloat(p);
-  d.f[1] = dcbArgFloat(p);
-#else
-  d.f[1] = dcbArgFloat(p);
-  d.f[0] = dcbArgFloat(p);
-#endif
+  if(p->freg_count < 2) {
+    //result = *((DCdouble*)p->stackptr-2); this changes the value, slightly
+    d.f[0] = ((DCfloat*)p->stackptr-4)[0]; // '-4' b/c those regs are stored right before the args
+    d.f[1] = ((DCfloat*)p->stackptr-4)[1];
+    ++p->freg_count;
+  } else {
+    //result = *((DCdouble*)p->stackptr); this changes the value, slightly
+    d.f[0] = ((DCfloat*)p->stackptr)[0];
+    d.f[1] = ((DCfloat*)p->stackptr)[1];
+  }
+  p->stackptr += sizeof(DCdouble);
   return d.result;
 }