authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-07 18:47:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-07 18:51:34-04:00
log9017efee220950b11070242415b6dc456d4442df
tree12feb8c48f36b6caa94862310c54939065fb16d9
parent85534a26c6ddea6277e79b12b759188689f3da43
signaturelock-open Commit is signed but in an unrecognized format.

C ABI: support medium size structs & unions for x86_64 params

See #1481

3 files changed, 49 insertions(+), 3 deletions(-)

src/codegen.cpp+9-3
......@@ -354,8 +354,12 @@ static void addLLVMFnAttrInt(LLVMValueRef fn_val, const char *attr_name, uint64_
354354 return addLLVMAttrInt(fn_val, -1, attr_name, attr_val);
355355}
356356
357static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) {
358 return addLLVMAttr(arg_val, param_index + 1, attr_name);
357static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char *attr_name) {
358 return addLLVMAttr(fn_val, param_index + 1, attr_name);
359}
360
361static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) {
362 return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val);
359363}
360364
361365static bool is_symbol_available(CodeGen *g, Buf *name) {
......@@ -2096,6 +2100,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20962100 switch (fn_walk->id) {
20972101 case FnWalkIdAttrs:
20982102 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
2103 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
20992104 fn_walk->data.attrs.gen_i += 1;
21002105 break;
21012106 case FnWalkIdCall:
......@@ -2132,6 +2137,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
21322137 switch (fn_walk->id) {
21332138 case FnWalkIdAttrs:
21342139 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");
2140 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
21352141 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
21362142 fn_walk->data.attrs.gen_i += 1;
21372143 break;
......@@ -2159,7 +2165,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
21592165 break;
21602166 }
21612167 return true;
2162 } else if (abi_class == X64CABIClass_INTEGER && ty_size <= 8) {
2168 } else if (abi_class == X64CABIClass_INTEGER) {
21632169 switch (fn_walk->id) {
21642170 case FnWalkIdAttrs:
21652171 fn_walk->data.attrs.gen_i += 1;
test/stage1/c_abi/cfuncs.c+18
......@@ -52,6 +52,13 @@ struct SmallStructInts {
5252};
5353void zig_small_struct_ints(struct SmallStructInts);
5454
55struct SplitStructInts {
56 uint64_t a;
57 uint8_t b;
58 uint32_t c;
59};
60void zig_split_struct_ints(struct SplitStructInts);
61
5562void run_c_tests(void) {
5663 zig_u8(0xff);
5764 zig_u16(0xfffe);
......@@ -83,6 +90,11 @@ void run_c_tests(void) {
8390 struct SmallStructInts s = {1, 2, 3, 4};
8491 zig_small_struct_ints(s);
8592 }
93
94 {
95 struct SplitStructInts s = {1234, 100, 1337};
96 zig_split_struct_ints(s);
97 }
8698}
8799
88100void c_u8(uint8_t x) {
......@@ -167,3 +179,9 @@ void c_small_struct_ints(struct SmallStructInts x) {
167179 assert_or_panic(x.c == 3);
168180 assert_or_panic(x.d == 4);
169181}
182
183void c_split_struct_ints(struct SplitStructInts x) {
184 assert_or_panic(x.a == 1234);
185 assert_or_panic(x.b == 100);
186 assert_or_panic(x.c == 1337);
187}
test/stage1/c_abi/main.zig+22
......@@ -181,3 +181,25 @@ export fn zig_small_struct_ints(x: SmallStructInts) void {
181181 assertOrPanic(x.c == 3);
182182 assertOrPanic(x.d == 4);
183183}
184
185const SplitStructInt = extern struct {
186 a: u64,
187 b: u8,
188 c: u32,
189};
190extern fn c_split_struct_ints(SplitStructInt) void;
191
192test "C ABI split struct of ints" {
193 var s = SplitStructInt{
194 .a = 1234,
195 .b = 100,
196 .c = 1337,
197 };
198 c_split_struct_ints(s);
199}
200
201export fn zig_split_struct_ints(x: SplitStructInt) void {
202 assertOrPanic(x.a == 1234);
203 assertOrPanic(x.b == 100);
204 assertOrPanic(x.c == 1337);
205}