# HG changeset patch # User Tassilo Philipp # Date 1489717656 -3600 # Node ID 2f7a7f3472cb18a23eb0a5dd71635a088f73f071 # Parent 06ee88ce4962fa25564ad9e51b2c5b6d8fee14d6 - first draft at sparc64 callbacks (floats not working, yet) diff -r 06ee88ce4962 -r 2f7a7f3472cb dyncallback/dyncall_args_sparc64.c --- a/dyncallback/dyncall_args_sparc64.c Tue Mar 14 00:07:31 2017 +0100 +++ b/dyncallback/dyncall_args_sparc64.c Fri Mar 17 03:27:36 2017 +0100 @@ -6,7 +6,7 @@ Description: Callback's Arguments VM - Implementation for sparc64 - not yet License: - Copyright (c) 2007-2015 Daniel Adler , + Copyright (c) 2007-2017 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -26,17 +26,18 @@ #include "dyncall_args_sparc64.h" -DCint dcbArgInt (DCArgs* p) { return 0; } -DCuint dcbArgUInt (DCArgs* p) { return 0; } -DCulonglong dcbArgULongLong(DCArgs* p) { return 0; } +DCulonglong dcbArgULongLong(DCArgs* p) { return *(DCulonglong*) p->arg_ptr++; } DClonglong dcbArgLongLong (DCArgs* p) { return (DClonglong)dcbArgULongLong(p); } -DClong dcbArgLong (DCArgs* p) { return (DClong) dcbArgUInt(p); } -DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgUInt(p); } -DCchar dcbArgChar (DCArgs* p) { return (DCchar) dcbArgUInt(p); } -DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgUInt(p); } -DCshort dcbArgShort (DCArgs* p) { return (DCshort) dcbArgUInt(p); } -DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgUInt(p); } -DCbool dcbArgBool (DCArgs* p) { return (DCbool) dcbArgUInt(p); } -DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgUInt(p); } -DCdouble dcbArgDouble (DCArgs* p) { return 0.0; } -DCfloat dcbArgFloat (DCArgs* p) { return 0.0f; } +DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgULongLong(p); } +DClong dcbArgLong (DCArgs* p) { return (DClong) dcbArgULongLong(p); } +DCuint dcbArgUInt (DCArgs* p) { return (DCuint) dcbArgULongLong(p); } +DCint dcbArgInt (DCArgs* p) { return (DCint) dcbArgULongLong(p); } +DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgULongLong(p); } +DCchar dcbArgChar (DCArgs* p) { return (DCchar) dcbArgULongLong(p); } +DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgULongLong(p); } +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++; } + diff -r 06ee88ce4962 -r 2f7a7f3472cb dyncallback/dyncall_args_sparc64.h --- a/dyncallback/dyncall_args_sparc64.h Tue Mar 14 00:07:31 2017 +0100 +++ b/dyncallback/dyncall_args_sparc64.h Fri Mar 17 03:27:36 2017 +0100 @@ -6,7 +6,7 @@ Description: Callback's Arguments VM - Header for sparc64 - not yet License: - Copyright (c) 2007-2015 Daniel Adler , + Copyright (c) 2007-2017 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -31,7 +31,7 @@ struct DCArgs { - int dummy; + long long *arg_ptr; }; #endif /* DYNCALLBACK_ARGS_SPARC64_H */ diff -r 06ee88ce4962 -r 2f7a7f3472cb dyncallback/dyncall_callback_sparc64.c --- a/dyncallback/dyncall_callback_sparc64.c Tue Mar 14 00:07:31 2017 +0100 +++ b/dyncallback/dyncall_callback_sparc64.c Fri Mar 17 03:27:36 2017 +0100 @@ -3,10 +3,10 @@ Package: dyncall Library: dyncallback File: dyncallback/dyncall_callback_sparc64.c - Description: Callback - Implementation for sparc64 (TODO: not implemented yet) + Description: Callback - Implementation for sparc64 License: - Copyright (c) 2007-2016 Daniel Adler , + Copyright (c) 2007-2017 Daniel Adler , Tassilo Philipp Permission to use, copy, modify, and distribute this software for any @@ -33,15 +33,16 @@ struct DCCallback { - DCThunk thunk; /* offset 0, size ?? */ - DCCallbackHandler* handler; /* offset ??, size 4 */ - size_t stack_cleanup; /* offset ??, size 4 */ - void* userdata; /* offset ??, size 4 */ + DCThunk thunk; /* offset 0, size 56 */ + DCCallbackHandler* handler; /* offset 56, size 8 */ + void* userdata; /* offset 64, size 8 */ }; void dcbInitCallback(DCCallback* pcb, const char* signature, DCCallbackHandler* handler, void* userdata) { + pcb->handler = handler; + pcb->userdata = userdata; } DCCallback* dcbNewCallback(const char* signature, DCCallbackHandler* handler, void* userdata) diff -r 06ee88ce4962 -r 2f7a7f3472cb dyncallback/dyncall_callback_sparc64.s --- a/dyncallback/dyncall_callback_sparc64.s Tue Mar 14 00:07:31 2017 +0100 +++ b/dyncallback/dyncall_callback_sparc64.s Fri Mar 17 03:27:36 2017 +0100 @@ -3,11 +3,10 @@ Package: dyncall Library: dyncallback File: dyncallback/dyncall_callback_sparc64.s - Description: Callback Thunk - Implementation for Sparc 64-bit + Description: Callback - Implementation for Sparc 64-bit License: - Copyright (c) 2007-2011 Daniel Adler , - Tassilo Philipp + Copyright (c) 2017 Tassilo Philipp Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -23,8 +22,59 @@ */ +/* input: + $i0 -> thunk + $i0+56 -> cb handler + $i0+64 -> userdata +*/ + +/* NOTE: %sp/%fp for v9 are offset, using them needs a "BIAS" of 2047 */ +.set BIAS, 2047 + +.text .globl dcCallbackThunkEntry + +/* Called by thunk - thunk stores pointer to DCCallback */ +/* in %g1, and pointer to called function in %g2 */ dcCallbackThunkEntry: - jmpl %i7 + 8, %g0 /* Return from proc. */ - nop + + /* 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 */ + /* 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 + + /* 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 */ + + /* Zero retval store. */ + stx %g0, [ %sp + BIAS + 200 ] + /* 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 */ + ldx [ %g1 + 64 ], %o3 /* Param 3 = userdata ptr */ + + /* Fetch callback handler address (after thunk blob) and call. */ + ldx [ %g1 + 56 ], %l0 + call %l0 + nop + + /* Put retval in %i0 (to be in caller's %o0), and %f0. */ + ldx [ %sp + BIAS + 200 ], %i0 + ldd [ %sp + BIAS + 200 ], %f0 + + /* Epilog. */ + restore /* unshift reg window */ + retl /* Return from proc. -- jmpl %i7 + 8, %g0 */ + nop +