Vararg abi fix. Version bumped to 0.2.14

This commit is contained in:
Christoffer Lerno
2022-07-13 14:08:37 +02:00
committed by Christoffer Lerno
parent 2a7d46844a
commit 28a8e17690
12 changed files with 102 additions and 91 deletions

View File

@@ -1,14 +0,0 @@
[[executable]]
name = "hello_world"
version = "0.1.0"
authors = ["John Doe <john.doe@example.com>"]
langrev = "1"
warnings = ["no-unused"]
# sources compiled
sources = ["./**"]
# libraries to use
libs = []
# c compiler
cc = "cc"
# c sources
csources = ["./csource/**"]

View File

@@ -261,7 +261,7 @@ void init_default_build_target(BuildTarget *target, BuildOptions *options)
void init_build_target(BuildTarget *target, BuildOptions *options)
{
*target = (BuildTarget) { 0 };
// Locate the project.toml
// Locate the project.c3p
file_find_top_dir();
// Parse it
Project *project = project_load();

View File

@@ -94,7 +94,7 @@ void create_project(BuildOptions *build_options)
if (!dir_change(build_options->project_name)) goto ERROR;
if (!file_touch("LICENCE")) goto ERROR;
if (!file_touch("LICENSE")) goto ERROR;
if (!file_touch("README.md")) goto ERROR;
@@ -154,3 +154,4 @@ ERROR:
}
exit_compiler(EXIT_FAILURE);
}

View File

@@ -173,4 +173,15 @@ void c_abi_func_create_aarch64(FunctionPrototype *prototype)
}
prototype->abi_args = args;
}
Type **va_params = prototype->varargs;
unsigned va_param_count = vec_size(va_params);
if (va_param_count)
{
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * va_param_count);
for (unsigned i = 0; i < va_param_count; i++)
{
args[i] = aarch64_classify_argument_type(va_params[i]);
}
prototype->abi_varargs = args;
}
}

View File

@@ -251,7 +251,17 @@ static ABIArgInfo *riscv_classify_return(Type *return_type)
// classifyArgumentType.
return riscv_classify_argument_type(return_type, true, &arg_gpr_left, &arg_fpr_left);
}
ABIArgInfo **riscv_create_params(Type** params, bool is_fixed, unsigned *arg_gprs_left, unsigned *arg_fprs_left)
{
unsigned param_count = vec_size(params);
if (!param_count) return NULL;
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = riscv_classify_argument_type(type_lowering(params[i]), is_fixed, arg_gprs_left, arg_fprs_left);
}
return args;
}
void c_abi_func_create_riscv(FunctionPrototype *prototype)
{
// Registers
@@ -287,16 +297,6 @@ void c_abi_func_create_riscv(FunctionPrototype *prototype)
true, &arg_gprs_left, &arg_fprs_left);
}
Type **params = prototype->params;
unsigned param_count = vec_size(prototype->params);
if (param_count)
{
bool is_fixed = true;
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = riscv_classify_argument_type(type_lowering(params[i]), is_fixed, &arg_gprs_left, &arg_fprs_left);
}
prototype->abi_args = args;
}
prototype->abi_args = riscv_create_params(prototype->params, true, &arg_gprs_left, &arg_fprs_left);
prototype->abi_varargs = riscv_create_params(prototype->varargs, false, &arg_gprs_left, &arg_fprs_left);
}

View File

@@ -51,6 +51,18 @@ static ABIArgInfo *wasm_classify_return(Type *type)
return c_abi_classify_return_type_default(type);
}
ABIArgInfo **wasm_create_params(Type **params)
{
unsigned param_count = vec_size(params);
if (!param_count) return NULL;
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = wasm_classify_argument_type(type_lowering(params[i]));
}
return args;
}
void c_abi_func_create_wasm(FunctionPrototype *prototype)
{
prototype->ret_abi_info = wasm_classify_return(type_lowering(prototype->abi_ret_type));
@@ -59,15 +71,6 @@ void c_abi_func_create_wasm(FunctionPrototype *prototype)
prototype->ret_by_ref_abi_info = wasm_classify_argument_type(type_get_ptr(prototype->ret_by_ref_type));
}
Type **params = prototype->params;
unsigned param_count = vec_size(prototype->params);
if (param_count)
{
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = wasm_classify_argument_type(type_lowering(params[i]));
}
prototype->abi_args = args;
}
prototype->abi_args = wasm_create_params(prototype->params);
prototype->abi_varargs = wasm_create_params(prototype->varargs);
}

View File

