aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_abi.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-05-22 11:33:08 +0100
committergingerBill <bill@gingerbill.org>2021-05-22 11:33:08 +0100
commitb8f8d4c3a12ea85285511112b33425923418556a (patch)
treee1d2401731e8fbdcce43f0551a3338a674c92a19 /src/llvm_abi.cpp
parent9e2eb717fe2a146ccd15e66a45d48d48f867e097 (diff)
Modify ABI for the Odin calling conventions on SysV slightly
Diffstat (limited to 'src/llvm_abi.cpp')
-rw-r--r--src/llvm_abi.cpp44
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 &reg_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));