diff --git a/src/compiler/enums.h b/src/compiler/enums.h index a87a76342..aa740c77f 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -762,6 +762,7 @@ typedef enum BUILTIN_MEMCOPY, BUILTIN_MEMSET, BUILTIN_SYSCALL, + BUILTIN_SYSCLOCK, BUILTIN_NONE, NUMBER_OF_BUILTINS = BUILTIN_NONE, } BuiltinFunction; diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 9336e0d0b..89e2fd688 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -617,6 +617,8 @@ void llvm_codegen_setup() intrinsic_id.umax = lookup_intrinsic("llvm.umax"); intrinsic_id.umin = lookup_intrinsic("llvm.umin"); + intrinsic_id.readcyclecounter = lookup_intrinsic("llvm.readcyclecounter"); + intrinsic_id.memset = lookup_intrinsic("llvm.memset"); intrinsic_id.memcpy = lookup_intrinsic("llvm.memcpy"); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index e5ed6b582..db9079de3 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4154,6 +4154,7 @@ static void llvm_emit_intrinsic_expr(GenContext *c, unsigned intrinsic, BEValue { call_args = 1; call_type[0] = llvm_get_type(c, expr->type); + if (intrinsic == intrinsic_id.readcyclecounter) call_args = 0; } else if (intrinsic == intrinsic_id.memcpy) { @@ -4344,6 +4345,8 @@ unsigned llvm_get_intrinsic(BuiltinFunction func) case BUILTIN_UNREACHABLE: case BUILTIN_STACKTRACE: UNREACHABLE + case BUILTIN_SYSCLOCK: + return intrinsic_id.readcyclecounter; case BUILTIN_TRAP: return intrinsic_id.trap; case BUILTIN_CEIL: diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 445b517c2..79c4f13de 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -178,6 +178,7 @@ typedef struct unsigned lifetime_end; unsigned memcpy; unsigned memset; + unsigned readcyclecounter; } LLVMIntrinsics; extern LLVMIntrinsics intrinsic_id; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index d67aec8d6..746843389 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2293,6 +2293,7 @@ static inline unsigned builtin_expected_args(BuiltinFunction func) case BUILTIN_UNREACHABLE: case BUILTIN_TRAP: case BUILTIN_STACKTRACE: + case BUILTIN_SYSCLOCK: return 0; case BUILTIN_SYSCALL: case BUILTIN_CEIL: @@ -2454,6 +2455,9 @@ static inline bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *ex case BUILTIN_TRAP: rtype = type_void; break; + case BUILTIN_SYSCLOCK: + rtype = type_ulong; + break; case BUILTIN_SYSCALL: if (arg_count > 7) { diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index d98ee9bba..5212329d6 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -177,6 +177,7 @@ void symtab_init(uint32_t capacity) kw_mainstub = KW_DEF("_$mainstub"); builtin_list[BUILTIN_TRAP] = KW_DEF("trap"); + builtin_list[BUILTIN_SYSCLOCK] = KW_DEF("sysclock"); builtin_list[BUILTIN_UNREACHABLE] = KW_DEF("unreachable"); builtin_list[BUILTIN_STACKTRACE] = KW_DEF("stacktrace"); builtin_list[BUILTIN_CEIL] = KW_DEF("ceil");