Mercurial > pub > dyncall > dyncall
annotate dyncallback/dyncall_args_x64.c @ 661:93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
author | Tassilo Philipp |
---|---|
date | Thu, 14 Mar 2024 10:11:28 +0100 |
parents | b36a738c8975 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncallback | |
5 File: dyncallback/dyncall_args_x64.c | |
6 Description: Callback's Arguments VM - Implementation for x64 | |
7 License: | |
8 | |
661
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
9 Copyright (c) 2007-2024 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 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 | |
661
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
28 #include "dyncall_args.h" |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
29 #include "dyncall_callvm_x64.h" /* reuse DCRegCount_x64 and DCRegData_x64_s */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
30 #include "dyncall_aggregate.h" |
0 | 31 |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
32 #include <assert.h> |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
33 #include <string.h> |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
34 |
0 | 35 |
661
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
36 struct DCArgs |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
37 { |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
38 /* state */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
39 int64* stack_ptr; /* offset 0 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
40 DCRegCount_x64 reg_count; /* offset 8, size:win 4, size:*nix 8 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
41 #if defined(DC_WINDOWS) |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
42 int pad_w; /* alignment helper for win/x64 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
43 #endif |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
44 int aggr_return_register; /* offset 16 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
45 int pad; /* offset 20 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
46 DCaggr** aggrs; /* offset 24 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
47 |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
48 /* reg data */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
49 DCRegData_x64_s reg_data; /* offset 32 */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
50 }; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
51 |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
557
diff
changeset
|
52 |
0 | 53 static int64* arg_i64(DCArgs* args) |
54 { | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
55 args->reg_count.i += (args->reg_count.i == args->aggr_return_register); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
56 |
0 | 57 if (args->reg_count.i < numIntRegs) |
58 return &args->reg_data.i[args->reg_count.i++]; | |
59 else | |
60 return args->stack_ptr++; | |
61 } | |
62 | |
63 | |
64 static double* arg_f64(DCArgs* args) | |
65 { | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
66 #if defined(DC_WINDOWS) |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
67 args->reg_count.f += (args->reg_count.f == args->aggr_return_register); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
68 #endif |
0 | 69 if (args->reg_count.f < numFloatRegs) |
70 return &args->reg_data.f[args->reg_count.f++]; | |
71 else | |
72 return (double*)args->stack_ptr++; | |
73 } | |
74 | |
75 | |
76 | |
77 DClonglong dcbArgLongLong (DCArgs* p) { return *arg_i64(p); } | |
78 DCint dcbArgInt (DCArgs* p) { return (int) dcbArgLongLong(p); } | |
79 DClong dcbArgLong (DCArgs* p) { return (long) dcbArgLongLong(p); } | |
80 DCchar dcbArgChar (DCArgs* p) { return (char) dcbArgLongLong(p); } | |
81 DCshort dcbArgShort (DCArgs* p) { return (short) dcbArgLongLong(p); } | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
82 DCbool dcbArgBool (DCArgs* p) { return dcbArgInt(p) != 0; } |
0 | 83 |
84 DCuint dcbArgUInt (DCArgs* p) { return (DCuint) dcbArgInt(p); } | |
85 DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgChar(p); } | |
86 DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgShort(p); } | |
87 DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgLong(p); } | |
88 DCulonglong dcbArgULongLong(DCArgs* p) { return (DCulonglong) dcbArgLongLong(p); } | |
89 | |
90 | |
91 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLongLong(p); } | |
92 | |
93 DCdouble dcbArgDouble (DCArgs* p) { return *arg_f64(p); } | |
94 DCfloat dcbArgFloat (DCArgs* p) { return *(float*)arg_f64(p); } | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
95 |
544
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
96 DCpointer dcbArgAggr (DCArgs* p, DCpointer target) |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
97 { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
98 int i; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
99 DCaggr *ag = *(p->aggrs++); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
100 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
101 if(!ag) { |
536
c0df40c888ac
- dyncallback fixes related to C++ non-trivial aggregates (not final, but fixing most obvious things I missed)
Tassilo Philipp
parents:
533
diff
changeset
|
102 /* non-trivial aggr: retrieve as ptr, user is supposed to make copy */ |
544
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
103 return dcbArgPointer(p); |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
104 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
105 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
106 #if defined(DC_UNIX) |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
107 DCRegCount_x64 n_regs = { p->reg_count.i, p->reg_count.f }; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
108 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
109 if(ag->sysv_classes[0] != SYSVC_MEMORY) { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
110 /* reclassify aggr w/ respect to remaining regs, might have been passed entirely via the stack */ |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
111 for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i) { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
112 DCuchar clz = ag->sysv_classes[i]; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
113 n_regs.i += (clz == SYSVC_INTEGER); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
114 n_regs.f += (clz == SYSVC_SSE); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
115 /* @@@AGGR implement when implementing x87 types */ |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
116 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
117 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
118 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
119 if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs)) |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
120 { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
121 memcpy(target, p->stack_ptr, ag->size); |
549
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
122 p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); /* advance to next full stack slot */ |
544
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
123 } |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
124 else |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
125 { |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
126 for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i) |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
127 { |
551
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
128 size_t s = ag->size - i*8; |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
129 s = s<8?s:8; |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
130 |
544
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
131 switch (ag->sysv_classes[i]) |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
132 { |
549
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
133 case SYSVC_INTEGER: |
551
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
134 { |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
135 DClonglong l = dcbArgLongLong(p); |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
136 memcpy((DClonglong*)target + i, &l, s); |
549
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
137 } |
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
138 break; |
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
139 |
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
140 case SYSVC_SSE: |
551
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
141 if(s == 8) |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
142 *(((DCdouble*)target) + i) = dcbArgDouble(p); |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
143 else if(s == 4) |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
144 *(DCfloat*)(((DCdouble*)target) + i) = dcbArgFloat (p); |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
145 else |
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
146 assert(DC_FALSE && "SYSV aggregate floating point slot mismatch (unexpected size of fp field)"); |
549
0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
Tassilo Philipp
parents:
544
diff
changeset
|
147 break; |
551
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
148 |
544
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
149 /* @@@AGGR implement when implementing x87 types */ |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
150 default: |
551
eef302b7a58d
- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents:
549
diff
changeset
|
151 assert(DC_FALSE && "unsupported SYSV aggregate slot classification"); /* shouldn't be reached, as we check for unupported classes earlier */ |
544
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
152 } |
111236b31c75
- C++ non-trivial aggregate-by-value handling:
Tassilo Philipp
parents:
537
diff
changeset
|
153 } |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
154 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
155 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
156 #else |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
157 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
158 switch (ag->size) { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
159 case 1: *(DCchar *)target = dcbArgChar (p); break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
160 case 2: *(DCshort *)target = dcbArgShort (p); break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
161 case 4: *(DClong *)target = dcbArgLong (p); break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
162 case 8: *(DClonglong*)target = dcbArgLongLong(p); break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
163 default: memcpy(target, dcbArgPointer(p), ag->size); break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
164 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
165 #endif |
554 | 166 |
167 return target; | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
168 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
169 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
170 |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
171 void dcbReturnAggr(DCArgs *args, DCValue *result, DCpointer ret) |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
172 { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
173 int i; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
174 DCaggr *ag = *(args->aggrs++); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
175 |
557
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
176 if(args->aggr_return_register >= 0) { |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
177 DCpointer dest = (DCpointer) args->reg_data.i[args->aggr_return_register]; |
557
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
178 if(ag) |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
179 memcpy(dest, ret, ag->size); |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
180 else { |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
181 /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */ |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
182 } |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
183 result->p = dest; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
184 } else { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
185 #if defined(DC_UNIX) |
557
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
186 /* A 16 byte struct would be sufficient for System V (because at most two of the four registers can be full). */ |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
187 /* But then it's much more complicated to copy the result to the correct registers in assembly. */ |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
188 typedef struct { |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
189 DClonglong r[2]; /* rax, rdx */ |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
190 DCdouble x[2]; /* xmm0, xmm1 */ |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
191 } DCRetRegs_SysV; |
b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
Tassilo Philipp
parents:
554
diff
changeset
|
192 |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
193 /* a max of 2 regs are used in this case, out of rax, rdx, xmm0 and xmm1 */ |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
194 /* space for 4 qwords is pointed to by (DCRetRegs_SysV*)result */ |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
195 DClonglong *intRegs = ((DCRetRegs_SysV*)result)->r; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
196 DCdouble *sseRegs = ((DCRetRegs_SysV*)result)->x; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
197 for(i=0; ag->sysv_classes[i] && i<2/*guaranteed*/; ++i) { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
198 switch (ag->sysv_classes[i]) { |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
199 case SYSVC_INTEGER: *(intRegs++) = ((DClonglong*)ret)[i]; break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
200 case SYSVC_SSE: *(sseRegs++) = ((DCdouble *)ret)[i]; break; |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
201 /* @@@AGGR implement when implementing x87 types, might lead to more than 2 regs (e.g. _m512) */ |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
202 default: assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier"); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
203 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
204 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
205 #else |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
206 /* copy aggregate (guaranteed to be <= 8b by call conv, as no hidden ptr) into result */ |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
207 assert(ag->size <= 8 && "aggregate info mismatch for return type"); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
208 memcpy(result, ret, ag->size); |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
209 #endif |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
210 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
211 } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
212 |