summaryrefslogtreecommitdiffstats
path: root/tests/run-make-fulldeps/extern-fn-struct-passing-abi/test.c
blob: 136b07129e1df3518679cef224113b5c67382d29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#include <assert.h>
#include <stdint.h>

struct Rect {
    int32_t a;
    int32_t b;
    int32_t c;
    int32_t d;
};

struct BiggerRect {
    struct Rect s;
    int32_t a;
    int32_t b;
};

struct FloatRect {
    int32_t a;
    int32_t b;
    double c;
};

struct Huge {
    int32_t a;
    int32_t b;
    int32_t c;
    int32_t d;
    int32_t e;
};

struct FloatPoint {
    double x;
    double y;
};

struct FloatOne {
    double x;
};

struct IntOdd {
    int8_t a;
    int8_t b;
    int8_t c;
};

// System V x86_64 ABI:
// a, b, c, d, e should be in registers
// s should be byval pointer
//
// Win64 ABI:
// a, b, c, d should be in registers
// e should be on the stack
// s should be byval pointer
void byval_rect(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(c == 3);
    assert(d == 4);
    assert(e == 5);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
}

// System V x86_64 ABI:
// a, b, c, d, e, f should be in registers
// s should be byval pointer on the stack
//
// Win64 ABI:
// a, b, c, d should be in registers
// e, f should be on the stack
// s should be byval pointer on the stack
void byval_many_rect(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e,
                     int32_t f, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(c == 3);
    assert(d == 4);
    assert(e == 5);
    assert(f == 6);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
}

// System V x86_64 ABI:
// a, b, c, d, e, f, g should be in sse registers
// s should be split across 2 registers
// t should be byval pointer
//
// Win64 ABI:
// a, b, c, d should be in sse registers
// e, f, g should be on the stack
// s should be on the stack (treated as 2 i64's)
// t should be on the stack (treated as an i64 and a double)
void byval_rect_floats(float a, float b, double c, float d, float e,
                       float f, double g, struct Rect s, struct FloatRect t) {
    assert(a == 1.);
    assert(b == 2.);
    assert(c == 3.);
    assert(d == 4.);
    assert(e == 5.);
    assert(f == 6.);
    assert(g == 7.);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
    assert(t.a == 3489);
    assert(t.b == 3490);
    assert(t.c == 8.);
}

// System V x86_64 ABI:
// a, b, d, e, f should be in registers
// c passed via sse registers
// s should be byval pointer
//
// Win64 ABI:
// a, b, d should be in registers
// c passed via sse registers
// e, f should be on the stack
// s should be byval pointer
void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
                           int32_t e, int32_t f, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(c == 3.);
    assert(d == 4);
    assert(e == 5);
    assert(f == 6);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
}

// System V x86_64 ABI:
// a, b, d, e, f should be byval pointer (on the stack)
// g passed via register (fixes #41375)
//
// Win64 ABI:
// a, b, d, e, f, g should be byval pointer
void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
                               struct Huge d, struct Huge e, struct Huge f,
                               struct Rect g) {
    assert(g.a == 123);
    assert(g.b == 456);
    assert(g.c == 789);
    assert(g.d == 420);
}

// System V x86_64 & Win64 ABI:
// a, b should be in registers
// s should be split across 2 integer registers
void split_rect(int32_t a, int32_t b, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
}

// System V x86_64 & Win64 ABI:
// a, b should be in sse registers
// s should be split across integer & sse registers
void split_rect_floats(float a, float b, struct FloatRect s) {
    assert(a == 1.);
    assert(b == 2.);
    assert(s.a == 3489);
    assert(s.b == 3490);
    assert(s.c == 8.);
}

// System V x86_64 ABI:
// a, b, d, f should be in registers
// c, e passed via sse registers
// s should be split across 2 registers
//
// Win64 ABI:
// a, b, d should be in registers
// c passed via sse registers
// e, f should be on the stack
// s should be on the stack (treated as 2 i64's)
void split_rect_with_floats(int32_t a, int32_t b, float c,
                            int32_t d, float e, int32_t f, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(c == 3.);
    assert(d == 4);
    assert(e == 5.);
    assert(f == 6);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
}

// System V x86_64 & Win64 ABI:
// a, b, c should be in registers
// s should be split across 2 registers
// t should be a byval pointer
void split_and_byval_rect(int32_t a, int32_t b, int32_t c, struct Rect s, struct Rect t) {
    assert(a == 1);
    assert(b == 2);
    assert(c == 3);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
    assert(t.a == 553);
    assert(t.b == 554);
    assert(t.c == 555);
    assert(t.d == 556);
}

// System V x86_64 & Win64 ABI:
// a, b should in registers
// s and return should be split across 2 registers
struct Rect split_ret_byval_struct(int32_t a, int32_t b, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);
    return s;
}

// System V x86_64 & Win64 ABI:
// a, b, c, d should be in registers
// return should be in a hidden sret pointer
// s should be a byval pointer
struct BiggerRect sret_byval_struct(int32_t a, int32_t b, int32_t c, int32_t d, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(c == 3);
    assert(d == 4);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);

    struct BiggerRect t;
    t.s = s; t.a = 27834; t.b = 7657;
    return t;
}

// System V x86_64 & Win64 ABI:
// a, b should be in registers
// return should be in a hidden sret pointer
// s should be split across 2 registers
struct BiggerRect sret_split_struct(int32_t a, int32_t b, struct Rect s) {
    assert(a == 1);
    assert(b == 2);
    assert(s.a == 553);
    assert(s.b == 554);
    assert(s.c == 555);
    assert(s.d == 556);

    struct BiggerRect t;
    t.s = s; t.a = 27834; t.b = 7657;
    return t;
}

// System V x86_64 & Win64 ABI:
// s should be byval pointer (since sizeof(s) > 16)
// return should in a hidden sret pointer
struct Huge huge_struct(struct Huge s) {
    assert(s.a == 5647);
    assert(s.b == 5648);
    assert(s.c == 5649);
    assert(s.d == 5650);
    assert(s.e == 5651);

    return s;
}

// System V x86_64 ABI:
// p should be in registers
// return should be in registers
//
// Win64 ABI and 64-bit PowerPC ELFv1 ABI:
// p should be a byval pointer
// return should be in a hidden sret pointer
struct FloatPoint float_point(struct FloatPoint p) {
    assert(p.x == 5.);
    assert(p.y == -3.);

    return p;
}

// 64-bit PowerPC ELFv1 ABI:
// f1 should be in a register
// return should be in a hidden sret pointer
struct FloatOne float_one(struct FloatOne f1) {
    assert(f1.x == 7.);

    return f1;
}

// 64-bit PowerPC ELFv1 ABI:
// i should be in the least-significant bits of a register
// return should be in a hidden sret pointer
struct IntOdd int_odd(struct IntOdd i) {
    assert(i.a == 1);
    assert(i.b == 2);
    assert(i.c == 3);

    return i;
}