浏览代码

use the correct frequency for the arm tsc timer

Colin Davidson 1 月之前
父节点
当前提交
1848e0df05
共有 5 个文件被更改,包括 22 次插入1 次删除
  1. 3 0
      base/intrinsics/intrinsics.odin
  2. 2 1
      core/time/tsc_darwin.odin
  3. 1 0
      src/check_builtin.cpp
  4. 3 0
      src/checker_builtin_procs.hpp
  5. 13 0
      src/llvm_backend_proc.cpp

+ 3 - 0
base/intrinsics/intrinsics.odin

@@ -361,6 +361,9 @@ wasm_memory_atomic_notify32 :: proc(ptr: ^u32, waiters: u32) -> (waiters_woken_u
 x86_cpuid  :: proc(ax, cx: u32) -> (eax, ebx, ecx, edx: u32) ---
 x86_xgetbv :: proc(cx: u32) -> (eax, edx: u32) ---
 
+// Arm64 targets
+arm64_read_cycle_counter_frequency :: proc() -> i64 ---
+
 
 // Darwin targets only
 objc_object   :: struct{}

+ 2 - 1
core/time/tsc_darwin.odin

@@ -1,13 +1,14 @@
 #+private
 package time
 
+import "base:intrinsics"
 import "core:sys/unix"
 
 _get_tsc_frequency :: proc "contextless" () -> (freq: u64, ok: bool) {
 	if ODIN_ARCH == .amd64 {
 		unix.sysctlbyname("machdep.tsc.frequency", &freq) or_return
 	} else if ODIN_ARCH == .arm64 {
-		unix.sysctlbyname("hw.tbfrequency", &freq) or_return
+		freq = u64(intrinsics.arm64_read_cycle_counter_frequency())
 	} else {
 		return
 	}

+ 1 - 0
src/check_builtin.cpp

@@ -4713,6 +4713,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 		}
 		break;
 
+	case BuiltinProc_arm64_read_cycle_counter_frequency:
 	case BuiltinProc_read_cycle_counter:
 		operand->mode = Addressing_Value;
 		operand->type = t_i64;

+ 3 - 0
src/checker_builtin_procs.hpp

@@ -225,6 +225,8 @@ BuiltinProc__simd_end,
 	BuiltinProc_x86_cpuid,
 	BuiltinProc_x86_xgetbv,
 
+	BuiltinProc_arm64_read_cycle_counter_frequency,
+
 	// Constant type tests
 
 BuiltinProc__type_begin,
@@ -584,6 +586,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
 	{STR_LIT("syscall_bsd"), 1, true, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
 	{STR_LIT("x86_cpuid"),  2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("x86_xgetbv"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+	{STR_LIT("arm64_read_cycle_counter_frequency"), 0, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 
 
 	{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},

+ 13 - 0
src/llvm_backend_proc.cpp

@@ -2809,6 +2809,19 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
 			}
 			return res;
 		}
+	case BuiltinProc_arm64_read_cycle_counter_frequency:
+		{
+			lbValue res = {};
+			res.type = tv.type;
+
+			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 $0, cntfrq_el0"), str_lit("=r"), has_side_effects);
+			GB_ASSERT(the_asm != nullptr);
+			res.value = LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
+
+			return res;
+		}
 
 	case BuiltinProc_count_trailing_zeros:
 		return lb_emit_count_trailing_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);