comparison dyncall/dyncall_callvm_arm32_thumb.c @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children beafc56094bc
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
1 /*
2
3 Package: dyncall
4 Library: dyncall
5 File: dyncall/dyncall_callvm_arm32_thumb.c
6 Description: ARM 32-bit "thumb" ABI callvm implementation
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
27
28 /*
29
30 dyncall callvm for 32bit ARM32 family of processors
31
32 SUPPORTED CALLING CONVENTIONS
33 armthumbcall
34
35 REVISION
36 2007/12/11 initial
37
38 */
39
40
41 #include "dyncall_callvm_arm32_thumb.h"
42 #include "dyncall_alloc.h"
43
44 static void dc_callvm_mode_arm32_thumb(DCCallVM* in_self,DCint mode);
45
46 static DCCallVM* dc_callvm_new_arm32_thumb(DCCallVM_vt* vt, DCsize size)
47 {
48 /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
49 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)dcAllocMem(sizeof(DCCallVM_arm32_thumb)+size+16);
50 dc_callvm_base_init(&self->mInterface, vt);
51 dcVecInit(&self->mVecHead, size);
52 return (DCCallVM*)self;
53 }
54
55
56 static void dc_callvm_free_arm32_thumb(DCCallVM* in_self)
57 {
58 dcFreeMem(in_self);
59 }
60
61
62 static void dc_callvm_reset_arm32_thumb(DCCallVM* in_self)
63 {
64 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
65 dcVecReset(&self->mVecHead);
66 }
67
68
69 static void dc_callvm_argInt_arm32_thumb(DCCallVM* in_self, DCint x)
70 {
71 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
72 dcVecAppend(&self->mVecHead, &x, sizeof(DCint));
73 }
74
75
76 static void dc_callvm_argBool_arm32_thumb(DCCallVM* in_self, DCbool x)
77 {
78 dc_callvm_argInt_arm32_thumb(in_self, (DCint)x);
79 }
80
81
82 static void dc_callvm_argChar_arm32_thumb(DCCallVM* in_self, DCchar x)
83 {
84 dc_callvm_argInt_arm32_thumb(in_self, x);
85 }
86
87
88 static void dc_callvm_argShort_arm32_thumb(DCCallVM* in_self, DCshort x)
89 {
90 dc_callvm_argInt_arm32_thumb(in_self, x);
91 }
92
93
94 static void dc_callvm_argLong_arm32_thumb(DCCallVM* in_self, DClong x)
95 {
96 dc_callvm_argInt_arm32_thumb(in_self, x);
97 }
98
99
100 static void dc_callvm_argLongLong_arm32_thumb(DCCallVM* in_self, DClonglong x)
101 {
102 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
103 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
104 }
105
106
107 static void dc_callvm_argLongLong_arm32_thumb_eabi(DCCallVM* in_self, DClonglong x)
108 {
109 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
110
111 /* 64 bit values need to be aligned on 8 byte boundaries */
112 dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4);
113 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
114 }
115
116
117 static void dc_callvm_argFloat_arm32_thumb(DCCallVM* in_self, DCfloat x)
118 {
119 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
120 dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat));
121 }
122
123
124 static void dc_callvm_argDouble_arm32_thumb(DCCallVM* in_self, DCdouble x)
125 {
126 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
127 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
128 }
129
130
131 static void dc_callvm_argDouble_arm32_thumb_eabi(DCCallVM* in_self, DCdouble x)
132 {
133 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
134
135 /* 64 bit values need to be aligned on 8 byte boundaries */
136 dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4);
137 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
138 }
139
140
141 static void dc_callvm_argPointer_arm32_thumb(DCCallVM* in_self, DCpointer x)
142 {
143 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
144 dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer));
145 }
146
147 typedef void (*call_void) (DCpointer target, DCpointer data, DCsize size);
148 typedef DClong (*call_word) (DCpointer target, DCpointer data, DCsize size);
149 typedef DClonglong (*call_dword) (DCpointer target, DCpointer data, DCsize size);
150
151
152
153 /* Call. */
154 void dc_callvm_call_arm32_thumb(DCCallVM* in_self, DCpointer target)
155 {
156 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
157 dcCall_arm32_thumb(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
158 }
159
160
161 #if 0
162 DClong dc_callvm_call_arm32_thumb_word(DCCallVM* in_self, DCpointer target)
163 {
164 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
165 // return dcCall_arm32_thumb_word(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
166 return ( (call_word) dcCall_arm32_thumb) (target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
167 }
168
169
170 DClonglong dc_callvm_call_arm32_thumb_dword(DCCallVM* in_self, DCpointer target)
171 {
172 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
173 // return dcCall_arm32_thumb_dword(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
174 return ( (call_dword) dcCall_arm32_thumb ) (target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
175 }
176 #endif
177
178
179 DCCallVM_vt gVT_arm32_thumb =
180 {
181 &dc_callvm_free_arm32_thumb
182 , &dc_callvm_reset_arm32_thumb
183 , &dc_callvm_mode_arm32_thumb
184 , &dc_callvm_argBool_arm32_thumb
185 , &dc_callvm_argChar_arm32_thumb
186 , &dc_callvm_argShort_arm32_thumb
187 , &dc_callvm_argInt_arm32_thumb
188 , &dc_callvm_argLong_arm32_thumb
189 , &dc_callvm_argLongLong_arm32_thumb
190 , &dc_callvm_argFloat_arm32_thumb
191 , &dc_callvm_argDouble_arm32_thumb
192 , &dc_callvm_argPointer_arm32_thumb
193 , NULL /* argStruct */
194 , (DCvoidvmfunc*) &dc_callvm_call_arm32_thumb
195 , (DCboolvmfunc*) &dc_callvm_call_arm32_thumb
196 , (DCcharvmfunc*) &dc_callvm_call_arm32_thumb
197 , (DCshortvmfunc*) &dc_callvm_call_arm32_thumb
198 , (DCintvmfunc*) &dc_callvm_call_arm32_thumb
199 , (DClongvmfunc*) &dc_callvm_call_arm32_thumb
200 , (DClonglongvmfunc*) &dc_callvm_call_arm32_thumb
201 , (DCfloatvmfunc*) &dc_callvm_call_arm32_thumb
202 , (DCdoublevmfunc*) &dc_callvm_call_arm32_thumb
203 , (DCpointervmfunc*) &dc_callvm_call_arm32_thumb
204 , NULL /* callStruct */
205 };
206
207
208 DCCallVM_vt gVT_arm32_thumb_eabi =
209 {
210 &dc_callvm_free_arm32_thumb
211 , &dc_callvm_reset_arm32_thumb
212 , &dc_callvm_mode_arm32_thumb
213 , &dc_callvm_argBool_arm32_thumb
214 , &dc_callvm_argChar_arm32_thumb
215 , &dc_callvm_argShort_arm32_thumb
216 , &dc_callvm_argInt_arm32_thumb
217 , &dc_callvm_argLong_arm32_thumb
218 , &dc_callvm_argLongLong_arm32_thumb_eabi
219 , &dc_callvm_argFloat_arm32_thumb
220 , &dc_callvm_argDouble_arm32_thumb_eabi
221 , &dc_callvm_argPointer_arm32_thumb
222 , NULL /* argStruct */
223 , (DCvoidvmfunc*) &dc_callvm_call_arm32_thumb
224 , (DCboolvmfunc*) &dc_callvm_call_arm32_thumb
225 , (DCcharvmfunc*) &dc_callvm_call_arm32_thumb
226 , (DCshortvmfunc*) &dc_callvm_call_arm32_thumb
227 , (DCintvmfunc*) &dc_callvm_call_arm32_thumb
228 , (DClongvmfunc*) &dc_callvm_call_arm32_thumb
229 , (DClonglongvmfunc*) &dc_callvm_call_arm32_thumb
230 , (DCfloatvmfunc*) &dc_callvm_call_arm32_thumb
231 , (DCdoublevmfunc*) &dc_callvm_call_arm32_thumb
232 , (DCpointervmfunc*) &dc_callvm_call_arm32_thumb
233 , NULL /* callStruct */
234 };
235
236
237 DCCallVM* dcNewCallVM_arm32_thumb(DCsize size)
238 {
239 /* Check OS if we need EABI as default. */
240 #if defined(DC__ABI_ARM_EABI)
241 return dc_callvm_new_arm32_thumb(&gVT_arm32_thumb_eabi, size);
242 #else
243 return dc_callvm_new_arm32_thumb(&gVT_arm32_thumb, size);
244 #endif
245 }
246
247
248 DCCallVM* dcNewCallVM(DCsize size)
249 {
250 return dcNewCallVM_arm32_thumb(size);
251 }
252
253
254 static void dc_callvm_mode_arm32_thumb(DCCallVM* in_self,DCint mode)
255 {
256 DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*) in_self;
257 DCCallVM_vt* vt;
258 switch(mode) {
259 /* Check OS if we need EABI as default. */
260 case DC_CALL_C_ELLIPSIS:
261 #if defined(DC__ABI_ARM_EABI)
262 case DC_CALL_C_DEFAULT: vt = &gVT_arm32_thumb_eabi; break;
263 #else
264 case DC_CALL_C_DEFAULT: vt = &gVT_arm32_thumb; break;
265 #endif
266 case DC_CALL_C_ARM_THUMB: vt = &gVT_arm32_thumb; break;
267 case DC_CALL_C_ARM_THUMB_EABI: vt = &gVT_arm32_thumb_eabi; break;
268 default: self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
269 }
270 self->mInterface.mVTpointer = vt;
271 }
272