implement partial C ABI support for aarch64
parent
32c89531b1
commit
f8bd1cd3b1
|
@ -74,6 +74,7 @@ enum UndefAllowed {
|
|||
enum X64CABIClass {
|
||||
X64CABIClass_Unknown,
|
||||
X64CABIClass_MEMORY,
|
||||
X64CABIClass_MEMORY_nobyval,
|
||||
X64CABIClass_INTEGER,
|
||||
X64CABIClass_SSE,
|
||||
};
|
||||
|
|
|
@ -919,14 +919,13 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
|
|||
if (type_is_c_abi_int(g, fn_type_id->return_type)) {
|
||||
return false;
|
||||
}
|
||||
if (g->zig_target->arch == ZigLLVM_x86) {
|
||||
if (g->zig_target->arch == ZigLLVM_x86 ||
|
||||
g->zig_target->arch == ZigLLVM_x86_64 ||
|
||||
target_is_arm(g->zig_target) ||
|
||||
target_is_riscv(g->zig_target))
|
||||
{
|
||||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
|
||||
return abi_class == X64CABIClass_MEMORY;
|
||||
} else if (g->zig_target->arch == ZigLLVM_x86_64) {
|
||||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
|
||||
return abi_class == X64CABIClass_MEMORY;
|
||||
} else if (target_is_arm(g->zig_target) || target_is_riscv(g->zig_target)) {
|
||||
return type_size(g, fn_type_id->return_type) > 16;
|
||||
return abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval;
|
||||
} else if (g->zig_target->arch == ZigLLVM_mipsel) {
|
||||
return false;
|
||||
}
|
||||
|
@ -7509,6 +7508,11 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
|
|||
|
||||
if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
|
||||
return type_windows_abi_x86_64_class(g, ty, ty_size);
|
||||
} else if (g->zig_target->arch == ZigLLVM_aarch64 ||
|
||||
g->zig_target->arch == ZigLLVM_aarch64_be)
|
||||
{
|
||||
X64CABIClass result = type_system_V_abi_x86_64_class(g, ty, ty_size);
|
||||
return (result == X64CABIClass_MEMORY) ? X64CABIClass_MEMORY_nobyval : result;
|
||||
} else {
|
||||
return type_system_V_abi_x86_64_class(g, ty, ty_size);
|
||||
}
|
||||
|
|
|
@ -1847,6 +1847,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
// Arrays are just pointers
|
||||
if (ty->id == ZigTypeIdArray) {
|
||||
assert(handle_is_ptr(ty));
|
||||
|
@ -1883,15 +1884,27 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
return true;
|
||||
}
|
||||
|
||||
if (g->zig_target->arch == ZigLLVM_x86_64) {
|
||||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty);
|
||||
size_t ty_size = type_size(g, ty);
|
||||
if (abi_class == X64CABIClass_MEMORY) {
|
||||
if (abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval) {
|
||||
assert(handle_is_ptr(ty));
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs:
|
||||
if (abi_class != X64CABIClass_MEMORY_nobyval) {
|
||||
ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty));
|
||||
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
|
||||
} else if (g->zig_target->arch == ZigLLVM_aarch64 ||
|
||||
g->zig_target->arch == ZigLLVM_aarch64_be)
|
||||
{
|
||||
// no attrs needed
|
||||
} else {
|
||||
if (source_node != nullptr) {
|
||||
give_up_with_c_abi_error(g, source_node);
|
||||
}
|
||||
// otherwise allow codegen code to report a compile error
|
||||
return false;
|
||||
}
|
||||
|
||||
// Byvalue parameters must not have address 0
|
||||
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
|
||||
fn_walk->data.attrs.gen_i += 1;
|
||||
|
|
Loading…
Reference in New Issue