comparison dyncall/dyncall_callvm_arm32_arm.c @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children 17b10cc8ce8b
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
1 /*
2
3 Package: dyncall
4 Library: dyncall
5 File: dyncall/dyncall_callvm_arm32_arm.c
6 Description: ARM 32-bit "arm" 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 armcall
34
35 REVISION
36 2007/12/11 initial
37
38 */
39
40
41 #include "dyncall_callvm_arm32_arm.h"
42 #include "dyncall_alloc.h"
43
44 static void dc_callvm_mode_arm32_arm(DCCallVM* in_self,DCint mode);
45
46 static DCCallVM* dc_callvm_new_arm32_arm(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_arm* self = (DCCallVM_arm32_arm*)dcAllocMem(sizeof(DCCallVM_arm32_arm)+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_arm(DCCallVM* in_self)
57 {
58 dcFreeMem(in_self);
59 }
60
61
62 static void dc_callvm_reset_arm32_arm(DCCallVM* in_self)
63 {
64 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
65 dcVecReset(&self->mVecHead);
66 }
67
68
69 static void dc_callvm_argInt_arm32_arm(DCCallVM* in_self, DCint x)
70 {
71 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
72 dcVecAppend(&self->mVecHead, &x, sizeof(DCint));
73 }
74
75
76 static void dc_callvm_argBool_arm32_arm(DCCallVM* in_self, DCbool x)
77 {
78 dc_callvm_argInt_arm32_arm(in_self, (DCint)x);
79 }
80
81
82 static void dc_callvm_argChar_arm32_arm(DCCallVM* in_self, DCchar x)
83 {
84 dc_callvm_argInt_arm32_arm(in_self, x);
85 }
86
87
88 static void dc_callvm_argShort_arm32_arm(DCCallVM* in_self, DCshort x)
89 {
90 dc_callvm_argInt_arm32_arm(in_self, x);
91 }
92
93
94 static void dc_callvm_argLong_arm32_arm(DCCallVM* in_self, DClong x)
95 {
96 dc_callvm_argInt_arm32_arm(in_self, x);
97 }
98
99
100 static void dc_callvm_argLongLong_arm32_arm(DCCallVM* in_self, DClonglong x)
101 {
102 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
103 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
104 }
105
106
107 static void dc_callvm_argLongLong_arm32_arm_eabi(DCCallVM* in_self, DClonglong x)
108 {
109 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)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_arm(DCCallVM* in_self, DCfloat x)
118 {
119 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
120 dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat));
121 }
122
123
124 static void dc_callvm_argDouble_arm32_arm(DCCallVM* in_self, DCdouble x)
125 {
126 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
127 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
128 }
129
130
131 static void dc_callvm_argDouble_arm32_arm_eabi(DCCallVM* in_self, DCdouble x)
132 {
133 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)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_arm(DCCallVM* in_self, DCpointer x)
142 {
143 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
144 dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer));
145 }
146
147
148 /* Call. */
149 void dc_callvm_call_arm32_arm(DCCallVM* in_self, DCpointer target)
150 {
151 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
152 dcCall_arm32_arm(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
153 }
154
155
156 DCCallVM_vt gVT_arm32_arm =
157 {
158 &dc_callvm_free_arm32_arm
159 , &dc_callvm_reset_arm32_arm
160 , &dc_callvm_mode_arm32_arm
161 , &dc_callvm_argBool_arm32_arm
162 , &dc_callvm_argChar_arm32_arm
163 , &dc_callvm_argShort_arm32_arm
164 , &dc_callvm_argInt_arm32_arm
165 , &dc_callvm_argLong_arm32_arm
166 , &dc_callvm_argLongLong_arm32_arm
167 , &dc_callvm_argFloat_arm32_arm
168 , &dc_callvm_argDouble_arm32_arm
169 , &dc_callvm_argPointer_arm32_arm
170 , NULL /* argStruct */
171 , (DCvoidvmfunc*) &dc_callvm_call_arm32_arm
172 , (DCboolvmfunc*) &dc_callvm_call_arm32_arm
173 , (DCcharvmfunc*) &dc_callvm_call_arm32_arm
174 , (DCshortvmfunc*) &dc_callvm_call_arm32_arm
175 , (DCintvmfunc*) &dc_callvm_call_arm32_arm
176 , (DClongvmfunc*) &dc_callvm_call_arm32_arm
177 , (DClonglongvmfunc*) &dc_callvm_call_arm32_arm
178 , (DCfloatvmfunc*) &dc_callvm_call_arm32_arm
179 , (DCdoublevmfunc*) &dc_callvm_call_arm32_arm
180 , (DCpointervmfunc*) &dc_callvm_call_arm32_arm
181 , NULL /* callStruct */
182 };
183
184
185 DCCallVM_vt gVT_arm32_arm_eabi =
186 {
187 &dc_callvm_free_arm32_arm
188 , &dc_callvm_reset_arm32_arm
189 , &dc_callvm_mode_arm32_arm
190 , &dc_callvm_argBool_arm32_arm
191 , &dc_callvm_argChar_arm32_arm
192 , &dc_callvm_argShort_arm32_arm
193 , &dc_callvm_argInt_arm32_arm
194 , &dc_callvm_argLong_arm32_arm
195 , &dc_callvm_argLongLong_arm32_arm_eabi
196 , &dc_callvm_argFloat_arm32_arm
197 , &dc_callvm_argDouble_arm32_arm_eabi
198 , &dc_callvm_argPointer_arm32_arm
199 , NULL /* argStruct */
200 , (DCvoidvmfunc*) &dc_callvm_call_arm32_arm
201 , (DCboolvmfunc*) &dc_callvm_call_arm32_arm
202 , (DCcharvmfunc*) &dc_callvm_call_arm32_arm
203 , (DCshortvmfunc*) &dc_callvm_call_arm32_arm
204 , (DCintvmfunc*) &dc_callvm_call_arm32_arm
205 , (DClongvmfunc*) &dc_callvm_call_arm32_arm
206 , (DClonglongvmfunc*) &dc_callvm_call_arm32_arm
207 , (DCfloatvmfunc*) &dc_callvm_call_arm32_arm
208 , (DCdoublevmfunc*) &dc_callvm_call_arm32_arm
209 , (DCpointervmfunc*) &dc_callvm_call_arm32_arm
210 , NULL /* callStruct */
211 };
212
213
214 DCCallVM* dcNewCallVM_arm32_arm(DCsize size)
215 {
216 /* Check OS if we need EABI as default. */
217 #if defined(DC__ABI_ARM_EABI)
218 return dc_callvm_new_arm32_arm(&gVT_arm32_arm_eabi, size);
219 #else
220 return dc_callvm_new_arm32_arm(&gVT_arm32_arm, size);
221 #endif
222 }
223
224
225 DCCallVM* dcNewCallVM(DCsize size)
226 {
227 return dcNewCallVM_arm32_arm(size);
228 }
229
230 static void dc_callvm_mode_arm32_arm(DCCallVM* in_self,DCint mode)
231 {
232 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*) in_self;
233 DCCallVM_vt* vt;
234 switch(mode) {
235 /* Check OS if we need EABI as default. */
236 case DC_CALL_C_ELLIPSIS:
237 case DC_CALL_C_ELLIPSIS_VARARGS:
238 #if defined(DC__ABI_ARM_EABI)
239 case DC_CALL_C_DEFAULT: vt = &gVT_arm32_arm_eabi; break;
240 #else
241 case DC_CALL_C_DEFAULT: vt = &gVT_arm32_arm; break;
242 #endif
243 case DC_CALL_C_ARM_ARM: vt = &gVT_arm32_arm; break;
244 case DC_CALL_C_ARM_ARM_EABI: vt = &gVT_arm32_arm_eabi; break;
245 default:
246 in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
247 return;
248 }
249 self->mInterface.mVTpointer = vt;
250 }
251