annotate dyncall/dyncall_callvm_arm64.c @ 357:d982a00c2177

- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
author Tassilo Philipp
date Tue, 25 Feb 2020 18:16:13 +0100
parents f5577f6bf97a
children ad5f9803f52f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 Package: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 Library: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 File: dyncall/dyncall_callvm_arm64.c
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Description: ARM 64-bit ABI implementation
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 License:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
281
f5577f6bf97a - file header cleanups for release
Tassilo Philipp
parents: 84
diff changeset
9 Copyright (c) 2015-2018 Daniel Adler <dadler@uni-goettingen.de>,
f5577f6bf97a - file header cleanups for release
Tassilo Philipp
parents: 84
diff changeset
10 Tassilo Philipp <tphilipp@potion-studios.com>
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 Permission to use, copy, modify, and distribute this software for any
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 purpose with or without fee is hereby granted, provided that the above
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 copyright notice and this permission notice appear in all copies.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 #include "dyncall_callvm_arm64.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 #include "dyncall_alloc.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 static void reset(DCCallVM* in_p)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 p->i = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 p->f = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 dcVecReset(&p->mVecHead);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 static void deinit(DCCallVM* in_self)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42 dcFreeMem(in_self);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 static void a_i64(DCCallVM* in_self, DClonglong x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 DCCallVM_arm64* p = (DCCallVM_arm64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 if (p->i < 8) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 p->I[p->i] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 p->i++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 } else {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 dcVecAppend(&p->mVecHead, &x, sizeof(DClonglong));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 static void a_bool (DCCallVM* self, DCbool x) { a_i64(self, (DClonglong)x); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 static void a_char (DCCallVM* self, DCchar x) { a_i64(self, x); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 static void a_short (DCCallVM* self, DCshort x) { a_i64(self, x); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 static void a_int (DCCallVM* self, DCint x) { a_i64(self, x); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 static void a_long (DCCallVM* self, DClong x) { a_i64(self, x); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 static void a_pointer (DCCallVM* self, DCpointer x) { a_i64(self, (DClonglong) x ); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 static void a_float(DCCallVM* in_p, DCfloat x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 if (p->f < 8) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 p->u.S[ p->f << 1 ] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 p->f++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 } else {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 dcVecAppend(&p->mVecHead, &x, sizeof(DCfloat));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 dcVecSkip(&p->mVecHead, 4); /* align to 8-bytes */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 static void a_double(DCCallVM* in_p, DCdouble x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 if (p->f < 8) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 p->u.D[ p->f ] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 p->f++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 } else {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 dcVecAppend(&p->mVecHead, &x, sizeof(DCdouble));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 void call(DCCallVM* in_p, DCpointer target)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 DCCallVM_arm64* p = (DCCallVM_arm64*)in_p;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 ** copy 'size' argument is given in number of 16-byte 'pair' blocks.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97 dcCall_arm64(target, dcVecData(&p->mVecHead), ( dcVecSize(&p->mVecHead) + 15 ) & -16, &p->u.S[0]);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
100 static void mode(DCCallVM* in_self, DCint mode);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
101
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 DCCallVM_vt vt_arm64 =
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104 &deinit
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105 , &reset
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 , &mode
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 , &a_bool
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108 , &a_char
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 , &a_short
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 , &a_int
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111 , &a_long
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 , &a_i64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113 , &a_float
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 , &a_double
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 , &a_pointer
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 , NULL /* argStruct */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 , (DCvoidvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118 , (DCboolvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119 , (DCcharvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 , (DCshortvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121 , (DCintvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 , (DClongvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 , (DClonglongvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124 , (DCfloatvmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 , (DCdoublevmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 , (DCpointervmfunc*) &call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 , NULL /* callStruct */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128 };
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
130 static void mode(DCCallVM* in_self, DCint mode)
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 {
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
132 DCCallVM_arm64* self = (DCCallVM_arm64*)in_self;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
133 DCCallVM_vt* vt;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135 switch(mode) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 case DC_CALL_C_DEFAULT:
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
137 case DC_CALL_C_ARM64:
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 case DC_CALL_C_ELLIPSIS:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 case DC_CALL_C_ELLIPSIS_VARARGS:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 vt = &vt_arm64;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142 default:
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
143 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 return;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145 }
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
146 dc_callvm_base_init(&self->mInterface, vt);
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
149 /* Public API. */
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
150 DCCallVM* dcNewCallVM(DCsize size)
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
151 {
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
152 DCCallVM_arm64* p = (DCCallVM_arm64*)dcAllocMem(sizeof(DCCallVM_arm64)+size);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
153
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
154 mode((DCCallVM*)p, DC_CALL_C_DEFAULT);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
155
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
156 dcVecInit(&p->mVecHead, size);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
157 reset((DCCallVM*)p);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
158
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
159 return (DCCallVM*)p;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
160 }
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
161