annotate dyncall/dyncall_aggregate_x64.c @ 551:eef302b7a58d

- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts - changelog wording tweaks for clarity - comment tweaks for clarity - (mostly pointless) microoptimization in aggr alignment calculation, avoiding a modulo, as alignment always a power of 2 - cleanups
author Tassilo Philipp
date Mon, 20 Jun 2022 14:57:49 +0200
parents ba70fb631bea
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
1 /*
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
2
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
3 Package: dyncall
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
4 Library: dyncall
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
5 File: dyncall/dyncall_aggregate_x64.c
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
6 Description:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
7 License:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
8
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
9 Copyright (c) 2021-2022 Tassilo Philipp <tphilipp@potion-studios.com>
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
10
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
11 Permission to use, copy, modify, and distribute this software for any
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
12 purpose with or without fee is hereby granted, provided that the above
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
13 copyright notice and this permission notice appear in all copies.
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
14
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
22
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
23 */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
24
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
25
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
26 #if defined(DC_UNIX)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
27
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
28 #define DC_ONE_8BYTE 8
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
29 #define DC_TWO_8BYTES 2*8
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
30 #define DC_EIGHT_8BYTES 8*8
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
31
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
32 /* helper - long long mask with each byte being X */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
33 #define LLBYTE(X) ((X)&0xFFULL)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
34 #define SYSVC_CHECK_ALL_CLASSES(X) ((LLBYTE(X)<<56)|(LLBYTE(X)<<48)|(LLBYTE(X)<<40)|(LLBYTE(X)<<32)|(LLBYTE(X)<<24)|(LLBYTE(X)<<16)|(LLBYTE(X)<<8)|LLBYTE(X))
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
35
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
36
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
37 static DCuchar dc_merge_sysv_classes(DCuchar clz, DCuchar new_class)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
38 {
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
39 if(clz == SYSVC_NONE)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
40 return new_class;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
41
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
42 if(new_class == SYSVC_NONE)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
43 return clz;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
44
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
45 if(clz == SYSVC_MEMORY || new_class == SYSVC_MEMORY)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
46 return SYSVC_MEMORY;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
47
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
48 if(clz == SYSVC_INTEGER || new_class == SYSVC_INTEGER)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
49 return SYSVC_INTEGER;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
50
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
51 /* @@@AGGR implement when implementing x87 types
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
52 if((clz & (SYSVC_X87|SYSVC_X87UP|SYSVC_COMPLEX_X87)) || (new_class & (SYSVC_X87|SYSVC_X87UP|SYSVC_COMPLEX_X87)))
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
53 return SYSVC_MEMORY;*/
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
54
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
55 return SYSVC_SSE;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
56 }
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
57
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
58
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
59 static DCuchar dc_get_sysv_class_for_8byte(const DCaggr *ag, int index, int base_offset)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
60 {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
61 int qword_offset = index * DC_ONE_8BYTE, i;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
62 DCuchar clz = SYSVC_NONE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
63
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
64 for(i=0; i<ag->n_fields; ++i) {
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
65 const DCfield *f = ag->fields + i;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
66 DCsize offset = base_offset + f->offset;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
67
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
68 /* field outside of qword at index? */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
69 if(offset >= (qword_offset + DC_ONE_8BYTE) || (offset + f->size * f->array_len) <= qword_offset)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
70 continue;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
71
546
Tassilo Philipp
parents: 542
diff changeset
72 /* if field is unaligned, class is MEMORY */
551
eef302b7a58d - amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents: 546
diff changeset
73 assert((f->alignment & (f->alignment - 1)) == 0); /* f->alignment required to be a power of 2*/
eef302b7a58d - amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents: 546
diff changeset
74 if(f->alignment && (offset & (f->alignment - 1)) != 0) /* offset not a multiple of (power of 2) f->alignment? */
546
Tassilo Philipp
parents: 542
diff changeset
75 return SYSVC_MEMORY;
Tassilo Philipp
parents: 542
diff changeset
76
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
77 DCuchar new_class = SYSVC_NONE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
78
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
79 switch (f->type) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
80 case DC_SIGCHAR_BOOL:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
81 case DC_SIGCHAR_CHAR:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
82 case DC_SIGCHAR_UCHAR:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
83 case DC_SIGCHAR_SHORT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
84 case DC_SIGCHAR_USHORT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
85 case DC_SIGCHAR_INT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
86 case DC_SIGCHAR_UINT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
87 case DC_SIGCHAR_LONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
88 case DC_SIGCHAR_ULONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
89 case DC_SIGCHAR_LONGLONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
90 case DC_SIGCHAR_ULONGLONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
91 case DC_SIGCHAR_STRING:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
92 case DC_SIGCHAR_POINTER:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
93 new_class = SYSVC_INTEGER;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
94 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
95 case DC_SIGCHAR_FLOAT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
96 case DC_SIGCHAR_DOUBLE:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
97 new_class = SYSVC_SSE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
98 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
99 case DC_SIGCHAR_AGGREGATE:
551
eef302b7a58d - amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents: 546
diff changeset
100 /* skip empty structs */
eef302b7a58d - amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents: 546
diff changeset
101 if(f->size)
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
102 {
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
103 /* aggregate arrays need to be checked per element, as an aggregate can be composed of
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
104 * multiple types, potentially split across an 8byte; loop only over parts within 8byte */
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
105 int j = (qword_offset-offset) / f->size;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
106 int k = DC_ONE_8BYTE / f->size + j + 1; /* +1 for split array elements at end of 8byte */
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
107 if(k > f->array_len)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
108 k = f->array_len;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
109
551
eef302b7a58d - amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts
Tassilo Philipp
parents: 546
diff changeset
110 for(; j<k; ++j)
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
111 new_class = dc_merge_sysv_classes(new_class, dc_get_sysv_class_for_8byte(f->sub_aggr, index, offset + f->size*j));
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
112 }
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
113 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
114 /*case DClongdouble, DCcomplexfloat DCcomplexdouble DCcomplexlongdouble etc... -> x87/x87up/complexx87 classes @@@AGGR implement */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
115 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
116
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
117 if (clz == new_class)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
118 continue;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
119
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
120 clz = dc_merge_sysv_classes(clz, new_class);
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
121 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
122
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
123 return clz;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
124 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
125
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
126
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
127 static void dc_get_sysv_classes_for_aggr(const DCaggr *ag, DCuchar *classes)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
128 {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
129 int i;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
130
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
131 #if 1 /* this is the optimized version that only respects types supported by dyncall */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
132
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
133 if(ag->size > DC_TWO_8BYTES) { /* @@@AGGR not checking if a field is unaligned */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
134 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
135 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
136 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
137
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
138 /* abi doc: "If one of the classes is MEMORY, the whole argument is passed in memory." */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
139 classes[0] = dc_get_sysv_class_for_8byte(ag, 0, 0);
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
140 if(classes[0] != SYSVC_MEMORY) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
141 classes[1] = dc_get_sysv_class_for_8byte(ag, 1, 0);
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
142 if(classes[1] == SYSVC_MEMORY)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
143 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
144 else
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
145 classes[2] = SYSVC_NONE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
146 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
147 /* @@@AGGR what would happen with alignment-enforced padding >= 8? Then no field would cover the eightbyte @@@test */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
148
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
149 #else /* this would be the version following the ABI more closely, to be implemented fully or partly when those types get supported by dyncall */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
150
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
151 /* abi doc: "If the size of an object is larger than eight qwords, or it
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
152 * contains unaligned fields, it has class MEMORY."
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
153 * note: ABI specs <v1.0 (2018) specify "four qwords", instead (b/c _m512 was added, later) */ /* @@@AGGR not checking if a field is unaligned */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
154 if(ag->size > DC_EIGHT_8BYTES) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
155 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
156 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
157 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
158
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
159 /* classify fields according to each of max 8 qwords */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
160 for(i = 0; i < DC_SYSV_MAX_NUM_CLASSES; ++i) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
161 classes[i] = dc_get_sysv_class_for_8byte(ag, i, 0);
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
162
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
163 /* abi doc: "If one of the classes is MEMORY, the whole argument is passed in memory." */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
164 if(classes[i] == SYSVC_MEMORY) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
165 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
166 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
167 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
168
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
169 /* stop eightbyte classification on first SYSVC_NONE returned */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
170 /* @@@AGGR what would happen with alignment-enforced padding >= 8? Then no field would cover the eightbyte @@@test */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
171 if(classes[i] == SYSVC_NONE)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
172 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
173 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
174
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
175 /* Do post merger cleanup */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
176
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
177 /* abi doc: "If X87UP is not preceded by X87, the whole argument is passed in memory." */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
178 for(i = 1; i < DC_SYSV_MAX_NUM_CLASSES; ++i) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
179 if (classes[i-1] == SYSVC_X87 && classes[i] != SYSVC_X87UP) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
180 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
181 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
182 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
183 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
184
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
185 /* abi doc: "If the size of the aggregate exceeds two qwords and the first eightbyte isn't
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
186 * SSE or any other eightbyte isn't SSEUP, the whole argument is passed in memory." */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
187 if(ag->size > DC_TWO_8BYTES) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
188 DClonglong mask = SYSVC_CHECK_ALL_CLASSES(SYSVC_SSEUP|SYSVC_NONE) ^ (LLBYTE(SYSVC_SSE|SYSVC_SSEUP|SYSVC_NONE)<<56);
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
189 if((*(DClonglong*)ag->sysv_classes & mask) != *(DClonglong*)ag->sysv_classes) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
190 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
191 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
192 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
193 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
194
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
195 /* abi doc: "If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE." */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
196 for(i = 1; i < DC_SYSV_MAX_NUM_CLASSES; ++i) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
197 DCuchar clz = classes[i];
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
198 if(classes[i] == SYSVC_SSEUP && !(classes[i-1] & (SYSVC_SSE|SYSVC_SSEUP)))
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
199 classes[i] = SYSVC_SSE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
200 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
201
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
202 #endif
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
203 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
204
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
205
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
206 void dcFinishAggr(DCaggr *ag)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
207 {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
208 dc_get_sysv_classes_for_aggr(ag, ag->sysv_classes);
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
209
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
210 /* @@@AGGR implement when implementing x87 types
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
211 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:
diff changeset
212 assert((ag->sysv_classes[i] & (SYSVC_MEMORY|SYSVC_INTEGER|SYSVC_SSE)) && "Unsupported System V class detected in struct");*/
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
213 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
214
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
215 #else
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
216
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
217 void dcFinishAggr(DCaggr *ag)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
218 {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
219 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
220
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
221 #endif
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
222