aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-02-16 16:03:49 +0000
committergingerBill <bill@gingerbill.org>2022-02-16 16:03:49 +0000
commitdb6bd9b358f17c0259ff5fe6411ce93407613338 (patch)
tree54b7e06a4bee7fcc1813616a5bcb9df11da6d6a5 /src
parent42ad54c28ee013618c7ee0039bbe1ce5dd1f0ba6 (diff)
Allow sysv and win64 calling conventions to be used on any platform on amd64
Diffstat (limited to 'src')
-rw-r--r--src/check_type.cpp19
-rw-r--r--src/docs_writer.cpp35
-rw-r--r--src/llvm_abi.cpp6
-rw-r--r--src/llvm_backend.hpp4
-rw-r--r--src/llvm_backend_proc.cpp2
-rw-r--r--src/parser.cpp6
-rw-r--r--src/parser.hpp18
7 files changed, 55 insertions, 35 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 32340070e..a11f5234b 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -1910,6 +1910,25 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
c->scope->flags &= ~ScopeFlag_ContextDefined;
}
+ TargetArchKind arch = build_context.metrics.arch;
+ switch (cc) {
+ case ProcCC_StdCall:
+ case ProcCC_FastCall:
+ if (arch != TargetArch_i386 || arch != TargetArch_amd64) {
+ error(proc_type_node, "Invalid procedure calling convention \"%s\" for target architecture, expected either i386 or amd64, got %.*s",
+ proc_calling_convention_strings[cc], LIT(target_arch_names[arch]));
+ }
+ break;
+ case ProcCC_Win64:
+ case ProcCC_SysV:
+ if (arch != TargetArch_amd64) {
+ error(proc_type_node, "Invalid procedure calling convention \"%s\" for target architecture, expected amd64, got %.*s",
+ proc_calling_convention_strings[cc], LIT(target_arch_names[arch]));
+ }
+ break;
+ }
+
+
bool variadic = false;
isize variadic_index = -1;
bool success = true;
diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp
index 0474ce8ff..2c5186c39 100644
--- a/src/docs_writer.cpp
+++ b/src/docs_writer.cpp
@@ -683,40 +683,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
types[1] = odin_doc_type(w, type->Proc.results);
doc_type.types = odin_write_slice(w, types, gb_count_of(types));
- String calling_convention = {};
- switch (type->Proc.calling_convention) {
- case ProcCC_Invalid:
- // no need
- break;
- case ProcCC_Odin:
- if (default_calling_convention() != ProcCC_Odin) {
- calling_convention = str_lit("odin");
- }
- break;
- case ProcCC_Contextless:
- if (default_calling_convention() != ProcCC_Contextless) {
- calling_convention = str_lit("contextless");
- }
- break;
- case ProcCC_CDecl:
- calling_convention = str_lit("cdecl");
- break;
- case ProcCC_StdCall:
- calling_convention = str_lit("stdcall");
- break;
- case ProcCC_FastCall:
- calling_convention = str_lit("fastcall");
- break;
- case ProcCC_None:
- calling_convention = str_lit("none");
- break;
- case ProcCC_Naked:
- calling_convention = str_lit("naked");
- break;
- case ProcCC_InlineAsm:
- calling_convention = str_lit("inline-assembly");
- break;
- }
+ String calling_convention = make_string_c(proc_calling_convention_strings[type->Proc.calling_convention]);
doc_type.calling_convention = odin_doc_write_string(w, calling_convention);
}
break;
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index 310df6639..0244b73d6 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -1184,6 +1184,12 @@ LB_ABI_INFO(lb_get_abi_info) {
ft->calling_convention = calling_convention;
return ft;
}
+ case ProcCC_Win64:
+ GB_ASSERT(build_context.metrics.arch == TargetArch_amd64);
+ return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
+ case ProcCC_SysV:
+ GB_ASSERT(build_context.metrics.arch == TargetArch_amd64);
+ return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention);
}
switch (build_context.metrics.arch) {
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 087cda22a..f2bcfaff6 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -548,6 +548,10 @@ lbCallingConventionKind const lb_calling_convention_map[ProcCC_MAX] = {
lbCallingConvention_C, // ProcCC_None,
lbCallingConvention_C, // ProcCC_Naked,
lbCallingConvention_C, // ProcCC_InlineAsm,
+
+ lbCallingConvention_Win64, // ProcCC_Win64,
+ lbCallingConvention_X86_64_SysV, // ProcCC_SysV,
+
};
enum : LLVMDWARFTypeEncoding {
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index ccb16ebe0..261e2819c 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -497,7 +497,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
}
LLVMValueRef debug_storage_value = value;
if (original_value != value && LLVMIsALoadInst(value)) {
- debug_storage_value = ptr.value;
+ debug_storage_value = LLVMGetOperand(value, 0);
}
lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block);
}
diff --git a/src/parser.cpp b/src/parser.cpp
index 0914c77ca..bd0e55b7f 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -3412,12 +3412,18 @@ ProcCallingConvention string_to_calling_convention(String s) {
if (s == "fast") return ProcCC_FastCall;
if (s == "none") return ProcCC_None;
if (s == "naked") return ProcCC_Naked;
+
+ if (s == "win64") return ProcCC_Win64;
+ if (s == "sysv") return ProcCC_SysV;
+
if (s == "system") {
if (build_context.metrics.os == TargetOs_windows) {
return ProcCC_StdCall;
}
return ProcCC_CDecl;
}
+
+
return ProcCC_Invalid;
}
diff --git a/src/parser.hpp b/src/parser.hpp
index ff0df0382..9e93f4b26 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -249,12 +249,30 @@ enum ProcCallingConvention : i32 {
ProcCC_InlineAsm = 8,
+ ProcCC_Win64 = 9,
+ ProcCC_SysV = 10,
+
+
ProcCC_MAX,
ProcCC_ForeignBlockDefault = -1,
};
+char const *proc_calling_convention_strings[ProcCC_MAX] = {
+ "",
+ "odin",
+ "contextless",
+ "cdecl",
+ "stdcall",
+ "fastcall",
+ "none",
+ "naked",
+ "inlineasm",
+ "win64",
+ "sysv",
+};
+
ProcCallingConvention default_calling_convention(void) {
return ProcCC_Odin;
}