diff options
| author | gingerBill <bill@gingerbill.org> | 2021-05-22 11:33:08 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-05-22 11:33:08 +0100 |
| commit | b8f8d4c3a12ea85285511112b33425923418556a (patch) | |
| tree | e1d2401731e8fbdcce43f0551a3338a674c92a19 /src/llvm_abi.cpp | |
| parent | 9e2eb717fe2a146ccd15e66a45d48d48f867e097 (diff) | |
Modify ABI for the Odin calling conventions on SysV slightly
Diffstat (limited to 'src/llvm_abi.cpp')
| -rw-r--r-- | src/llvm_abi.cpp | 44 |
1 files changed, 14 insertions, 30 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index aba85ae83..1347a1cdd 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -11,6 +11,8 @@ struct lbArgType { LLVMTypeRef pad_type; // Optional LLVMAttributeRef attribute; // Optional LLVMAttributeRef align_attribute; // Optional + i64 byval_alignment; + bool is_byval; }; @@ -18,14 +20,14 @@ i64 lb_sizeof(LLVMTypeRef type); i64 lb_alignof(LLVMTypeRef type); lbArgType lb_arg_type_direct(LLVMTypeRef type, LLVMTypeRef cast_type, LLVMTypeRef pad_type, LLVMAttributeRef attr) { - return lbArgType{lbArg_Direct, type, cast_type, pad_type, attr, nullptr}; + return lbArgType{lbArg_Direct, type, cast_type, pad_type, attr, nullptr, 0, false}; } lbArgType lb_arg_type_direct(LLVMTypeRef type) { return lb_arg_type_direct(type, nullptr, nullptr, nullptr); } lbArgType lb_arg_type_indirect(LLVMTypeRef type, LLVMAttributeRef attr) { - return lbArgType{lbArg_Indirect, type, nullptr, nullptr, attr, nullptr}; + return lbArgType{lbArg_Indirect, type, nullptr, nullptr, attr, nullptr, 0, false}; } lbArgType lb_arg_type_indirect_byval(LLVMContextRef c, LLVMTypeRef type) { @@ -34,11 +36,11 @@ lbArgType lb_arg_type_indirect_byval(LLVMContextRef c, LLVMTypeRef type) { LLVMAttributeRef byval_attr = lb_create_enum_attribute_with_type(c, "byval", type); LLVMAttributeRef align_attr = lb_create_enum_attribute(c, "align", alignment); - return lbArgType{lbArg_Indirect, type, nullptr, nullptr, byval_attr, align_attr}; + return lbArgType{lbArg_Indirect, type, nullptr, nullptr, byval_attr, align_attr, alignment, true}; } lbArgType lb_arg_type_ignore(LLVMTypeRef type) { - return lbArgType{lbArg_Ignore, type, nullptr, nullptr, nullptr, nullptr}; + return lbArgType{lbArg_Ignore, type, nullptr, nullptr, nullptr, nullptr, 0, false}; } struct lbFunctionType { @@ -458,11 +460,10 @@ namespace lbAbiAmd64SysV { Amd64TypeAttribute_StructRect, }; - Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count); lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined); void classify_with(LLVMTypeRef t, Array<RegClass> *cls, i64 ix, i64 off); void fixup(LLVMTypeRef t, Array<RegClass> *cls); - lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind); + lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention); Array<RegClass> classify(LLVMTypeRef t); LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_classes); @@ -473,11 +474,11 @@ namespace lbAbiAmd64SysV { ft->args = array_make<lbArgType>(heap_allocator(), arg_count); for (unsigned i = 0; i < arg_count; i++) { - ft->args[i] = amd64_type(c, arg_types[i], Amd64TypeAttribute_ByVal); + ft->args[i] = amd64_type(c, arg_types[i], Amd64TypeAttribute_ByVal, calling_convention); } if (return_is_defined) { - ft->ret = amd64_type(c, return_type, Amd64TypeAttribute_StructRect); + ft->ret = amd64_type(c, return_type, Amd64TypeAttribute_StructRect, calling_convention); } else { ft->ret = lb_arg_type_direct(LLVMVoidTypeInContext(c)); } @@ -514,7 +515,7 @@ namespace lbAbiAmd64SysV { return false; } - lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind) { + lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention) { if (is_register(type)) { LLVMAttributeRef attribute = nullptr; if (type == LLVMInt1TypeInContext(c)) { @@ -527,7 +528,10 @@ namespace lbAbiAmd64SysV { if (is_mem_cls(cls, attribute_kind)) { LLVMAttributeRef attribute = nullptr; if (attribute_kind == Amd64TypeAttribute_ByVal) { - return lb_arg_type_indirect_byval(c, type); + if (!is_calling_convention_odin(calling_convention)) { + return lb_arg_type_indirect_byval(c, type); + } + attribute = nullptr; } else if (attribute_kind == Amd64TypeAttribute_StructRect) { attribute = lb_create_enum_attribute_with_type(c, "sret", type); } @@ -817,26 +821,6 @@ namespace lbAbiAmd64SysV { } } - Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) { - auto args = array_make<lbArgType>(heap_allocator(), arg_count); - - for (unsigned i = 0; i < arg_count; i++) { - LLVMTypeRef t = arg_types[i]; - LLVMTypeKind kind = LLVMGetTypeKind(t); - if (kind == LLVMStructTypeKind) { - i64 sz = lb_sizeof(t); - if (sz == 0) { - args[i] = lb_arg_type_ignore(t); - } else { - args[i] = lb_arg_type_indirect_byval(c, t); - } - } else { - args[i] = non_struct(c, t); - } - } - return args; - } - lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) { if (!return_is_defined) { return lb_arg_type_direct(LLVMVoidTypeInContext(c)); |