diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
commit | 631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch) | |
tree | a1b87c8f8cad01cf18f7c5f57a08f102771ed303 /tests/run-make/extern-fn-struct-passing-abi/test.c | |
parent | Adding debian version 1.69.0+dfsg1-1. (diff) | |
download | rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/run-make/extern-fn-struct-passing-abi/test.c')
-rw-r--r-- | tests/run-make/extern-fn-struct-passing-abi/test.c | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/tests/run-make/extern-fn-struct-passing-abi/test.c b/tests/run-make/extern-fn-struct-passing-abi/test.c new file mode 100644 index 000000000..136b07129 --- /dev/null +++ b/tests/run-make/extern-fn-struct-passing-abi/test.c @@ -0,0 +1,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; +} |