# HG changeset patch # User cslag # Date 1467721257 -7200 # Node ID be08b699dca504317722e8a802cfef405ceec6d9 # Parent f1fc1c836bafc1b0a75c36e08f12e9c55ba08ba8 - mips64 n64 float fixes (big endian), now mips64 n64 is fully supported (for at least big-endian platforms, still need to test little endian) diff -r f1fc1c836baf -r be08b699dca5 dyncall/dyncall_value.h --- a/dyncall/dyncall_value.h Tue Jul 05 14:15:56 2016 +0200 +++ b/dyncall/dyncall_value.h Tue Jul 05 14:20:57 2016 +0200 @@ -48,14 +48,16 @@ union DCValue_ { +/* dyncallback assembly pulls value directly from DCValue structs, without */ +/* knowledge about types used, so lay it out as needed at compile time, here */ #if (defined(DC__Arch_PPC32) || defined(DC__Arch_MIPS)) && defined(DC__Endian_BIG) - DCbool B; + DCbool B; struct { DCchar c_pad[3]; DCchar c; }; struct { DCuchar C_pad[3]; DCuchar C; }; struct { DCshort s_pad; DCshort s; }; struct { DCshort S_pad; DCshort S; }; - DCint i; - DCuint I; + DCint i; + DCuint I; #elif (defined(DC__Arch_PPC64) || defined(DC__Arch_MIPS64)) && defined(DC__Endian_BIG) struct { DCbool B_pad; DCbool B; }; struct { DCchar c_pad[7]; DCchar c; }; @@ -65,22 +67,26 @@ struct { DCint i_pad; DCint i; }; struct { DCint I_pad; DCuint I; }; #else - DCbool B; - DCchar c; - DCuchar C; - DCshort s; - DCushort S; - DCint i; - DCuint I; + DCbool B; + DCchar c; + DCuchar C; + DCshort s; + DCushort S; + DCint i; + DCuint I; #endif - DClong j; - DCulong J; - DClonglong l; - DCulonglong L; - DCfloat f; - DCdouble d; - DCpointer p; - DCstring Z; + DClong j; + DCulong J; + DClonglong l; + DCulonglong L; +#if defined(DC__Arch_MIPS64) && defined(DC__Endian_BIG) + struct { DCfloat f_pad; DCfloat f; }; +#else + DCfloat f; +#endif + DCdouble d; + DCpointer p; + DCstring Z; }; #ifdef __cplusplus diff -r f1fc1c836baf -r be08b699dca5 dyncallback/dyncall_args_mips64.c --- a/dyncallback/dyncall_args_mips64.c Tue Jul 05 14:15:56 2016 +0200 +++ b/dyncallback/dyncall_args_mips64.c Tue Jul 05 14:20:57 2016 +0200 @@ -62,13 +62,20 @@ } return result; } -DCfloat dcbArgFloat(DCArgs* p) { - DCdouble d = dcbArgDouble(p); - return ((DCfloat*)&d) // single precision are stored in double slots, but not promoted +DCfloat dcbArgFloat(DCArgs* p) +{ + DCfloat result; + if(p->reg_count < DCARGS_MIPS_NUM_FREGS) { + result = ((DCfloat*)&p->freg_data[p->reg_count++]) #if defined(DC__Endian_LITTLE) [0]; #else - [1]; + [1]; /* single precision floats are right-justified in big-endian registers */ #endif + } else { + result = *((DCfloat*)p->stackptr); /* single precision floats are left-justified on stack in 64bit slots */ + p->stackptr += sizeof(DCdouble); + } + return result; }