annotate dyncall/dyncall_aggregate_x64.c @ 546:ba70fb631bea

x64: * support for non-standard aggr-by-value packing (#pragma pack, etc.) * callbacks: handling callconv prefixes in signature
author Tassilo Philipp
date Tue, 31 May 2022 19:29:34 +0200
parents a73a5cd50c19
children eef302b7a58d
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 */
Tassilo Philipp
parents: 542
diff changeset
73 if(f->alignment && (offset % f->alignment) != 0)
Tassilo Philipp
parents: 542
diff changeset
74 return SYSVC_MEMORY;
Tassilo Philipp
parents: 542
diff changeset
75
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
76 DCuchar new_class = SYSVC_NONE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
77
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
78 switch (f->type) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
79 case DC_SIGCHAR_BOOL:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
80 case DC_SIGCHAR_CHAR:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
81 case DC_SIGCHAR_UCHAR:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
82 case DC_SIGCHAR_SHORT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
83 case DC_SIGCHAR_USHORT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
84 case DC_SIGCHAR_INT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
85 case DC_SIGCHAR_UINT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
86 case DC_SIGCHAR_LONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
87 case DC_SIGCHAR_ULONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
88 case DC_SIGCHAR_LONGLONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
89 case DC_SIGCHAR_ULONGLONG:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
90 case DC_SIGCHAR_STRING:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
91 case DC_SIGCHAR_POINTER:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
92 new_class = SYSVC_INTEGER;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
93 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
94 case DC_SIGCHAR_FLOAT:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
95 case DC_SIGCHAR_DOUBLE:
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
96 new_class = SYSVC_SSE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
97 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
98 case DC_SIGCHAR_AGGREGATE:
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
99 /* skip empty structs */
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
100 if(f->size)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
101 {
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
102 /* 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
103 * 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
104 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
105 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
106 if(k > f->array_len)
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
107 k = f->array_len;
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
108
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
109 for(; j<k; ++j) {
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
110 //@@@STRUCT 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
111 //@@@STRUCT clz = dc_merge_sysv_classes(clz, new_class);
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
112 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
113 }
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
114 }
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
115 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
116 /*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
117 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
118
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
119 if (clz == new_class)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
120 continue;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
121
542
a73a5cd50c19 - fix passing aggregate-by-val on x64/sysv: subaggr classification for
Tassilo Philipp
parents: 533
diff changeset
122 clz = dc_merge_sysv_classes(clz, new_class);
533
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
123 }
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 return clz;
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
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 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
130 {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
131 int i;
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 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
134
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
135 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
136 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
137 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
138 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
139
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
140 /* 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
141 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
142 if(classes[0] != SYSVC_MEMORY) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
143 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
144 if(classes[1] == SYSVC_MEMORY)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
145 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
146 else
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
147 classes[2] = SYSVC_NONE;
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 /* @@@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
150
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
151 #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
152
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
153 /* 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
154 * contains unaligned fields, it has class MEMORY."
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
155 * 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
156 if(ag->size > DC_EIGHT_8BYTES) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
157 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
158 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
159 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
160
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
161 /* classify fields according to each of max 8 qwords */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
162 for(i = 0; i < DC_SYSV_MAX_NUM_CLASSES; ++i) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
163 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
164
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
165 /* 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
166 if(classes[i] == SYSVC_MEMORY) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
167 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
168 return;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
169 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
170
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
171 /* stop eightbyte classification on first SYSVC_NONE returned */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
172 /* @@@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
173 if(classes[i] == SYSVC_NONE)
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
174 break;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
175 }
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 /* Do post merger cleanup */
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
178
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
179 /* 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
180 for(i = 1; i < DC_SYSV_MAX_NUM_CLASSES; ++i) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
181 if (classes[i-1] == SYSVC_X87 && classes[i] != SYSVC_X87UP) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
182 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
183 return;
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 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
186
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
187 /* 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
188 * 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
189 if(ag->size > DC_TWO_8BYTES) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
190 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
191 if((*(DClonglong*)ag->sysv_classes & mask) != *(DClonglong*)ag->sysv_classes) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
192 classes[0] = SYSVC_MEMORY;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
193 return;
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 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
196
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
197 /* 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
198 for(i = 1; i < DC_SYSV_MAX_NUM_CLASSES; ++i) {
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
199 DCuchar clz = classes[i];
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
200 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
201 classes[i] = SYSVC_SSE;
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
202 }
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 #endif
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
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 void dcFinishAggr(DCaggr *ag)
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 dc_get_sysv_classes_for_aggr(ag, ag->sysv_classes);
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
211
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
212 /* @@@AGGR implement when implementing x87 types
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
213 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
214 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
215 }
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 #else
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 void dcFinishAggr(DCaggr *ag)
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 }
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
222
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
223 #endif
71c884e610f0 - integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
diff changeset
224