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.
This commit is contained in:
Meng Zhuo 2026-05-31 22:36:41 +08:00
parent 3b1fe97a59
commit 6b53465347
6 changed files with 32 additions and 3 deletions

View File

@ -73,7 +73,7 @@ OBJ-arm-vfp = $(OBJ-arm)
OBJ-arm-eabi = $(OBJ-arm) OBJ-arm-eabi = $(OBJ-arm)
OBJ-arm-eabihf = $(OBJ-arm) OBJ-arm-eabihf = $(OBJ-arm)
OBJ-arm-wince = $(ARM_O) $(WIN_O) 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-extra = $(filter $(EXTRA_O),$(OBJ-$T))
OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T))) OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))

10
lib/riscvflush.c Normal file
View File

@ -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);
}

1
tcc.h
View File

@ -1730,6 +1730,7 @@ ST_FUNC void arch_transfer_ret_regs(int);
ST_FUNC void gen_cvt_sxtw(void); ST_FUNC void gen_cvt_sxtw(void);
ST_FUNC void gen_cvt_csti(int t); ST_FUNC void gen_cvt_csti(int t);
ST_FUNC void gen_increment_tcov (SValue *sv); ST_FUNC void gen_increment_tcov (SValue *sv);
ST_FUNC void gen_clear_cache(void);
#endif #endif
/* ------------ c67-gen.c ------------ */ /* ------------ c67-gen.c ------------ */

View File

@ -5953,6 +5953,8 @@ ST_FUNC void unary(void)
vtop->type = type; vtop->type = type;
break; break;
} }
#endif
#ifdef TCC_TARGET_ARM64
case TOK___arm64_clear_cache: { case TOK___arm64_clear_cache: {
parse_builtin_params(0, "ee"); parse_builtin_params(0, "ee");
gen_clear_cache(); gen_clear_cache();
@ -5961,6 +5963,17 @@ ST_FUNC void unary(void)
break; break;
} }
#endif #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 */ /* atomic operations */
case TOK___atomic_store: case TOK___atomic_store:

View File

@ -490,7 +490,7 @@ static int protect_pages(void *ptr, unsigned long length, int mode)
if (mprotect(ptr, length, protect[mode])) if (mprotect(ptr, length, protect[mode]))
return -1; return -1;
/* XXX: BSD sometimes dump core with bad system call */ /* 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) { if (mode == 0 || mode == 3) {
void __clear_cache(void *beginning, void *end); void __clear_cache(void *beginning, void *end);
__clear_cache(ptr, (char *)ptr + length); __clear_cache(ptr, (char *)ptr + length);

View File

@ -307,8 +307,13 @@
#if defined TCC_TARGET_PE #if defined TCC_TARGET_PE
DEF(TOK___chkstk, "__chkstk") DEF(TOK___chkstk, "__chkstk")
#endif #endif
#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 #ifdef TCC_TARGET_ARM64
DEF(TOK___arm64_clear_cache, "__arm64_clear_cache") 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___addtf3, "__addtf3")
DEF(TOK___subtf3, "__subtf3") DEF(TOK___subtf3, "__subtf3")
DEF(TOK___multf3, "__multf3") DEF(TOK___multf3, "__multf3")