Mercurial > pub > dyncall > dyncall
changeset 196:95cf20c0d1de
- sparc64 callbacks:
* floating point support
* fixes for many arg calls
* this completes sparc64 callback support
author | Tassilo Philipp |
---|---|
date | Sun, 19 Mar 2017 19:34:34 +0100 |
parents | be9cb092625f |
children | 53c42b1d9f8b |
files | dyncallback/dyncall_args_sparc64.c dyncallback/dyncall_args_sparc64.h dyncallback/dyncall_callback_sparc64.s |
diffstat | 3 files changed, 72 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/dyncallback/dyncall_args_sparc64.c Sat Mar 18 19:10:01 2017 +0100 +++ b/dyncallback/dyncall_args_sparc64.c Sun Mar 19 19:34:34 2017 +0100 @@ -26,7 +26,7 @@ #include "dyncall_args_sparc64.h" -DCulonglong dcbArgULongLong(DCArgs* p) { return *(DCulonglong*) p->arg_ptr++; } +DCulonglong dcbArgULongLong(DCArgs* p) { return p->arg_ptr[p->i++]; } DClonglong dcbArgLongLong (DCArgs* p) { return (DClonglong)dcbArgULongLong(p); } DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgULongLong(p); } DClong dcbArgLong (DCArgs* p) { return (DClong) dcbArgULongLong(p); } @@ -38,6 +38,18 @@ DCshort dcbArgShort (DCArgs* p) { return (DCshort) dcbArgULongLong(p); } DCbool dcbArgBool (DCArgs* p) { return (DCbool) dcbArgULongLong(p); } DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgULongLong(p); } -DCdouble dcbArgDouble (DCArgs* p) { return *(DCdouble*) p->arg_ptr++; } -DCfloat dcbArgFloat (DCArgs* p) { return *(DCfloat*) p->arg_ptr++; } + +DCdouble dcbArgDouble(DCArgs* p) +{ + return (p->i < DCARGS_SPARC64_NUM_DOUBLE_REGS) + ? p->dreg_data[p->i++] + : *(DCdouble*)(p->arg_ptr + p->i++); +} +DCfloat dcbArgFloat(DCArgs* p) +{ + return (p->i < DCARGS_SPARC64_NUM_DOUBLE_REGS) + ? *((DCfloat*)(p->dreg_data + p->i++)+1) /* +1 bc single-prec fp args are */ + : *((DCfloat*)(p->arg_ptr + p->i++)+1); /* right aligned in 64bit slot */ +} +
--- a/dyncallback/dyncall_args_sparc64.h Sat Mar 18 19:10:01 2017 +0100 +++ b/dyncallback/dyncall_args_sparc64.h Sun Mar 19 19:34:34 2017 +0100 @@ -29,9 +29,13 @@ #include "dyncall_args.h" +#define DCARGS_SPARC64_NUM_DOUBLE_REGS 16 struct DCArgs { - long long *arg_ptr; + /* Don't change order or types, laid out for asm code to fill in! */ + DClonglong *arg_ptr; + DCdouble dreg_data[DCARGS_SPARC64_NUM_DOUBLE_REGS]; + DClonglong i; /* args fetched */ }; #endif /* DYNCALLBACK_ARGS_SPARC64_H */
--- a/dyncallback/dyncall_callback_sparc64.s Sat Mar 18 19:10:01 2017 +0100 +++ b/dyncallback/dyncall_callback_sparc64.s Sun Mar 19 19:34:34 2017 +0100 @@ -39,29 +39,63 @@ dcCallbackThunkEntry: /* Prolog. */ - /* Frame size of 208b comes from needing storage space for the following: */ - /* DCargs(sparc_req_reg_save_area:128 + spill:64 + argptr:8) + retval:8 */ + /* Frame size of 336b comes from needing storage space for the following: */ + /* req_reg_save_area:128 + spill:48 + dcargs:144 + retval:8 + pad:8 */ /* Spill area could theoretically be only 32b, b/c cbHandler function has */ - /* 4 arguments, and retval doesn't need stack, but let's be conservative. */ - save %sp, -208, %sp + /* 4 arguments, but let's be conservative. */ + save %sp, -336, %sp - /* Spill register args. */ - add %fp, BIAS + 136, %l0 - stx %i0, [ %l0 + 0 ] /* reg arg 0 */ - stx %i1, [ %l0 + 8 ] /* reg arg 1 */ - stx %i2, [ %l0 + 16 ] /* reg arg 2 */ - stx %i3, [ %l0 + 24 ] /* reg arg 3 */ - stx %i4, [ %l0 + 32 ] /* reg arg 4 */ - stx %i5, [ %l0 + 40 ] /* reg arg 5 */ - stx %l0, [ %sp + BIAS + 192 ] /* init arg_ptr */ + /* Spill register args as dcargs is based on that (in prev frame, after */ + /* req_reg_save_area). */ + add %fp, BIAS + 128, %l0 + stx %i0, [ %l0 + 0 ] /* reg arg 0 */ + stx %i1, [ %l0 + 8 ] /* reg arg 1 */ + stx %i2, [ %l0 + 16 ] /* reg arg 2 */ + stx %i3, [ %l0 + 24 ] /* reg arg 3 */ + stx %i4, [ %l0 + 32 ] /* reg arg 4 */ + stx %i5, [ %l0 + 40 ] /* reg arg 5 */ + stx %l0, [ %sp + BIAS + 176 ] /* set DCArg's arg_ptr */ + st %f0, [ %sp + BIAS + 184 ] /* store fp args in DCArgs's dreg_data */ + st %f1, [ %sp + BIAS + 188 ] /* @@@ I think stx should work to store */ + st %f2, [ %sp + BIAS + 192 ] /* all 64bits, but I get "Illegal */ + st %f3, [ %sp + BIAS + 196 ] /* Operands", so using single prec. */ + st %f4, [ %sp + BIAS + 200 ] /* store (st) */ + st %f5, [ %sp + BIAS + 204 ] + st %f6, [ %sp + BIAS + 208 ] + st %f7, [ %sp + BIAS + 212 ] + st %f8, [ %sp + BIAS + 216 ] + st %f9, [ %sp + BIAS + 220 ] + st %f10, [ %sp + BIAS + 224 ] + st %f11, [ %sp + BIAS + 228 ] + st %f12, [ %sp + BIAS + 232 ] + st %f13, [ %sp + BIAS + 236 ] + st %f14, [ %sp + BIAS + 240 ] + st %f15, [ %sp + BIAS + 244 ] + st %f16, [ %sp + BIAS + 248 ] + st %f17, [ %sp + BIAS + 252 ] + st %f18, [ %sp + BIAS + 256 ] + st %f19, [ %sp + BIAS + 260 ] + st %f20, [ %sp + BIAS + 264 ] + st %f21, [ %sp + BIAS + 268 ] + st %f22, [ %sp + BIAS + 272 ] + st %f23, [ %sp + BIAS + 276 ] + st %f24, [ %sp + BIAS + 280 ] + st %f25, [ %sp + BIAS + 284 ] + st %f26, [ %sp + BIAS + 288 ] + st %f27, [ %sp + BIAS + 292 ] + st %f28, [ %sp + BIAS + 296 ] + st %f29, [ %sp + BIAS + 300 ] + st %f30, [ %sp + BIAS + 304 ] + st %f31, [ %sp + BIAS + 308 ] + stx %g0, [ %sp + BIAS + 312 ] /* init DCArg's i */ /* Zero retval store. */ - stx %g0, [ %sp + BIAS + 200 ] + stx %g0, [ %sp + BIAS + 320 ] /* Prepare callback handler call. */ mov %g1, %o0 /* Param 0 = DCCallback*, %g1 holds ptr to thunk */ - add %sp, BIAS + 192, %o1 /* Param 1 = DCArgs* (ptr to struct with args ptr) */ - add %sp, BIAS + 200, %o2 /* Param 2 = results ptr to 8b of local stack data */ + add %sp, BIAS + 176, %o1 /* Param 1 = DCArgs* (ptr to struct with args ptr) */ + add %sp, BIAS + 320, %o2 /* Param 2 = results ptr to 8b of local stack data */ ldx [ %g1 + 64 ], %o3 /* Param 3 = userdata ptr */ /* Fetch callback handler address (after thunk blob) and call. */ @@ -70,8 +104,8 @@ nop /* Put retval in %i0 (to be in caller's %o0), and %f0. */ - ldx [ %sp + BIAS + 200 ], %i0 - ldd [ %sp + BIAS + 200 ], %f0 + ldx [ %sp + BIAS + 320 ], %i0 + ldd [ %sp + BIAS + 320 ], %f0 /* Epilog. */ restore /* unshift reg window */