0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncallback
|
|
5 File: dyncallback/dyncall_callback_x86.S
|
|
6 Description: Callback Thunk entry for x86
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2011-2015 Daniel Adler <dadler@uni-goettingen.de>
|
|
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 #include "../portasm/portasm-x86.S"
|
|
27 BEGIN_ASM
|
|
28 DCThunk_size = 16
|
|
29 DCArgs_size = 20
|
|
30 DCValue_size = 8
|
|
31
|
|
32 CTX_thunk = 0
|
|
33 CTX_phandler = 16
|
|
34 CTX_pargsvt = 20
|
|
35 CTX_stack_cleanup = 24
|
|
36 CTX_userdata = 28
|
|
37
|
|
38 frame_arg0 = 8
|
|
39 frame_ret = 4
|
|
40 frame_parent = 0
|
|
41 frame_CTX = -4
|
|
42 frame_DCArgs = -24
|
|
43 frame_DCValue = -32
|
|
44
|
|
45 #define ASCII_L 76
|
|
46 #define ASCII_l 108
|
|
47 #define ASCII_d 100
|
|
48 #define ASCII_f 102
|
|
49 #define ASCII_i 105
|
|
50 #define ASCII_v 118
|
|
51
|
|
52 GLOBAL(dcCallbackThunkEntry)
|
|
53 BEGIN_PROC(dcCallbackThunkEntry)
|
|
54 PUSH(EBP)
|
|
55 MOVL(ESP,EBP)
|
|
56 /* local variable frame_CTX) */
|
|
57 PUSH(EAX) /* EAX = CTX* */
|
|
58 /* initialize DCArgs */
|
|
59 PUSH(LIT(0)) /* fast_count */
|
|
60 PUSH(EDX) /* fast_data[1] */
|
|
61 PUSH(ECX) /* fast_data[0] */
|
|
62 LEA(DWORD(EBP,frame_arg0),ECX) /* compute arg stack address */
|
|
63 PUSH(ECX) /* stack-ptr */
|
|
64 PUSH(DWORD(EAX,CTX_pargsvt)) /* vtbl-ptr */
|
|
65 MOVL(ESP,ECX) /* ECX = DCArgs* */
|
|
66 /* initialize DCvalue */
|
|
67 PUSH(LIT(0))
|
|
68 PUSH(LIT(0))
|
|
69
|
|
70 MOVL(ESP,EDX) /* EDX = DCValue* */
|
|
71 ANDL(LIT(-16),ESP) /* align stack to 16 bytes. */
|
|
72 /* call handler(context) */
|
|
73 PUSH(DWORD(EAX,CTX_userdata)) /* userdata */
|
|
74 PUSH(EDX) /* DCValue* */
|
|
75 PUSH(ECX) /* DCargs* */
|
|
76 PUSH(EAX) /* DCCallback* */
|
|
77 CALL_DWORD(EAX,CTX_phandler)
|
|
78 /* cleanup stack */
|
|
79 MOVL(EBP,ESP) /* reset esp to frame */
|
|
80 POP(ECX) /* skip parent frame */
|
|
81 POP(ECX) /* pop return address */
|
|
82 MOVL(DWORD(EBP,frame_CTX),EDX)
|
|
83 ADD(DWORD(EDX,CTX_stack_cleanup),ESP) /* cleanup stack */
|
|
84 PUSH(ECX) /* push back return address */
|
|
85 LEA(DWORD(EBP,frame_DCValue), EDX)
|
|
86 MOVL(DWORD(EBP,0), EBP) /* EBP = parent frame */
|
|
87 /* handle return value */
|
|
88
|
|
89 CMP(LIT(ASCII_f),AL)
|
|
90 JE(LOCAL(return_f32))
|
|
91 CMP(LIT(ASCII_d),AL)
|
|
92 JE(LOCAL(return_f64))
|
|
93
|
97
|
94 /* All int cases (+ pointer & string cases) fall in the return_i64 case, here */
|
0
|
95 LOCAL(return_i64):
|
|
96 MOVL(DWORD(EDX,0),EAX)
|
|
97 MOVL(DWORD(EDX,4),EDX)
|
|
98 RET()
|
|
99 LOCAL(return_f32):
|
|
100 FLDS(DWORD(EDX,0))
|
|
101 RET()
|
|
102 LOCAL(return_f64):
|
|
103 FLDL(QWORD(EDX,0))
|
|
104 LOCAL(return_void):
|
|
105 RET()
|
|
106 END_PROC(dcCallbackThunkEntry)
|
|
107 END_ASM
|
|
108
|