3ds: use range clearing for small ranges
authornotaz <notasas@gmail.com>
Wed, 23 Oct 2024 23:25:47 +0000 (02:25 +0300)
committernotaz <notasas@gmail.com>
Thu, 24 Oct 2024 23:50:18 +0000 (02:50 +0300)
Seems to be wastefull to throw away the entire icache when just a few
new insns are compiled. Not that this gives any noticeable perf
difference though.

frontend/3ds/3ds_utils.h
frontend/3ds/utils.S
libpcsxcore/new_dynarec/new_dynarec.c

index 25bcc42..2fc44f2 100644 (file)
@@ -18,6 +18,7 @@
 
 void wait_for_input(void);
 void ctr_clear_cache(void);
+void ctr_clear_cache_range(void *start, void *end);
 //void ctr_invalidate_icache(void); // only icache
 
 extern __attribute__((weak)) int  __ctr_svchax;
index 61da155..6f7a6a2 100644 (file)
@@ -4,11 +4,39 @@
 
   .func ctr_clear_cache_kernel
 ctr_clear_cache_kernel:
+  @ this less than what B2.7.3 of DDI0100I_ARM_ARM recommends, but so is Linux
+  mrs r3, cpsr
   cpsid aif
   mov r0, #0
   mcr p15, 0, r0, c7, c10, 0    @ Clean entire data cache
   mcr p15, 0, r0, c7, c10, 4    @ Data Sync Barrier
   mcr p15, 0, r0, c7, c5, 0     @ Invalidate entire instruction cache / Flush BTB
+  msr cpsr, r3
+  bx lr
+  .endfunc
+
+  .func ctr_clear_cache_range_kernel
+ctr_clear_cache_range_kernel:
+  bic r0, r0, #31
+  mov r12, r0
+  mov r2, #0
+  mrs r3, cpsr
+  cpsid aif
+0:
+  mcr p15, 0, r0, c7, c10, 1    @ Clean Data Cache Line (using MVA)
+  add r0, r0, #32
+  cmp r0, r1
+  blo 0b
+  mcr p15, 0, r2, c7, c10, 4    @ Data Sync Barrier
+  mov r0, r12
+0:
+  mcr p15, 0, r0, c7, c5, 1     @ Invalidate Instruction Cache Line (using MVA)
+  add r0, r0, #32
+  cmp r0, r1
+  blo 0b
+  mcr p15, 0, r2, c7, c5, 6     @ Flush Entire Branch Target Cache
+
+  msr cpsr, r3
   bx lr
   .endfunc
 
@@ -23,6 +51,16 @@ ctr_clear_cache:
   bx lr
   .endfunc
 
+  .global ctr_clear_cache_range
+  .func ctr_clear_cache_range
+ctr_clear_cache_range:
+  mov r2, r1
+  mov r1, r0
+  adr r0, ctr_clear_cache_range_kernel
+  svc 0x80                      @ svcCustomBackdoor
+  bx lr
+  .endfunc
+
 #if 0
   .func ctr_invalidate_icache_kernel
 ctr_invalidate_icache_kernel:
index 6243db4..37caf47 100644 (file)
@@ -494,7 +494,11 @@ static void end_tcache_write(void *start, void *end)
   #elif defined(VITA)
   sceKernelSyncVMDomain(sceBlock, start, len);
   #elif defined(_3DS)
-  ctr_flush_invalidate_cache();
+  // tuned for old3ds' 16k:16k cache (in it's mostly clean state...)
+  if ((char *)end - (char *)start <= 2*1024)
+    ctr_clear_cache_range(start, end);
+  else
+    ctr_flush_invalidate_cache();
   ndrc_g.thread.cache_dirty = 1;
   #elif defined(HAVE_LIBNX)
   if (g_jit.type == JitType_CodeMemory) {