diff dyncall/dyncall_callvm_arm32_arm_armhf.c @ 51:9e9d6a90492a r0.9-RC4

- armhf experimental vararg call support
author cslag
date Sun, 20 Dec 2015 20:27:43 +0100
parents c4de113dc1e9
children 67961454902b
line wrap: on
line diff
--- a/dyncall/dyncall_callvm_arm32_arm_armhf.c	Sun Dec 20 15:38:14 2015 +0100
+++ b/dyncall/dyncall_callvm_arm32_arm_armhf.c	Sun Dec 20 20:27:43 2015 +0100
@@ -30,7 +30,7 @@
 
 static DCCallVM* dc_callvm_new_arm32_armhf(DCCallVM_vt* vt, DCsize size)
 {
-  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
+  /* Store at least 16 bytes (4 words for first 4 int args) for internal spill area. Assembly code depends on it. */
   DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)dcAllocMem(sizeof(DCCallVM_arm32_armhf)+size+16);
   dc_callvm_base_init(&p->mInterface, vt);
   dcVecInit(&p->mVecHead, size);
@@ -72,6 +72,7 @@
 static void a_char    (DCCallVM* in_self, DCchar  x) { a_int(in_self, x); }
 static void a_short   (DCCallVM* in_self, DCshort x) { a_int(in_self, x); }
 static void a_long    (DCCallVM* in_self, DClong  x) { a_int(in_self, x); }
+
 static void a_longlong(DCCallVM* in_self, DClonglong x)
 {
   DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)in_self;
@@ -86,6 +87,7 @@
     dcVecAppend(&p->mVecHead, &x, sizeof(DClonglong));
   }
 }
+
 static void a_pointer(DCCallVM* in_p, DCpointer x) { a_int(in_p, (DCint) x ); }
 
 static void a_float(DCCallVM* in_p, DCfloat x)
@@ -100,7 +102,7 @@
     }
   } else {
     dcVecAppend(&p->mVecHead, &x, sizeof(DCfloat));
-  } 
+  }
 }
 
 static void a_double(DCCallVM* in_p, DCdouble x)
@@ -115,21 +117,28 @@
     * (double*) &p->S[p->d] = x;
     p->d += 2;
     if (!(p->s & 1)) {
-      /* if s is even it always equals d. 
-	 otherwise, s points to an odd float register. 
-       */
+      /* if s is even it always equals d. otherwise, s points to an odd float register. */
       p->s = p->d;
     }
   } else {
     p->s = 16; /* fp registers all full - need to use stack now: stop filling gaps for single precision, also */
     v.d = x;
-
     /* 64 bit values need to be aligned on 8 byte boundaries */
     dcVecSkip(&p->mVecHead, dcVecSize(&p->mVecHead) & 4);
     dcVecAppend(&p->mVecHead, &v.b[0], sizeof(DCdouble));
   }
 }
 
+static void a_float_ellipsis(DCCallVM* in_p, DCfloat x)
+{
+  a_int(in_p, *(DCint*)&x);
+}
+
+static void a_double_ellipsis(DCCallVM* in_p, DCdouble x)
+{
+  a_longlong(in_p, *(DClonglong*)&x);
+}
+
 void call(DCCallVM* in_p, DCpointer target)
 {
   DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)in_p;
@@ -143,7 +152,7 @@
 , &mode
 , &a_bool
 , &a_char
-, &a_short 
+, &a_short
 , &a_int
 , &a_long
 , &a_longlong
@@ -164,7 +173,35 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM(DCsize size) 
+DCCallVM_vt vt_armhf_ellipsis =
+{
+  &deinit
+, &reset
+, &mode
+, &a_bool
+, &a_char
+, &a_short
+, &a_int
+, &a_long
+, &a_longlong
+, &a_float_ellipsis
+, &a_double_ellipsis
+, &a_pointer
+, NULL /* argStruct */
+, (DCvoidvmfunc*)       &call
+, (DCboolvmfunc*)       &call
+, (DCcharvmfunc*)       &call
+, (DCshortvmfunc*)      &call
+, (DCintvmfunc*)        &call
+, (DClongvmfunc*)       &call
+, (DClonglongvmfunc*)   &call
+, (DCfloatvmfunc*)      &call
+, (DCdoublevmfunc*)     &call
+, (DCpointervmfunc*)    &call
+, NULL /* callStruct */
+};
+
+DCCallVM* dcNewCallVM(DCsize size)
 {
 #if defined(DC__ABI_ARM_EABI)
   return dc_callvm_new_arm32_arm(&eabi, size);
@@ -180,18 +217,18 @@
 static void mode(DCCallVM* in_self,DCint mode)
 {
   DCCallVM_arm32_armhf* self = (DCCallVM_arm32_armhf*) in_self;
-  DCCallVM_vt*  vt;
   switch(mode) {
-    case DC_CALL_C_DEFAULT:        
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_ARM_ARMHF:
+      self->mInterface.mVTpointer = &vt_armhf;
+      break;
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
-    case DC_CALL_C_ARM_ARMHF:        
-      vt = &vt_armhf;
+      self->mInterface.mVTpointer = &vt_armhf_ellipsis;
       break;
-    default: 
+    default:
       in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
       return;
   }
-  self->mInterface.mVTpointer = vt;
 }