From 493bc653b5762514dac8c8941d6564ccf5bb8528 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 23 Feb 2022 11:23:27 +0000 Subject: Add `@(no_red_zone)` for procedures --- src/llvm_backend_proc.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 7ead77c2c..209f2f67b 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -135,6 +135,10 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lb_add_attribute_to_proc(m, p->value, "naked"); } + if (entity->Procedure.no_red_zone) { + lb_add_attribute_to_proc(m, p->value, "noredzone"); + } + switch (p->inlining) { case ProcInlining_inline: lb_add_attribute_to_proc(m, p->value, "alwaysinline"); -- cgit v1.2.3 From 196bd735d4c30964182fdf1f374f767ccb0912fa Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 23 Feb 2022 11:29:36 +0000 Subject: Replace local `@(no_red_zone)` with global `-disable-red-zone` --- src/build_settings.cpp | 8 ++++++++ src/check_decl.cpp | 8 -------- src/checker.cpp | 7 ------- src/checker.hpp | 1 - src/entity.cpp | 1 - src/llvm_backend_proc.cpp | 2 +- src/main.cpp | 8 ++++++++ 7 files changed, 17 insertions(+), 18 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 790f7f1bc..62f43fad3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -278,6 +278,7 @@ struct BuildContext { bool copy_file_contents; RelocMode reloc_mode; + bool disable_red_zone; u32 cmd_doc_flags; @@ -1002,6 +1003,13 @@ void init_build_context(TargetMetrics *cross_target) { bc->threaded_checker = true; #endif + if (bc->disable_red_zone) { + if (!(bc->metrics.os == TargetOs_freestanding && !is_arch_wasm())) { + gb_printf_err("-disable-red-zone is not support for this target"); + gb_exit(1); + } + } + // NOTE(zangent): The linker flags to set the build architecture are different // across OSs. It doesn't make sense to allocate extra data on the heap diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 6f8caff98..45d741532 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -826,14 +826,6 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; - if (ac.no_red_zone) { - if (!is_arch_wasm()) { - e->Procedure.no_red_zone = true; - } else { - error(e->token, "@(no_red_zone) is not supported on this target architecture"); - } - } - if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { if (ac.objc_name.len == 0 && ac.objc_is_class_method) { error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); diff --git a/src/checker.cpp b/src/checker.cpp index 89e60c258..fe1d362fa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3128,13 +3128,6 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } } return true; - } else if (name == "no_red_zone") { - if (value != nullptr) { - error(elem, "Expected no value for '%.*s'", LIT(name)); - } else { - ac->no_red_zone = true; - } - return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 548439774..552e6aca7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -117,7 +117,6 @@ struct AttributeContext { bool test : 1; bool init : 1; bool set_cold : 1; - bool no_red_zone : 1; u32 optimization_mode; // ProcedureOptimizationMode String objc_class; diff --git a/src/entity.cpp b/src/entity.cpp index 84ddd5c6b..f5720293f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -226,7 +226,6 @@ struct Entity { bool is_foreign; bool is_export; bool generated_from_polymorphic; - bool no_red_zone; ProcedureOptimizationMode optimization_mode; } Procedure; struct { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 209f2f67b..053ee2fb2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -135,7 +135,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lb_add_attribute_to_proc(m, p->value, "naked"); } - if (entity->Procedure.no_red_zone) { + if (!entity->Procedure.is_foreign && build_context.disable_red_zone) { lb_add_attribute_to_proc(m, p->value, "noredzone"); } diff --git a/src/main.cpp b/src/main.cpp index cfc7decb1..1e7b78da4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -626,6 +626,7 @@ enum BuildFlagKind { BuildFlag_Microarch, BuildFlag_RelocMode, + BuildFlag_DisableRedZone, BuildFlag_TestName, @@ -782,6 +783,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test); @@ -1365,6 +1367,9 @@ bool parse_build_flags(Array args) { break; } + case BuildFlag_DisableRedZone: + build_context.disable_red_zone = true; + break; case BuildFlag_TestName: { GB_ASSERT(value.kind == ExactValue_String); { @@ -2096,6 +2101,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(3, "pic"); print_usage_line(3, "dynamic-no-pic"); print_usage_line(0, ""); + + print_usage_line(1, "-disable-red-zone"); + print_usage_line(2, "Disable red zone on a supported freestanding target"); } if (check) { -- cgit v1.2.3 From f907516cbd0078b69996929d02742d0c1a48c226 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 12 Mar 2022 10:48:31 +0000 Subject: #Fix 1615 Replace `llvm.readcyclecounter` with `cntvct_el0` on arm64 --- src/llvm_backend_proc.cpp | 21 +++++++++++++++------ src/llvm_backend_utility.cpp | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index eb6c89b85..1698c211b 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1402,14 +1402,23 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_read_cycle_counter: { - char const *name = "llvm.readcyclecounter"; - unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); - GB_ASSERT_MSG(id != 0, "Unable to find %s", name); - LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0); - lbValue res = {}; - res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, ""); res.type = tv.type; + + if (build_context.metrics.arch == TargetArch_arm64) { + LLVMTypeRef func_type = LLVMFunctionType(LLVMInt64TypeInContext(p->module->ctx), nullptr, 0, false); + bool has_side_effects = false; + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("mrs x9, cntvct_el0"), str_lit("=r"), has_side_effects); + GB_ASSERT(the_asm != nullptr); + res.value = LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); + } else { + char const *name = "llvm.readcyclecounter"; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", name); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0); + + res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, ""); + } return res; } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 431cfea9b..15075380a 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1779,7 +1779,7 @@ LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, Strin return LLVMGetInlineAsm(func_type, cast(char *)str.text, cast(size_t)str.len, cast(char *)clobbers.text, cast(size_t)clobbers.len, - /*HasSideEffects*/true, /*IsAlignStack*/false, + has_side_effects, is_align_stack, dialect #if LLVM_VERSION_MAJOR >= 13 , /*CanThrow*/false -- cgit v1.2.3