summaryrefslogtreecommitdiff
path: root/compiler-rt/lib/builtins/clear_cache.c
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /compiler-rt/lib/builtins/clear_cache.c
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'compiler-rt/lib/builtins/clear_cache.c')
-rw-r--r--compiler-rt/lib/builtins/clear_cache.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/compiler-rt/lib/builtins/clear_cache.c b/compiler-rt/lib/builtins/clear_cache.c
index e83e21254e85..72e02e613de5 100644
--- a/compiler-rt/lib/builtins/clear_cache.c
+++ b/compiler-rt/lib/builtins/clear_cache.c
@@ -147,6 +147,16 @@ void __clear_cache(void *start, void *end) {
for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size)
__asm__ volatile("flush %0" : : "r"(dword));
+#elif defined(__riscv) && defined(__linux__)
+#define __NR_riscv_flush_icache (244 + 15)
+ register void *start_reg __asm("a0") = start;
+ const register void *end_reg __asm("a1") = end;
+ const register long flags __asm("a2") = 0;
+ const register long syscall_nr __asm("a7") = __NR_riscv_flush_icache;
+ __asm __volatile("ecall"
+ : "=r"(start_reg)
+ : "r"(start_reg), "r"(end_reg), "r"(flags), "r"(syscall_nr));
+ assert(start_reg == 0 && "Cache flush syscall failed.");
#else
#if __APPLE__
// On Darwin, sys_icache_invalidate() provides this functionality