comparison dyncall/dyncall_callvm_sparc64.c @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children 67961454902b
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
1 /*
2
3 Package: dyncall
4 Library: dyncall
5 File: dyncall/dyncall_callvm_sparc64.c
6 Description: Call VM for sparc64 64-bit processor architecture.
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
27 #include "dyncall_callvm_sparc64.h"
28 #include "dyncall_call_sparc64.h"
29 #include "dyncall_alloc.h"
30
31 #define IREGS 6
32 #define FREGS 16
33 #define SREGS 16
34 #define DHEAD (IREGS+FREGS)*8+SREGS*4
35
36 /* Reset argument buffer. */
37 static void dc_callvm_reset_sparc64(DCCallVM* in_self)
38 {
39 DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
40 dcVecResize(&self->mVecHead,DHEAD);
41 self->mIntRegs = 0;
42 self->mFloatRegs = 0;
43 self->mUseSingleFlags = 0;
44 }
45
46 /* Construtor. */
47 /* the six output registers %o0-%o5 are always loaded, thus we need to ensure the argument buffer has space for at least 24 bytes. */
48 static DCCallVM* dc_callvm_new_sparc64(DCCallVM_vt* vt, DCsize size)
49 {
50 DCCallVM_sparc64* self = (DCCallVM_sparc64*) dcAllocMem(sizeof(DCCallVM_sparc64)+DHEAD+size);
51 dc_callvm_base_init(&self->mInterface, vt);
52 dcVecInit(&self->mVecHead,DHEAD+size);
53 dc_callvm_reset_sparc64(&self->mInterface);
54 return (DCCallVM*)self;
55 }
56
57 /* Destructor. */
58 static void dc_callvm_free_sparc64(DCCallVM* in_self)
59 {
60 dcFreeMem(in_self);
61 }
62
63 /* all integers are promoted to 64-bit. */
64
65 static void dc_callvm_argLongLong_sparc64(DCCallVM* in_self, DClonglong x)
66 {
67 DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
68 if (self->mIntRegs < IREGS) {
69 * ( (DClonglong*) ( dcVecAt(&self->mVecHead, (self->mIntRegs++)*8) ) ) = x;
70 } else {
71 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
72 }
73 if (self->mFloatRegs < FREGS) self->mFloatRegs++;
74 }
75
76 static void dc_callvm_argLong_sparc64 (DCCallVM* in_self, DClong x) { dc_callvm_argLongLong_sparc64(in_self, (DClonglong) x ); }
77 static void dc_callvm_argInt_sparc64 (DCCallVM* in_self, DCint x) { dc_callvm_argLongLong_sparc64(in_self, (DClonglong) x ); }
78 static void dc_callvm_argBool_sparc64 (DCCallVM* in_self, DCbool x) { dc_callvm_argLongLong_sparc64(in_self, (DClonglong) x ); }
79 static void dc_callvm_argChar_sparc64 (DCCallVM* in_self, DCchar x) { dc_callvm_argLongLong_sparc64(in_self, (DClonglong) x ); }
80 static void dc_callvm_argShort_sparc64 (DCCallVM* in_self, DCshort x) { dc_callvm_argLongLong_sparc64(in_self, (DClonglong) x ); }
81 static void dc_callvm_argPointer_sparc64(DCCallVM* in_self, DCpointer x) { dc_callvm_argLongLong_sparc64(in_self, (DClonglong) x ); }
82
83 static void dc_callvm_argDouble_sparc64(DCCallVM* in_self, DCdouble x)
84 {
85 DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
86 if (self->mFloatRegs < FREGS) {
87 * ((double*)dcVecAt(&self->mVecHead,(IREGS+(self->mFloatRegs++))*8)) = x;
88 }
89 if (self->mIntRegs < IREGS) {
90 self->mIntRegs++;
91 } else {
92 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
93 }
94 }
95
96 static void dc_callvm_argDouble_sparc64_ellipsis(DCCallVM* in_self, DCdouble x)
97 {
98 union {
99 long long l;
100 double d;
101 } u;
102 u.d = x;
103 dc_callvm_argLongLong_sparc64(in_self, u.l);
104 }
105
106 static void dc_callvm_argFloat_sparc64_ellipsis(DCCallVM* in_self, DCfloat x)
107 {
108 dc_callvm_argDouble_sparc64_ellipsis(in_self, (DCdouble) x);
109 }
110
111 static void dc_callvm_argFloat_sparc64(DCCallVM* in_self, DCfloat x)
112 {
113 DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
114 if (self->mFloatRegs < FREGS) {
115 self->mUseSingleFlags |= 1<<self->mFloatRegs;
116 * ((float*)dcVecAt(&self->mVecHead,(IREGS+FREGS)*8 + (self->mFloatRegs++)*4)) = x;
117 }
118
119 if (self->mIntRegs < IREGS) {
120 self->mIntRegs++;
121 } else {
122 union {
123 DCdouble d;
124 DClonglong l;
125 DCfloat f[2];
126 } u;
127 u.f[1] = x;
128 dcVecAppend(&self->mVecHead, &u.l, sizeof(DClonglong));
129 }
130 }
131
132 #if 0
133 /* call: delegate to default call kernel */
134 static void dc_callvm_call_sparc64(DCCallVM* in_self, DCpointer target)
135 {
136 DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
137 dcCall_sparc64(target, dcVecSize(&self->mVecHead), dcVecData(&self->mVecHead));
138 }
139 #endif
140
141 static void dc_callvm_mode_sparc64(DCCallVM* in_self, DCint mode);
142
143 DCCallVM_vt gVT_sparc64_ellipsis =
144 {
145 &dc_callvm_free_sparc64,
146 &dc_callvm_reset_sparc64,
147 &dc_callvm_mode_sparc64,
148 &dc_callvm_argBool_sparc64,
149 &dc_callvm_argChar_sparc64,
150 &dc_callvm_argShort_sparc64,
151 &dc_callvm_argInt_sparc64,
152 &dc_callvm_argLong_sparc64,
153 &dc_callvm_argLongLong_sparc64,
154 &dc_callvm_argFloat_sparc64_ellipsis,
155 &dc_callvm_argDouble_sparc64_ellipsis,
156 &dc_callvm_argPointer_sparc64,
157 NULL /* argStruct */,
158 (DCvoidvmfunc*) &dcCall_sparc64,
159 (DCboolvmfunc*) &dcCall_sparc64,
160 (DCcharvmfunc*) &dcCall_sparc64,
161 (DCshortvmfunc*) &dcCall_sparc64,
162 (DCintvmfunc*) &dcCall_sparc64,
163 (DClongvmfunc*) &dcCall_sparc64,
164 (DClonglongvmfunc*) &dcCall_sparc64,
165 (DCfloatvmfunc*) &dcCall_sparc64,
166 (DCdoublevmfunc*) &dcCall_sparc64,
167 (DCpointervmfunc*) &dcCall_sparc64,
168 NULL /* callStruct */
169 };
170
171 /* CallVM virtual table. */
172 DCCallVM_vt gVT_sparc64 =
173 {
174 &dc_callvm_free_sparc64,
175 &dc_callvm_reset_sparc64,
176 &dc_callvm_mode_sparc64,
177 &dc_callvm_argBool_sparc64,
178 &dc_callvm_argChar_sparc64,
179 &dc_callvm_argShort_sparc64,
180 &dc_callvm_argInt_sparc64,
181 &dc_callvm_argLong_sparc64,
182 &dc_callvm_argLongLong_sparc64,
183 &dc_callvm_argFloat_sparc64,
184 &dc_callvm_argDouble_sparc64,
185 &dc_callvm_argPointer_sparc64,
186 NULL /* argStruct */,
187 (DCvoidvmfunc*) &dcCall_sparc64,
188 (DCboolvmfunc*) &dcCall_sparc64,
189 (DCcharvmfunc*) &dcCall_sparc64,
190 (DCshortvmfunc*) &dcCall_sparc64,
191 (DCintvmfunc*) &dcCall_sparc64,
192 (DClongvmfunc*) &dcCall_sparc64,
193 (DClonglongvmfunc*) &dcCall_sparc64,
194 (DCfloatvmfunc*) &dcCall_sparc64,
195 (DCdoublevmfunc*) &dcCall_sparc64,
196 (DCpointervmfunc*) &dcCall_sparc64,
197 NULL /* callStruct */
198 };
199
200 /* mode: only a single mode available currently. */
201 static void dc_callvm_mode_sparc64(DCCallVM* in_self, DCint mode)
202 {
203 switch(mode) {
204 case DC_CALL_C_DEFAULT:
205 case DC_CALL_C_ELLIPSIS:
206 case DC_CALL_C_SPARC64:
207 in_self->mVTpointer = &gVT_sparc64;
208 break;
209 case DC_CALL_C_ELLIPSIS_VARARGS:
210 in_self->mVTpointer = &gVT_sparc64_ellipsis;
211 break;
212 default:
213 in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
214 break;
215 }
216 }
217
218
219 /* Public API. */
220 DCCallVM* dcNewCallVM(DCsize size)
221 {
222 return dc_callvm_new_sparc64(&gVT_sparc64,size);
223 }
224
225 #if 0
226 /* Load integer 32-bit. */
227 static void dc_callvm_argInt_sparc64(DCCallVM* in_self, DCint x)
228 {
229 DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
230 dcVecAppend(&self->mVecHead, &x, sizeof(DCint));
231 }
232
233 /* we propagate Bool,Char,Short,Int to LongLong. */
234
235 static void dc_callvm_argBool_sparc64(DCCallVM* in_self, DCbool x) { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
236 static void dc_callvm_argChar_sparc64(DCCallVM* in_self, DCchar x) { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
237 static void dc_callvm_argShort_sparc64(DCCallVM* in_self, DCshort x) { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
238 #endif
239