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
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: dyncallback
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 File: dyncallback/dyncall_args_x64.c
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Description: Callback's Arguments VM - Implementation for x64
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
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 Tassilo Philipp <tphilipp@potion-studios.com>
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
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 static int64* arg_i64(DCArgs* args)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 if (args->reg_count.i < numIntRegs)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 return &args->reg_data.i[args->reg_count.i++];
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 return args->stack_ptr++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 static double* arg_f64(DCArgs* args)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 if (args->reg_count.f < numFloatRegs)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 return &args->reg_data.f[args->reg_count.f++];
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 return (double*)args->stack_ptr++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74
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 DClonglong dcbArgLongLong (DCArgs* p) { return *arg_i64(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 DCint dcbArgInt (DCArgs* p) { return (int) dcbArgLongLong(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 DClong dcbArgLong (DCArgs* p) { return (long) dcbArgLongLong(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 DCchar dcbArgChar (DCArgs* p) { return (char) dcbArgLongLong(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
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
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 DCuint dcbArgUInt (DCArgs* p) { return (DCuint) dcbArgInt(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgChar(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgShort(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgLong(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 DCulonglong dcbArgULongLong(DCArgs* p) { return (DCulonglong) dcbArgLongLong(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLongLong(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 DCdouble dcbArgDouble (DCArgs* p) { return *arg_f64(p); }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
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
4d87bd4890b0 win64 callback dcbArgAggr() retval fix
Tassilo Philipp
parents: 551
diff changeset
166
4d87bd4890b0 win64 callback dcbArgAggr() retval fix
Tassilo Philipp
parents: 551
diff changeset
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