mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
x86_64: fix abi of a struct that partially fits in registers
Closes #26035
This commit is contained in:
parent
51bb2b3d2d
commit
a1827d5977
3 changed files with 78 additions and 54 deletions
|
|
@ -181159,6 +181159,9 @@ fn resolveCallingConventionValues(
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const save_param_gpr_index = param_gpr_index;
|
||||||
|
const save_param_sse_index = param_gpr_index;
|
||||||
|
|
||||||
var arg_mcv: [4]MCValue = undefined;
|
var arg_mcv: [4]MCValue = undefined;
|
||||||
var arg_mcv_len: u32 = 0;
|
var arg_mcv_len: u32 = 0;
|
||||||
|
|
||||||
|
|
@ -181258,6 +181261,9 @@ fn resolveCallingConventionValues(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
param_gpr_index = save_param_gpr_index;
|
||||||
|
param_sse_index = save_param_sse_index;
|
||||||
|
|
||||||
const param_align = ty.abiAlignment(zcu).max(.@"8");
|
const param_align = ty.abiAlignment(zcu).max(.@"8");
|
||||||
result.stack_byte_count = @intCast(param_align.forward(result.stack_byte_count));
|
result.stack_byte_count = @intCast(param_align.forward(result.stack_byte_count));
|
||||||
result.stack_align = result.stack_align.max(param_align);
|
result.stack_align = result.stack_align.max(param_align);
|
||||||
|
|
|
||||||
|
|
@ -212,55 +212,64 @@ struct Struct_u64_u64 {
|
||||||
|
|
||||||
struct Struct_u64_u64 zig_ret_struct_u64_u64(void);
|
struct Struct_u64_u64 zig_ret_struct_u64_u64(void);
|
||||||
|
|
||||||
void zig_struct_u64_u64_0(struct Struct_u64_u64);
|
void zig_struct_u64_u64_0(struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_1(size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_1(size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_2(size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_2(size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_3(size_t, size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_3(size_t, size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_4(size_t, size_t, size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_4(size_t, size_t, size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_5(size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_5(size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_6(size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_6(size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_7(size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_7(size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
void zig_struct_u64_u64_8(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64);
|
void zig_struct_u64_u64_8(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64, size_t);
|
||||||
|
|
||||||
struct Struct_u64_u64 c_ret_struct_u64_u64(void) {
|
struct Struct_u64_u64 c_ret_struct_u64_u64(void) {
|
||||||
return (struct Struct_u64_u64){ 21, 22 };
|
return (struct Struct_u64_u64){ 21, 22 };
|
||||||
}
|
}
|
||||||
|
|
||||||
void c_struct_u64_u64_0(struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_0(struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 23);
|
assert_or_panic(s.a == 23);
|
||||||
assert_or_panic(s.b == 24);
|
assert_or_panic(s.b == 24);
|
||||||
|
assert_or_panic(i == 1);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_1(size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_1(size_t a0, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 25);
|
assert_or_panic(s.a == 25);
|
||||||
assert_or_panic(s.b == 26);
|
assert_or_panic(s.b == 26);
|
||||||
|
assert_or_panic(i == 2);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_2(size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_2(size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 27);
|
assert_or_panic(s.a == 27);
|
||||||
assert_or_panic(s.b == 28);
|
assert_or_panic(s.b == 28);
|
||||||
|
assert_or_panic(i == 3);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_3(size_t, size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_3(size_t, size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 29);
|
assert_or_panic(s.a == 29);
|
||||||
assert_or_panic(s.b == 30);
|
assert_or_panic(s.b == 30);
|
||||||
|
assert_or_panic(i == 4);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_4(size_t, size_t, size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_4(size_t, size_t, size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 31);
|
assert_or_panic(s.a == 31);
|
||||||
assert_or_panic(s.b == 32);
|
assert_or_panic(s.b == 32);
|
||||||
|
assert_or_panic(i == 5);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_5(size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_5(size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 33);
|
assert_or_panic(s.a == 33);
|
||||||
assert_or_panic(s.b == 34);
|
assert_or_panic(s.b == 34);
|
||||||
|
assert_or_panic(i == 6);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_6(size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_6(size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 35);
|
assert_or_panic(s.a == 35);
|
||||||
assert_or_panic(s.b == 36);
|
assert_or_panic(s.b == 36);
|
||||||
|
assert_or_panic(i == 7);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_7(size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_7(size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 37);
|
assert_or_panic(s.a == 37);
|
||||||
assert_or_panic(s.b == 38);
|
assert_or_panic(s.b == 38);
|
||||||
|
assert_or_panic(i == 8);
|
||||||
}
|
}
|
||||||
void c_struct_u64_u64_8(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s) {
|
void c_struct_u64_u64_8(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, struct Struct_u64_u64 s, size_t i) {
|
||||||
assert_or_panic(s.a == 39);
|
assert_or_panic(s.a == 39);
|
||||||
assert_or_panic(s.b == 40);
|
assert_or_panic(s.b == 40);
|
||||||
|
assert_or_panic(i == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Struct_f32 {
|
struct Struct_f32 {
|
||||||
|
|
@ -2737,15 +2746,15 @@ void run_c_tests(void) {
|
||||||
struct Struct_u64_u64 s = zig_ret_struct_u64_u64();
|
struct Struct_u64_u64 s = zig_ret_struct_u64_u64();
|
||||||
assert_or_panic(s.a == 1);
|
assert_or_panic(s.a == 1);
|
||||||
assert_or_panic(s.b == 2);
|
assert_or_panic(s.b == 2);
|
||||||
zig_struct_u64_u64_0((struct Struct_u64_u64){ .a = 3, .b = 4 });
|
zig_struct_u64_u64_0((struct Struct_u64_u64){ .a = 3, .b = 4 }, 1);
|
||||||
zig_struct_u64_u64_1(0, (struct Struct_u64_u64){ .a = 5, .b = 6 });
|
zig_struct_u64_u64_1(0, (struct Struct_u64_u64){ .a = 5, .b = 6 }, 2);
|
||||||
zig_struct_u64_u64_2(0, 1, (struct Struct_u64_u64){ .a = 7, .b = 8 });
|
zig_struct_u64_u64_2(0, 1, (struct Struct_u64_u64){ .a = 7, .b = 8 }, 3);
|
||||||
zig_struct_u64_u64_3(0, 1, 2, (struct Struct_u64_u64){ .a = 9, .b = 10 });
|
zig_struct_u64_u64_3(0, 1, 2, (struct Struct_u64_u64){ .a = 9, .b = 10 }, 4);
|
||||||
zig_struct_u64_u64_4(0, 1, 2, 3, (struct Struct_u64_u64){ .a = 11, .b = 12 });
|
zig_struct_u64_u64_4(0, 1, 2, 3, (struct Struct_u64_u64){ .a = 11, .b = 12 }, 5);
|
||||||
zig_struct_u64_u64_5(0, 1, 2, 3, 4, (struct Struct_u64_u64){ .a = 13, .b = 14 });
|
zig_struct_u64_u64_5(0, 1, 2, 3, 4, (struct Struct_u64_u64){ .a = 13, .b = 14 }, 6);
|
||||||
zig_struct_u64_u64_6(0, 1, 2, 3, 4, 5, (struct Struct_u64_u64){ .a = 15, .b = 16 });
|
zig_struct_u64_u64_6(0, 1, 2, 3, 4, 5, (struct Struct_u64_u64){ .a = 15, .b = 16 }, 7);
|
||||||
zig_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, (struct Struct_u64_u64){ .a = 17, .b = 18 });
|
zig_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, (struct Struct_u64_u64){ .a = 17, .b = 18 }, 8);
|
||||||
zig_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, (struct Struct_u64_u64){ .a = 19, .b = 20 });
|
zig_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, (struct Struct_u64_u64){ .a = 19, .b = 20 }, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(ZIG_RISCV64)
|
#if !defined(ZIG_RISCV64)
|
||||||
|
|
|
||||||
|
|
@ -278,54 +278,63 @@ export fn zig_ret_struct_u64_u64() Struct_u64_u64 {
|
||||||
return .{ .a = 1, .b = 2 };
|
return .{ .a = 1, .b = 2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn zig_struct_u64_u64_0(s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_0(s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 3) catch @panic("test failure");
|
expect(s.a == 3) catch @panic("test failure");
|
||||||
expect(s.b == 4) catch @panic("test failure");
|
expect(s.b == 4) catch @panic("test failure");
|
||||||
|
expect(i == 1) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_1(_: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_1(_: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 5) catch @panic("test failure");
|
expect(s.a == 5) catch @panic("test failure");
|
||||||
expect(s.b == 6) catch @panic("test failure");
|
expect(s.b == 6) catch @panic("test failure");
|
||||||
|
expect(i == 2) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_2(_: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_2(_: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 7) catch @panic("test failure");
|
expect(s.a == 7) catch @panic("test failure");
|
||||||
expect(s.b == 8) catch @panic("test failure");
|
expect(s.b == 8) catch @panic("test failure");
|
||||||
|
expect(i == 3) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_3(_: usize, _: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_3(_: usize, _: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 9) catch @panic("test failure");
|
expect(s.a == 9) catch @panic("test failure");
|
||||||
expect(s.b == 10) catch @panic("test failure");
|
expect(s.b == 10) catch @panic("test failure");
|
||||||
|
expect(i == 4) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_4(_: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_4(_: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 11) catch @panic("test failure");
|
expect(s.a == 11) catch @panic("test failure");
|
||||||
expect(s.b == 12) catch @panic("test failure");
|
expect(s.b == 12) catch @panic("test failure");
|
||||||
|
expect(i == 5) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_5(_: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_5(_: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 13) catch @panic("test failure");
|
expect(s.a == 13) catch @panic("test failure");
|
||||||
expect(s.b == 14) catch @panic("test failure");
|
expect(s.b == 14) catch @panic("test failure");
|
||||||
|
expect(i == 6) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_6(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_6(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 15) catch @panic("test failure");
|
expect(s.a == 15) catch @panic("test failure");
|
||||||
expect(s.b == 16) catch @panic("test failure");
|
expect(s.b == 16) catch @panic("test failure");
|
||||||
|
expect(i == 7) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_7(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_7(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 17) catch @panic("test failure");
|
expect(s.a == 17) catch @panic("test failure");
|
||||||
expect(s.b == 18) catch @panic("test failure");
|
expect(s.b == 18) catch @panic("test failure");
|
||||||
|
expect(i == 8) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
export fn zig_struct_u64_u64_8(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
|
export fn zig_struct_u64_u64_8(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64, i: usize) void {
|
||||||
expect(s.a == 19) catch @panic("test failure");
|
expect(s.a == 19) catch @panic("test failure");
|
||||||
expect(s.b == 20) catch @panic("test failure");
|
expect(s.b == 20) catch @panic("test failure");
|
||||||
|
expect(i == 9) catch @panic("test failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn c_ret_struct_u64_u64() Struct_u64_u64;
|
extern fn c_ret_struct_u64_u64() Struct_u64_u64;
|
||||||
|
|
||||||
extern fn c_struct_u64_u64_0(Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_0(Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_1(usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_1(usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_2(usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_2(usize, usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_3(usize, usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_3(usize, usize, usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_4(usize, usize, usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_4(usize, usize, usize, usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_5(usize, usize, usize, usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_5(usize, usize, usize, usize, usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_6(usize, usize, usize, usize, usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_6(usize, usize, usize, usize, usize, usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_7(usize, usize, usize, usize, usize, usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_7(usize, usize, usize, usize, usize, usize, usize, Struct_u64_u64, usize) void;
|
||||||
extern fn c_struct_u64_u64_8(usize, usize, usize, usize, usize, usize, usize, usize, Struct_u64_u64) void;
|
extern fn c_struct_u64_u64_8(usize, usize, usize, usize, usize, usize, usize, usize, Struct_u64_u64, usize) void;
|
||||||
|
|
||||||
test "C ABI struct u64 u64" {
|
test "C ABI struct u64 u64" {
|
||||||
if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
|
if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
|
||||||
|
|
@ -336,15 +345,15 @@ test "C ABI struct u64 u64" {
|
||||||
const s = c_ret_struct_u64_u64();
|
const s = c_ret_struct_u64_u64();
|
||||||
try expect(s.a == 21);
|
try expect(s.a == 21);
|
||||||
try expect(s.b == 22);
|
try expect(s.b == 22);
|
||||||
c_struct_u64_u64_0(.{ .a = 23, .b = 24 });
|
c_struct_u64_u64_0(.{ .a = 23, .b = 24 }, 1);
|
||||||
c_struct_u64_u64_1(0, .{ .a = 25, .b = 26 });
|
c_struct_u64_u64_1(0, .{ .a = 25, .b = 26 }, 2);
|
||||||
c_struct_u64_u64_2(0, 1, .{ .a = 27, .b = 28 });
|
c_struct_u64_u64_2(0, 1, .{ .a = 27, .b = 28 }, 3);
|
||||||
c_struct_u64_u64_3(0, 1, 2, .{ .a = 29, .b = 30 });
|
c_struct_u64_u64_3(0, 1, 2, .{ .a = 29, .b = 30 }, 4);
|
||||||
c_struct_u64_u64_4(0, 1, 2, 3, .{ .a = 31, .b = 32 });
|
c_struct_u64_u64_4(0, 1, 2, 3, .{ .a = 31, .b = 32 }, 5);
|
||||||
c_struct_u64_u64_5(0, 1, 2, 3, 4, .{ .a = 33, .b = 34 });
|
c_struct_u64_u64_5(0, 1, 2, 3, 4, .{ .a = 33, .b = 34 }, 6);
|
||||||
c_struct_u64_u64_6(0, 1, 2, 3, 4, 5, .{ .a = 35, .b = 36 });
|
c_struct_u64_u64_6(0, 1, 2, 3, 4, 5, .{ .a = 35, .b = 36 }, 7);
|
||||||
c_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, .{ .a = 37, .b = 38 });
|
c_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, .{ .a = 37, .b = 38 }, 8);
|
||||||
c_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, .{ .a = 39, .b = 40 });
|
c_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, .{ .a = 39, .b = 40 }, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Struct_f32 = extern struct {
|
const Struct_f32 = extern struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue