aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_proc.cpp
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2022-03-12 10:48:31 +0000
committergingerBill <gingerBill@users.noreply.github.com>2022-03-12 10:48:31 +0000
commitf907516cbd0078b69996929d02742d0c1a48c226 (patch)
treee36a3a428465848088d3dd638b34c024914f6a61 /src/llvm_backend_proc.cpp
parentc12c7d53701e1ba9d110a9c4bd61fc2cb19a8fd1 (diff)
#Fix 1615 Replace `llvm.readcyclecounter` with `cntvct_el0` on arm64
Diffstat (limited to 'src/llvm_backend_proc.cpp')
-rw-r--r--src/llvm_backend_proc.cpp21
1 files changed, 15 insertions, 6 deletions
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;
}