mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Vararg abi fix. Version bumped to 0.2.14
This commit is contained in:
committed by
Christoffer Lerno
parent
2a7d46844a
commit
28a8e17690
@@ -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/**"]
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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(®s, params[i], false, is_vector_call, is_reg_call);
|
||||
}
|
||||
prototype->abi_args = args;
|
||||
}
|
||||
prototype->abi_args = win64_create_params(prototype->params, ®s, is_vector_call, is_reg_call);
|
||||
prototype->abi_varargs = win64_create_params(prototype->varargs, ®s, is_vector_call, is_reg_call);
|
||||
}
|
||||
@@ -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, ®s, params[i]);
|
||||
}
|
||||
prototype->abi_args = args;
|
||||
}
|
||||
}
|
||||
prototype->abi_args = x86_create_params(prototype->call_abi, prototype->params, ®s);
|
||||
prototype->abi_varargs = x86_create_params(prototype->call_abi, prototype->params, ®s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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(©);
|
||||
prototype = ©
|
||||
LLVMTypeRef *params_type = NULL;
|
||||
llvm_update_prototype_abi(c, prototype, ¶ms_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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ¶ms);
|
||||
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], ¶ms);
|
||||
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], ¶ms);
|
||||
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, ¶ms);
|
||||
return LLVMFunctionType(ret, params, vec_size(params), prototype->variadic == VARIADIC_RAW);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.2.13"
|
||||
#define COMPILER_VERSION "0.2.14"
|
||||
Reference in New Issue
Block a user