@@ -137,6 +137,18 @@ void win64_vector_call_args(Regs *regs, FunctionPrototype *prototype, bool is_ve
}
}
ABIArgInfo **win64_create_params(Type **params, Regs *regs, bool is_vector_call, bool is_reg_call)
{
unsigned param_count = vec_size(params);
if (!param_count) return NULL;
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = win64_classify(regs, params[i], false, is_vector_call, is_reg_call);
}
return args;
}
void c_abi_func_create_win64(FunctionPrototype *prototype)
{
// allow calling sysv?
@@ -187,15 +199,6 @@ void c_abi_func_create_win64(FunctionPrototype *prototype)
return;
}
Type **params = prototype->params;
unsigned param_count = vec_size(prototype->params);
if (param_count)
{
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = win64_classify(&regs, params[i], false, is_vector_call, is_reg_call);
}
prototype->abi_args = args;
}
prototype->abi_args = win64_create_params(prototype->params, &regs, is_vector_call, is_reg_call);
prototype->abi_varargs = win64_create_params(prototype->varargs, &regs, is_vector_call, is_reg_call);
}

View File

@@ -8,6 +8,8 @@
static bool x86_try_use_free_regs(Regs *regs, Type *type);
ABIArgInfo **x86_create_params(CallABI abi, Type **p_type, Regs *ptr);
static inline bool type_is_simd_vector(Type *type)
{
type = type->canonical;
@@ -606,6 +608,18 @@ static ABIArgInfo *x86_classify_argument(CallABI call, Regs *regs, Type *type)
UNREACHABLE
}
ABIArgInfo **x86_create_params(CallABI abi, Type **params, Regs *regs)
{
unsigned param_count = vec_size(params);
if (!param_count) return NULL;
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = x86_classify_argument(abi, regs, params[i]);
}
return args;
}
void c_abi_func_create_x86(FunctionPrototype *prototype)
{
// 1. Calculate the registers we have available
@@ -668,19 +682,8 @@ void c_abi_func_create_x86(FunctionPrototype *prototype)
{
FATAL_ERROR("X86 vector call not supported");
}
else
{
Type **params = prototype->params;
unsigned param_count = vec_size(prototype->params);
if (param_count)
{
ABIArgInfo **args = MALLOC(sizeof(ABIArgInfo) * param_count);
for (unsigned i = 0; i < param_count; i++)
{
args[i] = x86_classify_argument(prototype->call_abi, &regs, params[i]);
}
prototype->abi_args = args;
}
}
prototype->abi_args = x86_create_params(prototype->call_abi, prototype->params, &regs);
prototype->abi_varargs = x86_create_params(prototype->call_abi, prototype->params, &regs);
}

View File

@@ -4436,7 +4436,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
llvm_emit_intrinsic_expr(c, llvm_get_intrinsic(func), result_value, expr);
}
void llvm_add_abi_call_attributes(GenContext *c, LLVMValueRef call_value, int start_index, int count, Type **types, ABIArgInfo **infos)
void llvm_add_abi_call_attributes(GenContext *c, LLVMValueRef call_value, int count, ABIArgInfo **infos)
{
for (unsigned i = 0; i < count; i++)
{
@@ -4449,10 +4449,10 @@ void llvm_add_abi_call_attributes(GenContext *c, LLVMValueRef call_value, int st
llvm_attribute_add_call_type(c,
call_value,
attribute_id.byval,
(int)i + start_index,
(int)info->param_index_start + 1,
llvm_get_type(c, info->indirect.type));
}
llvm_attribute_add_call(c, call_value, attribute_id.align, (int)i + start_index, info->indirect.alignment);
llvm_attribute_add_call(c, call_value, attribute_id.align, (int)info->param_index_start + 1, info->indirect.alignment);
break;
default:
break;
@@ -4534,13 +4534,15 @@ void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
copy.varargs = NULL;
for (unsigned i = non_variadic_params; i < arguments; i++)
{
vec_add(copy.varargs, args[i]->type);
vec_add(copy.varargs, type_flatten(args[i]->type));
}
copy.ret_abi_info = NULL;
copy.ret_by_ref_abi_info = NULL;
copy.abi_args = NULL;
c_abi_func_create(&copy);
prototype = &copy;
LLVMTypeRef *params_type = NULL;
llvm_update_prototype_abi(c, prototype, &params_type);
}
}
ABIArgInfo *ret_info = prototype->ret_abi_info;
@@ -4714,14 +4716,12 @@ void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
}
assert(!prototype->ret_by_ref || prototype->ret_by_ref_abi_info->kind != ABI_ARG_INDIRECT);
llvm_add_abi_call_attributes(c, call_value, prototype->ret_by_ref ? 2 : 1, non_variadic_params, params, abi_args);
llvm_add_abi_call_attributes(c, call_value, non_variadic_params, abi_args);
if (prototype->abi_varargs)
{
llvm_add_abi_call_attributes(c,
call_value,
1 + non_variadic_params,
vec_size(prototype->varargs),
prototype->varargs,
prototype->abi_varargs);
}

View File

