Mercurial > pub > dyncall > dyncall
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 |
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 | 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 | 75 return SYSVC_MEMORY; |
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 |