Mercurial > pub > dyncall > dyncall
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; }