@@ -299,6 +299,7 @@ void llvm_emit_comparison(GenContext *c, BEValue *be_value, BEValue *lhs, BEValu
void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_len);
// -- type ---
LLVMTypeRef llvm_func_type(GenContext *context, FunctionPrototype *prototype);
LLVMTypeRef llvm_update_prototype_abi(GenContext *context, FunctionPrototype *prototype, LLVMTypeRef **params);
// -- instr ---
void llvm_emit_cond_br(GenContext *context, BEValue *value, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);

View File

@@ -222,12 +222,9 @@ static inline void add_func_type_param(GenContext *context, Type *param_type, AB
arg_info->param_index_end = (MemberIndex)vec_size(*params);
}
LLVMTypeRef llvm_func_type(GenContext *context, FunctionPrototype *prototype)
LLVMTypeRef llvm_update_prototype_abi(GenContext *context, FunctionPrototype *prototype, LLVMTypeRef **params)
{
LLVMTypeRef *params = NULL;
LLVMTypeRef return_type = NULL;
LLVMTypeRef retval = NULL;
Type *call_return_type = prototype->abi_ret_type;
ABIArgInfo *ret_arg_info = prototype->ret_abi_info;
@@ -239,62 +236,68 @@ LLVMTypeRef llvm_func_type(GenContext *context, FunctionPrototype *prototype)
case ABI_ARG_EXPAND:
UNREACHABLE;
case ABI_ARG_INDIRECT:
vec_add(params, llvm_get_ptr_type(context, call_return_type));
return_type = llvm_get_type(context, type_void);
vec_add(*params, llvm_get_ptr_type(context, call_return_type));
retval = llvm_get_type(context, type_void);
break;
case ABI_ARG_EXPAND_COERCE:
{
LLVMTypeRef lo = llvm_abi_type(context, ret_arg_info->direct_pair.lo);
if (!abi_type_is_valid(ret_arg_info->direct_pair.hi))
{
return_type = lo;
retval = lo;
break;
}
LLVMTypeRef hi = llvm_abi_type(context, ret_arg_info->direct_pair.hi);
return_type = llvm_get_twostruct(context, lo, hi);
retval = llvm_get_twostruct(context, lo, hi);
break;
}
case ABI_ARG_IGNORE:
return_type = llvm_get_type(context, type_void);
retval = llvm_get_type(context, type_void);
break;
case ABI_ARG_DIRECT_PAIR:
{
LLVMTypeRef lo = llvm_abi_type(context, ret_arg_info->direct_pair.lo);
LLVMTypeRef hi = llvm_abi_type(context, ret_arg_info->direct_pair.hi);
return_type = llvm_get_twostruct(context, lo, hi);
retval = llvm_get_twostruct(context, lo, hi);
break;
}
case ABI_ARG_DIRECT:
return_type = llvm_get_type(context, call_return_type);
retval = llvm_get_type(context, call_return_type);
break;
case ABI_ARG_DIRECT_SPLIT_STRUCT:
UNREACHABLE
case ABI_ARG_DIRECT_COERCE_INT:
return_type = LLVMIntTypeInContext(context->context, type_size(call_return_type) * 8);
retval = LLVMIntTypeInContext(context->context, type_size(call_return_type) * 8);
break;
case ABI_ARG_DIRECT_COERCE:
return_type = llvm_get_type(context, ret_arg_info->direct_coerce_type);
retval = llvm_get_type(context, ret_arg_info->direct_coerce_type);
break;
}
// If it's failable and it's not void (meaning ret_abi_info will be NULL)
if (prototype->ret_by_ref)
{
add_func_type_param(context, type_get_ptr(type_lowering(prototype->ret_by_ref_type)), prototype->ret_by_ref_abi_info, &params);
add_func_type_param(context, type_get_ptr(type_lowering(prototype->ret_by_ref_type)), prototype->ret_by_ref_abi_info, params);
}
// Add in all of the required arguments.
VECEACH(prototype->params, i)
{
add_func_type_param(context, prototype->params[i], prototype->abi_args[i], &params);
add_func_type_param(context, prototype->params[i], prototype->abi_args[i], params);
}
VECEACH(prototype->varargs, i)
{
add_func_type_param(context, prototype->varargs[i], prototype->abi_varargs[i], &params);
add_func_type_param(context, prototype->varargs[i], prototype->abi_varargs[i], params);
}
return retval;
}
return LLVMFunctionType(return_type, params, vec_size(params), prototype->variadic == VARIADIC_RAW);
LLVMTypeRef llvm_func_type(GenContext *context, FunctionPrototype *prototype)
{
LLVMTypeRef *params = NULL;
LLVMTypeRef ret = llvm_update_prototype_abi(context, prototype, &params);
return LLVMFunctionType(ret, params, vec_size(params), prototype->variadic == VARIADIC_RAW);
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.2.13"
#define COMPILER_VERSION "0.2.14"