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_...@@ -354,8 +354,12 @@ static void addLLVMFnAttrInt(LLVMValueRef fn_val, const char *attr_name, uint64_
354 return addLLVMAttrInt(fn_val, -1, attr_name, attr_val);354 return addLLVMAttrInt(fn_val, -1, attr_name, attr_val);
355}355}
356356
357static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) {357static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char *attr_name) {
358 return addLLVMAttr(arg_val, param_index + 1, 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);
359}363}
360364
361static bool is_symbol_available(CodeGen *g, Buf *name) {365static 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_...@@ -2096,6 +2100,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2096 switch (fn_walk->id) {2100 switch (fn_walk->id) {
2097 case FnWalkIdAttrs:2101 case FnWalkIdAttrs:
2098 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");2102 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));
2099 fn_walk->data.attrs.gen_i += 1;2104 fn_walk->data.attrs.gen_i += 1;
2100 break;2105 break;
2101 case FnWalkIdCall:2106 case FnWalkIdCall:
...@@ -2132,6 +2137,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2132,6 +2137,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2132 switch (fn_walk->id) {2137 switch (fn_walk->id) {
2133 case FnWalkIdAttrs:2138 case FnWalkIdAttrs:
2134 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");2139 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));
2135 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");2141 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
2136 fn_walk->data.attrs.gen_i += 1;2142 fn_walk->data.attrs.gen_i += 1;
2137 break;2143 break;
...@@ -2159,7 +2165,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2159,7 +2165,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2159 break;2165 break;
2160 }2166 }
2161 return true;2167 return true;
2162 } else if (abi_class == X64CABIClass_INTEGER && ty_size <= 8) {2168 } else if (abi_class == X64CABIClass_INTEGER) {
2163 switch (fn_walk->id) {2169 switch (fn_walk->id) {
2164 case FnWalkIdAttrs:2170 case FnWalkIdAttrs:
2165 fn_walk->data.attrs.gen_i += 1;2171 fn_walk->data.attrs.gen_i += 1;
test/stage1/c_abi/cfuncs.c+18
...@@ -52,6 +52,13 @@ struct SmallStructInts {...@@ -52,6 +52,13 @@ struct SmallStructInts {
52};52};
53void zig_small_struct_ints(struct SmallStructInts);53void 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
55void run_c_tests(void) {62void run_c_tests(void) {
56 zig_u8(0xff);63 zig_u8(0xff);
57 zig_u16(0xfffe);64 zig_u16(0xfffe);
...@@ -83,6 +90,11 @@ void run_c_tests(void) {...@@ -83,6 +90,11 @@ void run_c_tests(void) {
83 struct SmallStructInts s = {1, 2, 3, 4};90 struct SmallStructInts s = {1, 2, 3, 4};
84 zig_small_struct_ints(s);91 zig_small_struct_ints(s);
85 }92 }
93
94 {
95 struct SplitStructInts s = {1234, 100, 1337};
96 zig_split_struct_ints(s);
97 }
86}98}
8799
88void c_u8(uint8_t x) {100void c_u8(uint8_t x) {
...@@ -167,3 +179,9 @@ void c_small_struct_ints(struct SmallStructInts x) {...@@ -167,3 +179,9 @@ void c_small_struct_ints(struct SmallStructInts x) {
167 assert_or_panic(x.c == 3);179 assert_or_panic(x.c == 3);
168 assert_or_panic(x.d == 4);180 assert_or_panic(x.d == 4);
169}181}
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 {...@@ -181,3 +181,25 @@ export fn zig_small_struct_ints(x: SmallStructInts) void {
181 assertOrPanic(x.c == 3);181 assertOrPanic(x.c == 3);
182 assertOrPanic(x.d == 4);182 assertOrPanic(x.d == 4);
183}183}
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}