stage2: Fix multiple_llvm_int parameter passing

Small iteration oopsie

We could really use some more comprehensive C ABI tests.
This commit is contained in:
Cody Tapscott 2022-09-27 19:57:43 -07:00 committed by Veikka Tuominen
parent f3a1b5c481
commit e165b8b223
3 changed files with 133 additions and 8 deletions

View File

@ -1035,10 +1035,11 @@ pub const Object = struct {
}
const ints_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
const casted_ptr = builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), "");
for (llvm_ints) |_, i_usize| {
const i = @intCast(c_uint, i_usize);
const param = llvm_func.getParam(i);
const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");
for (llvm_ints) |_, field_i_usize| {
const field_i = @intCast(c_uint, field_i_usize);
const param = llvm_func.getParam(llvm_arg_i);
llvm_arg_i += 1;
const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, field_i, "");
const store_inst = builder.buildStore(param, field_ptr);
store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
}
@ -1070,10 +1071,11 @@ pub const Object = struct {
}
const floats_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
const casted_ptr = builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), "");
for (llvm_floats) |_, i_usize| {
const i = @intCast(c_uint, i_usize);
const param = llvm_func.getParam(i);
const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, "");
for (llvm_floats) |_, field_i_usize| {
const field_i = @intCast(c_uint, field_i_usize);
const param = llvm_func.getParam(llvm_arg_i);
llvm_arg_i += 1;
const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, field_i, "");
const store_inst = builder.buildStore(param, field_ptr);
store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
}

View File

@ -120,6 +120,24 @@ typedef struct Vector5 {
float q;
} Vector5;
typedef struct Rect {
uint32_t left;
uint32_t right;
uint32_t top;
uint32_t bottom;
} Rect;
void zig_multiple_struct_ints(struct Rect, struct Rect);
typedef struct FloatRect {
float left;
float right;
float top;
float bottom;
} FloatRect;
void zig_multiple_struct_floats(struct FloatRect, struct FloatRect);
void run_c_tests(void) {
zig_u8(0xff);
zig_u16(0xfffe);
@ -200,6 +218,18 @@ void run_c_tests(void) {
assert_or_panic(res.e == 24);
}
{
struct Rect r1 = {1, 21, 16, 4};
struct Rect r2 = {178, 189, 21, 15};
zig_multiple_struct_ints(r1, r2);
}
{
struct FloatRect r1 = {1, 21, 16, 4};
struct FloatRect r2 = {178, 189, 21, 15};
zig_multiple_struct_floats(r1, r2);
}
{
assert_or_panic(zig_ret_bool() == 1);
@ -436,6 +466,28 @@ void c_big_struct_floats(Vector5 vec) {
assert_or_panic(vec.q == 55);
}
void c_multiple_struct_ints(Rect x, Rect y) {
assert_or_panic(x.left == 1);
assert_or_panic(x.right == 21);
assert_or_panic(x.top == 16);
assert_or_panic(x.bottom == 4);
assert_or_panic(y.left == 178);
assert_or_panic(y.right == 189);
assert_or_panic(y.top == 21);
assert_or_panic(y.bottom == 15);
}
void c_multiple_struct_floats(FloatRect x, FloatRect y) {
assert_or_panic(x.left == 1);
assert_or_panic(x.right == 21);
assert_or_panic(x.top == 16);
assert_or_panic(x.bottom == 4);
assert_or_panic(y.left == 178);
assert_or_panic(y.right == 189);
assert_or_panic(y.top == 21);
assert_or_panic(y.bottom == 15);
}
bool c_ret_bool() {
return 1;
}

View File

@ -355,6 +355,9 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void {
extern fn c_big_struct_both(BigStruct) BigStruct;
extern fn c_multiple_struct_ints(Rect, Rect) void;
extern fn c_multiple_struct_floats(FloatRect, FloatRect) void;
test "C ABI sret and byval together" {
var s = BigStruct{
.a = 1,
@ -423,6 +426,74 @@ test "C ABI structs of floats as parameter" {
c_big_struct_floats(v5);
}
const Rect = extern struct {
left: u32,
right: u32,
top: u32,
bottom: u32,
};
export fn zig_multiple_struct_ints(x: Rect, y: Rect) void {
expect(x.left == 1) catch @panic("test failure");
expect(x.right == 21) catch @panic("test failure");
expect(x.top == 16) catch @panic("test failure");
expect(x.bottom == 4) catch @panic("test failure");
expect(y.left == 178) catch @panic("test failure");
expect(y.right == 189) catch @panic("test failure");
expect(y.top == 21) catch @panic("test failure");
expect(y.bottom == 15) catch @panic("test failure");
}
test "C ABI structs of ints as multiple parameters" {
var r1 = Rect{
.left = 1,
.right = 21,
.top = 16,
.bottom = 4,
};
var r2 = Rect{
.left = 178,
.right = 189,
.top = 21,
.bottom = 15,
};
c_multiple_struct_ints(r1, r2);
}
const FloatRect = extern struct {
left: f32,
right: f32,
top: f32,
bottom: f32,
};
export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {
expect(x.left == 1) catch @panic("test failure");
expect(x.right == 21) catch @panic("test failure");
expect(x.top == 16) catch @panic("test failure");
expect(x.bottom == 4) catch @panic("test failure");
expect(y.left == 178) catch @panic("test failure");
expect(y.right == 189) catch @panic("test failure");
expect(y.top == 21) catch @panic("test failure");
expect(y.bottom == 15) catch @panic("test failure");
}
test "C ABI structs of floats as multiple parameters" {
var r1 = FloatRect{
.left = 1,
.right = 21,
.top = 16,
.bottom = 4,
};
var r2 = FloatRect{
.left = 178,
.right = 189,
.top = 21,
.bottom = 15,
};
c_multiple_struct_floats(r1, r2);
}
export fn zig_ret_bool() bool {
return true;
}