aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-02-16 16:04:20 +0000
committergingerBill <bill@gingerbill.org>2022-02-16 16:04:20 +0000
commit8e8a075a2232038eb3a24e2b7b0a0b183d13b89d (patch)
tree281af208f9cdc367ba793991c3242db94a1eb851 /src
parent65dedbb1caaa785a444d32a7a15adaf6c396b07f (diff)
parentdb6bd9b358f17c0259ff5fe6411ce93407613338 (diff)
Merge branch 'master' into directx-packages
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_debug.cpp28
-rw-r--r--src/llvm_backend_opt.cpp2
-rw-r--r--src/llvm_backend_proc.cpp18
-rw-r--r--src/parser.cpp6
-rw-r--r--src/parser.hpp18
9 files changed, 82 insertions, 54 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 7e0ad2bd9..6c49b9b8b 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -1928,6 +1928,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_debug.cpp b/src/llvm_backend_debug.cpp
index f60096aad..ff1c5c7dc 100644
--- a/src/llvm_backend_debug.cpp
+++ b/src/llvm_backend_debug.cpp
@@ -958,15 +958,15 @@ void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T
);
LLVMValueRef storage = ptr;
- LLVMValueRef instr = ptr;
+ LLVMBasicBlockRef block = p->decl_block->block;
LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
lb_set_llvm_metadata(m, ptr, llvm_expr);
- LLVMDIBuilderInsertDeclareBefore(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, instr);
+ LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block);
}
-void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number) {
+void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) {
if (p->debug_info == nullptr) {
return;
}
@@ -1020,19 +1020,14 @@ void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T
);
LLVMValueRef storage = ptr;
- LLVMValueRef instr = ptr;
- LLVMBasicBlockRef block = p->decl_block->block;
LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
lb_set_llvm_metadata(m, ptr, llvm_expr);
- if (LLVMIsAAllocaInst(instr)) {
- LLVMDIBuilderInsertDeclareBefore(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, instr);
- } else {
- // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block
- // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an
- // instruction "before" it.
- LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block);
- }
+
+ // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block
+ // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an
+ // instruction "before" it.
+ LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block);
}
@@ -1055,5 +1050,10 @@ void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
token.string = str_lit("context");
token.pos = pos;
- lb_add_debug_local_variable(p, ctx.addr.value, t_context, token);
+ LLVMValueRef ptr = ctx.addr.value;
+ while (LLVMIsABitCastInst(ptr)) {
+ ptr = LLVMGetOperand(ptr, 0);
+ }
+
+ lb_add_debug_local_variable(p, ptr, t_context, token);
}
diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp
index 8f1c7ad59..d36bdec0b 100644
--- a/src/llvm_backend_opt.cpp
+++ b/src/llvm_backend_opt.cpp
@@ -56,7 +56,7 @@ LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data
#endif
void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimization_level) {
- if (optimization_level == 0 && build_context.ODIN_DEBUG) {
+ if (false && optimization_level == 0 && build_context.ODIN_DEBUG) {
LLVMAddMergedLoadStoreMotionPass(fpm);
} else {
LLVMAddPromoteMemoryToRegisterPass(fpm);
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 2a0380605..261e2819c 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -480,9 +480,8 @@ void lb_begin_procedure_body(lbProcedure *p) {
} else if (arg_type->kind == lbArg_Direct) {
if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
LLVMTypeRef param_type = lb_type(p->module, e->type);
- LLVMValueRef value = LLVMGetParam(p->value, param_offset+param_index);
-
- value = OdinLLVMBuildTransmute(p, value, param_type);
+ LLVMValueRef original_value = LLVMGetParam(p->value, param_offset+param_index);
+ LLVMValueRef value = OdinLLVMBuildTransmute(p, original_value, param_type);
lbValue param = {};
param.value = value;
@@ -491,7 +490,16 @@ void lb_begin_procedure_body(lbProcedure *p) {
lbValue ptr = lb_address_from_load_or_generate_local(p, param);
GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
lb_add_entity(p->module, e, ptr);
- lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1);
+
+ lbBlock *block = p->decl_block;
+ if (original_value != value) {
+ block = p->curr_block;
+ }
+ LLVMValueRef debug_storage_value = value;
+ if (original_value != value && LLVMIsALoadInst(value)) {
+ debug_storage_value = LLVMGetOperand(value, 0);
+ }
+ lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block);
}
} else if (arg_type->kind == lbArg_Indirect) {
if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
@@ -499,7 +507,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
ptr.value = LLVMGetParam(p->value, param_offset+param_index);
ptr.type = alloc_type_pointer(e->type);
lb_add_entity(p->module, e, ptr);
- lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1);
+ lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block);
}
}
}
diff --git a/src/parser.cpp b/src/parser.cpp
index b55d745f1..7309d9769 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 fb84210b3..83c755553 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;
}