Mercurial > pub > dyncall > dyncall
diff dyncallback/dyncall_callback_x86_8a.s @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncallback/dyncall_callback_x86_8a.s Thu Mar 19 22:24:28 2015 +0100 @@ -0,0 +1,100 @@ +/* + + Package: dyncall + Library: dyncall + File: dyncall/dyncall_callback_x86_8a.s + Description: x86 abi callback kernel implementation for Plan9's 8a + License: + + Copyright (c) 2013 Tassilo Philipp <tphilipp@potion-studios.com> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*/ + + +TEXT dcCallbackThunkEntry(SB), $0 + + /* input: + AX -> thunk + AX+16 -> cb handler + AX+20 -> dcargsvt + AX+24 -> stack cleanup <-- not used for stack cleaning as caller cleans up, + AX+28 -> userdata however reused as flag to indicate 64bit return value) + */ + + /* prolog */ + MOVL SP, BP + + /* copy of DCargs passed to cb handler */ + PUSHL $0 /* fast_count (unused on plan9, but using shared x86 dcargs struct) */ + SUBL $8, SP /* skip fast_data[] ( " ) */ + LEAL 8(BP), CX /* ptr to args on stack, depending if return val is 64bit ... */ + CMPL 24(AX), $1 + JEQ is_ll_ret + LEAL 4(BP), CX /* ... or not */ +is_ll_ret: + PUSHL CX + PUSHL 20(AX) /* args vtable ptr */ + MOVL SP, CX /* DCArgs-ptr (data pushed above) */ + + /* space for return value (long long) */ + PUSHL $0 + PUSHL $0 + MOVL SP, DX /* retval ptr */ + + /* call the handler */ + PUSHL 28(AX) /* userdata for handler */ + PUSHL DX /* results */ + PUSHL CX /* args */ + PUSHL AX /* callback obj */ + MOVL 16(AX), AX + CALL AX + + /* copy retval from ptr on stack to AX or stack space if 64bit */ + MOVL 8(SP), BX /* ptr to retval */ + CMPL AX, $0x6c /* 'l' @@@ compares return from handler, might be different from sig - design currently in discussion */ + JEQ ll_ret; + CMPL AX, $0x4c /* 'L' @@@ compares return from handler, might be different from sig - design currently in discussion */ + JEQ ll_ret; + CMPL AX, $0x66 /* 'f' @@@ compares return from handler, might be different from sig - design currently in discussion */ + JEQ f_ret; + CMPL AX, $0x64 /* 'd' @@@ compares return from handler, might be different from sig - design currently in discussion */ + JEQ d_ret; + JMP other_ret + +ll_ret: + MOVL 48(SP), DX /* ptr to ret address space; 48 = stack size + caller's ret address */ + MOVL (BX), CX + MOVL CX, (DX) + MOVL 4(BX), CX + MOVL CX, 4(DX) + JMP cont_ret + +f_ret: + FMOVF (BX), F0 + JMP cont_ret + +d_ret: + FMOVD (BX), F0 + JMP cont_ret + +other_ret: + MOVL (BX), AX /* 32bit non-fp are returned in AX */ + + /* epilog */ +cont_ret: + ADDL $44, SP /* Cleanup stack */ + POPL CX /* hack to emulate RET without getting overly strict */ + JMP CX /* 'unbalanced PUSH/POP' warning/error from 8l */ +