From 6b5346534746d4e81525109869b836359175ba1d Mon Sep 17 00:00:00 2001 From: Meng Zhuo Date: Sun, 31 May 2026 22:36:41 +0800 Subject: [PATCH] riscv64: enable gen_clear_cache with I-cache flushing Wire gen_clear_cache to __riscv64_clear_cache builtin, emitting fence.i for instruction cache synchronization. Add lib/riscvflush.c to provide __clear_cache for JIT bootstrap. Extend tccrun.c I-cache flush guard to include RISC-V targets. Add gen_clear_cache declaration to tcc.h riscv64 section. --- lib/Makefile | 2 +- lib/riscvflush.c | 10 ++++++++++ tcc.h | 1 + tccgen.c | 13 +++++++++++++ tccrun.c | 2 +- tcctok.h | 7 ++++++- 6 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 lib/riscvflush.c diff --git a/lib/Makefile b/lib/Makefile index 0afadff5..3ac6f8f0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -73,7 +73,7 @@ OBJ-arm-vfp = $(OBJ-arm) OBJ-arm-eabi = $(OBJ-arm) OBJ-arm-eabihf = $(OBJ-arm) OBJ-arm-wince = $(ARM_O) $(WIN_O) -OBJ-riscv64 = $(RISCV64_O) $(LIN_O) +OBJ-riscv64 = $(RISCV64_O) riscvflush.o $(LIN_O) OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T)) OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T))) diff --git a/lib/riscvflush.c b/lib/riscvflush.c new file mode 100644 index 00000000..995bbfc8 --- /dev/null +++ b/lib/riscvflush.c @@ -0,0 +1,10 @@ +/* riscvflush.c - flush the instruction cache + + __clear_cache is used in tccrun.c, It is a built-in + intrinsic with gcc. However tcc in order to compile + itself needs this function */ + +void __clear_cache(void *beg, void *end) +{ + __riscv64_clear_cache(beg, end); +} diff --git a/tcc.h b/tcc.h index c74fae47..d22ed534 100644 --- a/tcc.h +++ b/tcc.h @@ -1730,6 +1730,7 @@ ST_FUNC void arch_transfer_ret_regs(int); ST_FUNC void gen_cvt_sxtw(void); ST_FUNC void gen_cvt_csti(int t); ST_FUNC void gen_increment_tcov (SValue *sv); +ST_FUNC void gen_clear_cache(void); #endif /* ------------ c67-gen.c ------------ */ diff --git a/tccgen.c b/tccgen.c index 7d1381f8..a5df8876 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5953,6 +5953,8 @@ ST_FUNC void unary(void) vtop->type = type; break; } +#endif +#ifdef TCC_TARGET_ARM64 case TOK___arm64_clear_cache: { parse_builtin_params(0, "ee"); gen_clear_cache(); @@ -5961,6 +5963,17 @@ ST_FUNC void unary(void) break; } #endif +#ifdef TCC_TARGET_RISCV64 + case TOK___riscv64_clear_cache: { + parse_builtin_params(0, "ee"); + vpop(); + vpop(); + gen_clear_cache(); + vpushi(0); + vtop->type.t = VT_VOID; + break; + } +#endif /* atomic operations */ case TOK___atomic_store: diff --git a/tccrun.c b/tccrun.c index 5d16da9a..b3127413 100644 --- a/tccrun.c +++ b/tccrun.c @@ -490,7 +490,7 @@ static int protect_pages(void *ptr, unsigned long length, int mode) if (mprotect(ptr, length, protect[mode])) return -1; /* XXX: BSD sometimes dump core with bad system call */ -# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64 +# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 if (mode == 0 || mode == 3) { void __clear_cache(void *beginning, void *end); __clear_cache(ptr, (char *)ptr + length); diff --git a/tcctok.h b/tcctok.h index b4f5ba7c..458e106d 100644 --- a/tcctok.h +++ b/tcctok.h @@ -307,8 +307,13 @@ #if defined TCC_TARGET_PE DEF(TOK___chkstk, "__chkstk") #endif -#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 +#ifdef TCC_TARGET_ARM64 DEF(TOK___arm64_clear_cache, "__arm64_clear_cache") +#endif +#ifdef TCC_TARGET_RISCV64 + DEF(TOK___riscv64_clear_cache, "__riscv64_clear_cache") +#endif +#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 DEF(TOK___addtf3, "__addtf3") DEF(TOK___subtf3, "__subtf3") DEF(TOK___multf3, "__multf3")