Mercurial > pub > dyncall > dyncall
comparison dyncallback/dyncall_callback_ppc32_apple.s @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children | df556fd8ea37 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3e629dc19168 |
---|---|
1 /* | |
2 | |
3 Package: dyncall | |
4 Library: dyncallback | |
5 File: dyncallback/dyncall_callback_ppc32_apple.s | |
6 Description: Callback Thunk - PowerPC 32-bit System V ABI | |
7 License: | |
8 | |
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>, | |
10 Tassilo Philipp <tphilipp@potion-studios.com> | |
11 | |
12 Permission to use, copy, modify, and distribute this software for any | |
13 purpose with or without fee is hereby granted, provided that the above | |
14 copyright notice and this permission notice appear in all copies. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 | |
24 */ | |
25 | |
26 .machine ppc | |
27 .text | |
28 .align 2 | |
29 | |
30 /* Callback Thunk Entry code for PowerPC 32-bit Darwin/Apple Mac OS X. */ | |
31 | |
32 | |
33 /* Stack Frame Layout: | |
34 | |
35 204 DCValue ( ) | |
36 56 DCArgs (32+104+4+8 = 148) | |
37 24 Parameter area ( 4*8 = 32 ) | |
38 0 Linkage area ( 24 ) | |
39 | |
40 | |
41 */ | |
42 | |
43 /* Constants. */ | |
44 INT_REGS = 8 | |
45 FLOAT_REGS = 13 | |
46 SIZEOF_INT = 4 | |
47 SIZEOF_DOUBLE = 8 | |
48 | |
49 | |
50 /* Linkage area. */ | |
51 LINK_SP = 0 | |
52 LINK_CR = 4 | |
53 LINK_LR = 8 | |
54 LINK_OFFSET = 0 | |
55 LINK_SIZE = 24 | |
56 /* Parameter area. */ | |
57 PAR_OFFSET = LINK_SIZE | |
58 PAR_SIZE = 32 | |
59 /* local struct DCArgs */ | |
60 ARGS_OFFSET = (PAR_OFFSET+PAR_SIZE) | |
61 ARGS_SIZE = (SIZEOF_INT*INT_REGS)+(SIZEOF_DOUBLE*FLOAT_REGS) /* = 136 */ | |
62 /* local struct DCValue */ | |
63 RESULT_OFFSET = (ARGS_OFFSET+ARGS_SIZE) | |
64 RESULT_SIZE = 16 | |
65 /* additional locals (reg 30/31) */ | |
66 LOCALS_OFFSET = (RESULT_OFFSET+RESULT_SIZE) | |
67 LOCALS_SIZE = 2*SIZEOF_INT | |
68 /* total */ | |
69 FRAME_SIZE = ( (LOCALS_OFFSET+LOCALS_SIZE)+15 & (-16) ) | |
70 | |
71 /* struct DCCallback */ | |
72 DCB_THUNK = 0 | |
73 DCB_HANDLER = 24 | |
74 DCB_STACKCLEAN = 28 | |
75 DCB_USERDATA = 32 | |
76 | |
77 /* struct DCArgs */ | |
78 DCA_IARRAY = 0 | |
79 DCA_FARRAY = SIZEOF_INT*INT_REGS | |
80 DCA_SP = DCA_FARRAY + SIZEOF_DOUBLE*FLOAT_REGS | |
81 DCA_ICOUNT = DCA_SP + 4 | |
82 DCA_FCOUNT = DCA_ICOUNT + 4 | |
83 | |
84 /* struct DCValue */ | |
85 DCV_INT = 0 | |
86 DCV_FLOAT = 0 | |
87 DCV_DOUBLE = 0 | |
88 DCV_LONG_HI32 = 0 | |
89 DCV_LONG_LO32 = 4 | |
90 DCV_SIZE = 8 | |
91 | |
92 iregfile = ARGS_OFFSET+DCA_IARRAY | |
93 fregfile = ARGS_OFFSET+DCA_FARRAY | |
94 save_sp = ARGS_OFFSET+DCA_SP | |
95 icount = ARGS_OFFSET+DCA_ICOUNT | |
96 fcount = ARGS_OFFSET+DCA_FCOUNT | |
97 .globl _dcCallbackThunkEntry | |
98 | |
99 /* | |
100 Thunk entry: | |
101 R2 = DCCallback* | |
102 */ | |
103 _dcCallbackThunkEntry: | |
104 | |
105 mflr r0 | |
106 stw r0, 8(r1) /* store return address */ | |
107 /* stmw r30, -8(r1) */ /* store preserved registers (r30/r31) */ | |
108 addi r12, r1, PAR_OFFSET /* temporary r12 = parameter area on callers stack frame */ | |
109 stwu r1, -FRAME_SIZE(r1) /* save callers stack pointer and make new stack frame. */ | |
110 stw r3, iregfile+0*4(r1) /* spill 8 integer parameter registers */ | |
111 stw r4, iregfile+1*4(r1) | |
112 stw r5, iregfile+2*4(r1) | |
113 stw r6, iregfile+3*4(r1) | |
114 stw r7, iregfile+4*4(r1) | |
115 stw r8, iregfile+5*4(r1) | |
116 stw r9, iregfile+6*4(r1) | |
117 stw r10,iregfile+7*4(r1) | |
118 stfd f1, fregfile+ 0*8(r1) /* spill 13 float parameter registers */ | |
119 stfd f2, fregfile+ 1*8(r1) | |
120 stfd f3, fregfile+ 2*8(r1) | |
121 stfd f4, fregfile+ 3*8(r1) | |
122 stfd f5, fregfile+ 4*8(r1) | |
123 stfd f6, fregfile+ 5*8(r1) | |
124 stfd f7, fregfile+ 6*8(r1) | |
125 stfd f8, fregfile+ 7*8(r1) | |
126 stfd f9, fregfile+ 8*8(r1) | |
127 stfd f10,fregfile+ 9*8(r1) | |
128 stfd f11,fregfile+10*8(r1) | |
129 stfd f12,fregfile+11*8(r1) | |
130 stfd f13,fregfile+12*8(r1) | |
131 /* initialize struct DCCallback */ | |
132 stw r12,save_sp(r1) /* init stack pointer */ | |
133 xor r0, r0, r0 /* init register counters */ | |
134 stw r0, icount(r1) | |
135 stw r0, fcount(r1) | |
136 /* invoke callback handler */ | |
137 mr r3, r2 /* arg 1: DCCallback* pcb */ | |
138 addi r4, r1, ARGS_OFFSET /* arg 2: DCArgs* args */ | |
139 addi r5, r1, RESULT_OFFSET /* arg 3: DCValue* result */ | |
140 lwz r6, DCB_USERDATA(r2) /* arg 4: void* userdata */ | |
141 | |
142 /* branch-and-link to DCCallback.handler */ | |
143 lwz r12, DCB_HANDLER(r2) | |
144 mtctr r12 | |
145 bctrl | |
146 addi r0, r1, RESULT_OFFSET /* r0 = DCValue* */ | |
147 /* switch on base result type */ | |
148 cmpi cr0, r3, 'B | |
149 beq .i32 | |
150 cmpi cr0, r3, 'i | |
151 beq .i32 | |
152 cmpi cr0, r3, 'l | |
153 beq .i64 | |
154 cmpi cr0, r3, 'f | |
155 beq .f32 | |
156 cmpi cr0, r3, 'd | |
157 beq .f64 | |
158 cmpi cr0, r3, 'p | |
159 beq .i32 | |
160 .void: /* ignore result (void call) */ | |
161 b .end | |
162 .i32: /* result is integer <= 32-bit result */ | |
163 lwz r3, RESULT_OFFSET + DCV_INT(r1) | |
164 b .end | |
165 .f32: /* result is C float result */ | |
166 lfs f1, RESULT_OFFSET + DCV_FLOAT(r1) | |
167 b .end | |
168 .f64: | |
169 lfd f1, RESULT_OFFSET + DCV_FLOAT(r1) | |
170 b .end | |
171 .i64: /* result is C double result */ | |
172 lwz r3, RESULT_OFFSET + DCV_LONG_HI32(r1) | |
173 lwz r4, RESULT_OFFSET + DCV_LONG_LO32(r1) | |
174 b .end | |
175 .end: | |
176 lwz r1, 0(r1) /* restore stack pointer */ | |
177 /* lmw r30, -8(r1) */ /* restore preserved registers */ | |
178 lwz r0, 8(r1) /* load link register with return address */ | |
179 mtlr r0 | |
180 blr /* branch back to link register */ | |
181 |