Mercurial > pub > dyncall > dyncall
diff dyncall/dyncall_callvm_arm64.c @ 371:451299d50c1a
- windows arm64 support (dyncall, dyncallback, cmake support for armasm64), thanks Bernhard Urban-Forster!
- minor cleanups
author | Tassilo Philipp |
---|---|
date | Fri, 25 Dec 2020 18:07:39 +0100 |
parents | ad5f9803f52f |
children | 041cb6ad4d50 |
line wrap: on
line diff
--- a/dyncall/dyncall_callvm_arm64.c Sat Dec 19 20:02:08 2020 +0100 +++ b/dyncall/dyncall_callvm_arm64.c Fri Dec 25 18:07:39 2020 +0100 @@ -26,6 +26,7 @@ #include "dyncall_callvm_arm64.h" #include "dyncall_alloc.h" +#include "dyncall_macros.h" void dcCall_arm64(DCpointer target, DCpointer data, DCsize size, DCpointer regdata); @@ -74,7 +75,7 @@ p->f++; } else { dcVecAppend(&p->mVecHead, &x, sizeof(DCfloat)); - dcVecSkip(&p->mVecHead, 4); /* align to 8-bytes */ + dcVecSkip(&p->mVecHead, 4); /* align to 8-bytes */ } } @@ -130,16 +131,69 @@ , NULL /* callStruct */ }; +#ifdef DC__OS_Win64 +/* for variadic, allocate arguments to an imaginary stack, where the first 64 bytes of + the stack are loaded into x0-x7, and any remaining arguments on the stack */ + +static void var_bool (DCCallVM* in_p, DCbool x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_char (DCCallVM* in_p, DCchar x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_short (DCCallVM* in_p, DCshort x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_int (DCCallVM* in_p, DCint x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_long (DCCallVM* in_p, DClong x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_pointer (DCCallVM* in_p, DCpointer x) { a_i64( in_p, ((DClonglong) x) ); } +static void var_float (DCCallVM* in_p, DCfloat x) { + DClonglong tmp = 0; + memcpy(&tmp, &x, sizeof(DCfloat)); + a_i64(in_p, tmp); +} +static void var_double (DCCallVM* in_p, DCdouble x) { + a_i64(in_p, *(DClonglong *)&x); +} + +DCCallVM_vt vt_arm64_win_varargs = +{ + &deinit +, &reset +, &mode +, &var_bool +, &var_char +, &var_short +, &var_int +, &var_long +, &a_i64 +, &var_float +, &var_double +, &var_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 */ +}; +#endif + static void mode(DCCallVM* in_self, DCint mode) { DCCallVM_arm64* self = (DCCallVM_arm64*)in_self; DCCallVM_vt* vt; switch(mode) { + case DC_CALL_C_ELLIPSIS: + case DC_CALL_C_ELLIPSIS_VARARGS: +#ifdef DC__OS_Win64 + vt = &vt_arm64_win_varargs; + break; +#endif /* if not win64, use below */ + case DC_CALL_SYS_DEFAULT: case DC_CALL_C_DEFAULT: case DC_CALL_C_ARM64: - case DC_CALL_C_ELLIPSIS: - case DC_CALL_C_ELLIPSIS_VARARGS: vt = &vt_arm64; break; default: