#include #include struct S { uint8_t x; int32_t y; }; struct S2 { int32_t x; uint8_t y; }; struct S3 { uint8_t x[5]; }; __declspec(dllexport) void __stdcall stdcall_fn_1(int i) { printf("stdcall_fn_1(%d)\n", i); fflush(stdout); } __declspec(dllexport) void __stdcall stdcall_fn_2(uint8_t i, float f) { printf("stdcall_fn_2(%d, %.1f)\n", i, f); fflush(stdout); } __declspec(dllexport) void __stdcall stdcall_fn_3(double d) { printf("stdcall_fn_3(%.1f)\n", d); fflush(stdout); } __declspec(dllexport) void __stdcall stdcall_fn_4(uint8_t i, uint8_t j, float f) { printf("stdcall_fn_4(%d, %d, %.1f)\n", i, j, f); fflush(stdout); } __declspec(dllexport) void __stdcall stdcall_fn_5(struct S s, int i) { printf("stdcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i); fflush(stdout); } // Test that stdcall support works correctly with the nullable pointer optimization. __declspec(dllexport) void __stdcall stdcall_fn_6(struct S* s) { if (s) { printf("stdcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y); } else { printf("stdcall_fn_6(null)\n"); } fflush(stdout); } __declspec(dllexport) void __stdcall stdcall_fn_7(struct S2 s, int i) { printf("stdcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i); fflush(stdout); } // Verify that we compute the correct amount of space in the argument list for a 5-byte struct. __declspec(dllexport) void __stdcall stdcall_fn_8(struct S3 s, struct S3 t) { printf("stdcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n", s.x[0], s.x[1], s.x[2], s.x[3], s.x[4], t.x[0], t.x[1], t.x[2], t.x[3], t.x[4] ); fflush(stdout); } // test whether f64/double values are aligned on 4-byte or 8-byte boundaries. __declspec(dllexport) void __stdcall stdcall_fn_9(uint8_t x, double y) { printf("stdcall_fn_9(%d, %.1f)\n", x, y); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_1(int i) { printf("fastcall_fn_1(%d)\n", i); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_2(uint8_t i, float f) { printf("fastcall_fn_2(%d, %.1f)\n", i, f); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_3(double d) { printf("fastcall_fn_3(%.1f)\n", d); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_4(uint8_t i, uint8_t j, float f) { printf("fastcall_fn_4(%d, %d, %.1f)\n", i, j, f); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_5(struct S s, int i) { printf("fastcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_6(struct S* s) { if (s) { printf("fastcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y); } else { printf("fastcall_fn_6(null)\n"); } fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_7(struct S2 s, int i) { printf("fastcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_8(struct S3 s, struct S3 t) { printf("fastcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n", s.x[0], s.x[1], s.x[2], s.x[3], s.x[4], t.x[0], t.x[1], t.x[2], t.x[3], t.x[4] ); fflush(stdout); } __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) { printf("fastcall_fn_9(%d, %.1f)\n", x, y); fflush(stdout); } // GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485 #ifdef _MSC_VER __declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) { printf("vectorcall_fn_1(%d)\n", i); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_2(uint8_t i, float f) { printf("vectorcall_fn_2(%d, %.1f)\n", i, f); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_3(double d) { printf("vectorcall_fn_3(%.1f)\n", d); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_4(uint8_t i, uint8_t j, float f) { printf("vectorcall_fn_4(%d, %d, %.1f)\n", i, j, f); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_5(struct S s, int i) { printf("vectorcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_6(struct S* s) { if (s) { printf("vectorcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y); } else { printf("vectorcall_fn_6(null)\n"); } fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_7(struct S2 s, int i) { printf("vectorcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_8(struct S3 s, struct S3 t) { printf("vectorcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n", s.x[0], s.x[1], s.x[2], s.x[3], s.x[4], t.x[0], t.x[1], t.x[2], t.x[3], t.x[4] ); fflush(stdout); } __declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) { printf("vectorcall_fn_9(%d, %.1f)\n", x, y); fflush(stdout); } #endif