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