authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-09-27 19:57:43-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-28 12:48:28+03:00
loge165b8b223bfaaeb5953dec9a1f03b8e0ce4ddab
tree67af3c2ea71a7b50d283009ed92f0d08223e221d
parentf3a1b5c481646ee35813cbe8bb2b0a3979df3ab8

stage2: Fix multiple_llvm_int parameter passing

Small iteration oopsie We could really use some more comprehensive C ABI tests.

3 files changed, 133 insertions(+), 8 deletions(-)

src/codegen/llvm.zig+10-8
......@@ -1035,10 +1035,11 @@ pub const Object = struct {
10351035 }
10361036 const ints_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
10371037 const casted_ptr = builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), "");
1038 for (llvm_ints) |_, i_usize| {
1039 const i = @intCast(c_uint, i_usize);
1040 const param = llvm_func.getParam(i);
1041 const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");
1038 for (llvm_ints) |_, field_i_usize| {
1039 const field_i = @intCast(c_uint, field_i_usize);
1040 const param = llvm_func.getParam(llvm_arg_i);
1041 llvm_arg_i += 1;
1042 const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, field_i, "");
10421043 const store_inst = builder.buildStore(param, field_ptr);
10431044 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
10441045 }
......@@ -1070,10 +1071,11 @@ pub const Object = struct {
10701071 }
10711072 const floats_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
10721073 const casted_ptr = builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), "");
1073 for (llvm_floats) |_, i_usize| {
1074 const i = @intCast(c_uint, i_usize);
1075 const param = llvm_func.getParam(i);
1076 const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, "");
1074 for (llvm_floats) |_, field_i_usize| {
1075 const field_i = @intCast(c_uint, field_i_usize);
1076 const param = llvm_func.getParam(llvm_arg_i);
1077 llvm_arg_i += 1;
1078 const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, field_i, "");
10771079 const store_inst = builder.buildStore(param, field_ptr);
10781080 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
10791081 }
test/c_abi/cfuncs.c+52
......@@ -120,6 +120,24 @@ typedef struct Vector5 {
120120 float q;
121121} Vector5;
122122
123typedef struct Rect {
124 uint32_t left;
125 uint32_t right;
126 uint32_t top;
127 uint32_t bottom;
128} Rect;
129
130void zig_multiple_struct_ints(struct Rect, struct Rect);
131
132typedef struct FloatRect {
133 float left;
134 float right;
135 float top;
136 float bottom;
137} FloatRect;
138
139void zig_multiple_struct_floats(struct FloatRect, struct FloatRect);
140
123141void run_c_tests(void) {
124142 zig_u8(0xff);
125143 zig_u16(0xfffe);
......@@ -200,6 +218,18 @@ void run_c_tests(void) {
200218 assert_or_panic(res.e == 24);
201219 }
202220
221 {
222 struct Rect r1 = {1, 21, 16, 4};
223 struct Rect r2 = {178, 189, 21, 15};
224 zig_multiple_struct_ints(r1, r2);
225 }
226
227 {
228 struct FloatRect r1 = {1, 21, 16, 4};
229 struct FloatRect r2 = {178, 189, 21, 15};
230 zig_multiple_struct_floats(r1, r2);
231 }
232
203233 {
204234 assert_or_panic(zig_ret_bool() == 1);
205235
......@@ -436,6 +466,28 @@ void c_big_struct_floats(Vector5 vec) {
436466 assert_or_panic(vec.q == 55);
437467}
438468
469void c_multiple_struct_ints(Rect x, Rect y) {
470 assert_or_panic(x.left == 1);
471 assert_or_panic(x.right == 21);
472 assert_or_panic(x.top == 16);
473 assert_or_panic(x.bottom == 4);
474 assert_or_panic(y.left == 178);
475 assert_or_panic(y.right == 189);
476 assert_or_panic(y.top == 21);
477 assert_or_panic(y.bottom == 15);
478}
479
480void c_multiple_struct_floats(FloatRect x, FloatRect y) {
481 assert_or_panic(x.left == 1);
482 assert_or_panic(x.right == 21);
483 assert_or_panic(x.top == 16);
484 assert_or_panic(x.bottom == 4);
485 assert_or_panic(y.left == 178);
486 assert_or_panic(y.right == 189);
487 assert_or_panic(y.top == 21);
488 assert_or_panic(y.bottom == 15);
489}
490
439491bool c_ret_bool() {
440492 return 1;
441493}
test/c_abi/main.zig+71
......@@ -355,6 +355,9 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void {
355355
356356extern fn c_big_struct_both(BigStruct) BigStruct;
357357
358extern fn c_multiple_struct_ints(Rect, Rect) void;
359extern fn c_multiple_struct_floats(FloatRect, FloatRect) void;
360
358361test "C ABI sret and byval together" {
359362 var s = BigStruct{
360363 .a = 1,
......@@ -423,6 +426,74 @@ test "C ABI structs of floats as parameter" {
423426 c_big_struct_floats(v5);
424427}
425428
429const Rect = extern struct {
430 left: u32,
431 right: u32,
432 top: u32,
433 bottom: u32,
434};
435
436export fn zig_multiple_struct_ints(x: Rect, y: Rect) void {
437 expect(x.left == 1) catch @panic("test failure");
438 expect(x.right == 21) catch @panic("test failure");
439 expect(x.top == 16) catch @panic("test failure");
440 expect(x.bottom == 4) catch @panic("test failure");
441 expect(y.left == 178) catch @panic("test failure");
442 expect(y.right == 189) catch @panic("test failure");
443 expect(y.top == 21) catch @panic("test failure");
444 expect(y.bottom == 15) catch @panic("test failure");
445}
446
447test "C ABI structs of ints as multiple parameters" {
448 var r1 = Rect{
449 .left = 1,
450 .right = 21,
451 .top = 16,
452 .bottom = 4,
453 };
454 var r2 = Rect{
455 .left = 178,
456 .right = 189,
457 .top = 21,
458 .bottom = 15,
459 };
460 c_multiple_struct_ints(r1, r2);
461}
462
463const FloatRect = extern struct {
464 left: f32,
465 right: f32,
466 top: f32,
467 bottom: f32,
468};
469
470export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {
471 expect(x.left == 1) catch @panic("test failure");
472 expect(x.right == 21) catch @panic("test failure");
473 expect(x.top == 16) catch @panic("test failure");
474 expect(x.bottom == 4) catch @panic("test failure");
475 expect(y.left == 178) catch @panic("test failure");
476 expect(y.right == 189) catch @panic("test failure");
477 expect(y.top == 21) catch @panic("test failure");
478 expect(y.bottom == 15) catch @panic("test failure");
479}
480
481test "C ABI structs of floats as multiple parameters" {
482 var r1 = FloatRect{
483 .left = 1,
484 .right = 21,
485 .top = 16,
486 .bottom = 4,
487 };
488 var r2 = FloatRect{
489 .left = 178,
490 .right = 189,
491 .top = 21,
492 .bottom = 15,
493 };
494 c_multiple_struct_floats(r1, r2);
495}
496
426497export fn zig_ret_bool() bool {
427498 return true;
428499}