0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_callback_x86_8a.s
|
|
6 Description: x86 abi callback kernel implementation for Plan9's 8a
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2013 Tassilo Philipp <tphilipp@potion-studios.com>
|
|
10
|
|
11 Permission to use, copy, modify, and distribute this software for any
|
|
12 purpose with or without fee is hereby granted, provided that the above
|
|
13 copyright notice and this permission notice appear in all copies.
|
|
14
|
|
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
22
|
|
23 */
|
|
24
|
|
25
|
|
26 TEXT dcCallbackThunkEntry(SB), $0
|
|
27
|
|
28 /* input:
|
|
29 AX -> thunk
|
|
30 AX+16 -> cb handler
|
|
31 AX+20 -> dcargsvt
|
|
32 AX+24 -> stack cleanup <-- not used for stack cleaning as caller cleans up,
|
|
33 AX+28 -> userdata however reused as flag to indicate 64bit return value)
|
|
34 */
|
|
35
|
|
36 /* prolog */
|
|
37 MOVL SP, BP
|
|
38
|
|
39 /* copy of DCargs passed to cb handler */
|
|
40 PUSHL $0 /* fast_count (unused on plan9, but using shared x86 dcargs struct) */
|
|
41 SUBL $8, SP /* skip fast_data[] ( " ) */
|
|
42 LEAL 8(BP), CX /* ptr to args on stack, depending if return val is 64bit ... */
|
|
43 CMPL 24(AX), $1
|
|
44 JEQ is_ll_ret
|
|
45 LEAL 4(BP), CX /* ... or not */
|
|
46 is_ll_ret:
|
|
47 PUSHL CX
|
|
48 PUSHL 20(AX) /* args vtable ptr */
|
|
49 MOVL SP, CX /* DCArgs-ptr (data pushed above) */
|
|
50
|
|
51 /* space for return value (long long) */
|
|
52 PUSHL $0
|
|
53 PUSHL $0
|
|
54 MOVL SP, DX /* retval ptr */
|
|
55
|
|
56 /* call the handler */
|
|
57 PUSHL 28(AX) /* userdata for handler */
|
|
58 PUSHL DX /* results */
|
|
59 PUSHL CX /* args */
|
|
60 PUSHL AX /* callback obj */
|
|
61 MOVL 16(AX), AX
|
|
62 CALL AX
|
|
63
|
|
64 /* copy retval from ptr on stack to AX or stack space if 64bit */
|
|
65 MOVL 8(SP), BX /* ptr to retval */
|
|
66 CMPL AX, $0x6c /* 'l' @@@ compares return from handler, might be different from sig - design currently in discussion */
|
|
67 JEQ ll_ret;
|
|
68 CMPL AX, $0x4c /* 'L' @@@ compares return from handler, might be different from sig - design currently in discussion */
|
|
69 JEQ ll_ret;
|
|
70 CMPL AX, $0x66 /* 'f' @@@ compares return from handler, might be different from sig - design currently in discussion */
|
|
71 JEQ f_ret;
|
|
72 CMPL AX, $0x64 /* 'd' @@@ compares return from handler, might be different from sig - design currently in discussion */
|
|
73 JEQ d_ret;
|
|
74 JMP other_ret
|
|
75
|
|
76 ll_ret:
|
|
77 MOVL 48(SP), DX /* ptr to ret address space; 48 = stack size + caller's ret address */
|
|
78 MOVL (BX), CX
|
|
79 MOVL CX, (DX)
|
|
80 MOVL 4(BX), CX
|
|
81 MOVL CX, 4(DX)
|
|
82 JMP cont_ret
|
|
83
|
|
84 f_ret:
|
|
85 FMOVF (BX), F0
|
|
86 JMP cont_ret
|
|
87
|
|
88 d_ret:
|
|
89 FMOVD (BX), F0
|
|
90 JMP cont_ret
|
|
91
|
|
92 other_ret:
|
|
93 MOVL (BX), AX /* 32bit non-fp are returned in AX */
|
|
94
|
|
95 /* epilog */
|
|
96 cont_ret:
|
|
97 ADDL $44, SP /* Cleanup stack */
|
|
98 POPL CX /* hack to emulate RET without getting overly strict */
|
|
99 JMP CX /* 'unbalanced PUSH/POP' warning/error from 8l */
|
|
100
|