mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
C ABI: support medium size structs & unions for x86_64 params
See #1481
This commit is contained in:
parent
85534a26c6
commit
9017efee22
@ -354,8 +354,12 @@ static void addLLVMFnAttrInt(LLVMValueRef fn_val, const char *attr_name, uint64_
|
||||
return addLLVMAttrInt(fn_val, -1, attr_name, attr_val);
|
||||
}
|
||||
|
||||
static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) {
|
||||
return addLLVMAttr(arg_val, param_index + 1, attr_name);
|
||||
static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char *attr_name) {
|
||||
return addLLVMAttr(fn_val, param_index + 1, attr_name);
|
||||
}
|
||||
|
||||
static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) {
|
||||
return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val);
|
||||
}
|
||||
|
||||
static 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_
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs:
|
||||
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
|
||||
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
|
||||
fn_walk->data.attrs.gen_i += 1;
|
||||
break;
|
||||
case FnWalkIdCall:
|
||||
@ -2132,6 +2137,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs:
|
||||
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");
|
||||
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
|
||||
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
|
||||
fn_walk->data.attrs.gen_i += 1;
|
||||
break;
|
||||
@ -2159,7 +2165,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} else if (abi_class == X64CABIClass_INTEGER && ty_size <= 8) {
|
||||
} else if (abi_class == X64CABIClass_INTEGER) {
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs:
|
||||
fn_walk->data.attrs.gen_i += 1;
|
||||
|
||||
@ -52,6 +52,13 @@ struct SmallStructInts {
|
||||
};
|
||||
void zig_small_struct_ints(struct SmallStructInts);
|
||||
|
||||
struct SplitStructInts {
|
||||
uint64_t a;
|
||||
uint8_t b;
|
||||
uint32_t c;
|
||||
};
|
||||
void zig_split_struct_ints(struct SplitStructInts);
|
||||
|
||||
void run_c_tests(void) {
|
||||
zig_u8(0xff);
|
||||
zig_u16(0xfffe);
|
||||
@ -83,6 +90,11 @@ void run_c_tests(void) {
|
||||
struct SmallStructInts s = {1, 2, 3, 4};
|
||||
zig_small_struct_ints(s);
|
||||
}
|
||||
|
||||
{
|
||||
struct SplitStructInts s = {1234, 100, 1337};
|
||||
zig_split_struct_ints(s);
|
||||
}
|
||||
}
|
||||
|
||||
void c_u8(uint8_t x) {
|
||||
@ -167,3 +179,9 @@ void c_small_struct_ints(struct SmallStructInts x) {
|
||||
assert_or_panic(x.c == 3);
|
||||
assert_or_panic(x.d == 4);
|
||||
}
|
||||
|
||||
void c_split_struct_ints(struct SplitStructInts x) {
|
||||
assert_or_panic(x.a == 1234);
|
||||
assert_or_panic(x.b == 100);
|
||||
assert_or_panic(x.c == 1337);
|
||||
}
|
||||
|
||||
@ -181,3 +181,25 @@ export fn zig_small_struct_ints(x: SmallStructInts) void {
|
||||
assertOrPanic(x.c == 3);
|
||||
assertOrPanic(x.d == 4);
|
||||
}
|
||||
|
||||
const SplitStructInt = extern struct {
|
||||
a: u64,
|
||||
b: u8,
|
||||
c: u32,
|
||||
};
|
||||
extern fn c_split_struct_ints(SplitStructInt) void;
|
||||
|
||||
test "C ABI split struct of ints" {
|
||||
var s = SplitStructInt{
|
||||
.a = 1234,
|
||||
.b = 100,
|
||||
.c = 1337,
|
||||
};
|
||||
c_split_struct_ints(s);
|
||||
}
|
||||
|
||||
export fn zig_split_struct_ints(x: SplitStructInt) void {
|
||||
assertOrPanic(x.a == 1234);
|
||||
assertOrPanic(x.b == 100);
|
||||
assertOrPanic(x.c == 1337);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user