PPC: Use builtin D-Cache/I-Cache sync code.

This commit is contained in:
Mike Pall 2012-03-29 01:12:54 +02:00
parent a53a549774
commit 1980ee95b0
4 changed files with 522 additions and 484 deletions

View File

@ -2533,6 +2533,31 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Miscellaneous functions -------------------------------------------- |//-- Miscellaneous functions --------------------------------------------
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------
| |
|// void lj_vm_cachesync(void *start, void *end)
|// Flush D-Cache and invalidate I-Cache. Assumes 32 byte cache line size.
|// This is a good lower bound, except for very ancient PPC models.
|->vm_cachesync:
| // Compute start of first cache line and number of cache lines.
| rlwinm CARG1, CARG1, 0, 0, 26
| sub CARG2, CARG2, CARG1
| addi CARG2, CARG2, 31
| rlwinm. CARG2, CARG2, 27, 5, 31
| beqlr
| mtctr CARG2
| mr CARG3, CARG1
|1: // Flush D-Cache.
| dcbst r0, CARG1
| addi CARG1, CARG1, 32
| bdnz <1
| sync
| mtctr CARG2
|1: // Invalidate I-Cache.
| icbi r0, CARG3
| addi CARG3, CARG3, 32
| bdnz <1
| isync
| blr
|
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------
|//-- FFI helper functions ----------------------------------------------- |//-- FFI helper functions -----------------------------------------------
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -29,15 +29,6 @@
void sys_icache_invalidate(void *start, size_t len); void sys_icache_invalidate(void *start, size_t len);
#endif #endif
#if LJ_TARGET_LINUX && LJ_TARGET_PPC
#include <dlfcn.h>
static void (*mcode_sync_ppc)(void *start, void *end);
static void mcode_sync_dummy(void *start, void *end)
{
UNUSED(start); UNUSED(end);
}
#endif
/* Synchronize data/instruction cache. */ /* Synchronize data/instruction cache. */
void lj_mcode_sync(void *start, void *end) void lj_mcode_sync(void *start, void *end)
{ {
@ -48,14 +39,9 @@ void lj_mcode_sync(void *start, void *end)
UNUSED(start); UNUSED(end); UNUSED(start); UNUSED(end);
#elif LJ_TARGET_OSX #elif LJ_TARGET_OSX
sys_icache_invalidate(start, (char *)end-(char *)start); sys_icache_invalidate(start, (char *)end-(char *)start);
#elif LJ_TARGET_LINUX && LJ_TARGET_PPC #elif LJ_TARGET_PPC
if (!mcode_sync_ppc) { lj_vm_cachesync(start, end);
void *vdso = dlopen("linux-vdso32.so.1", RTLD_LAZY); #elif defined(__GNUC__)
if (!vdso || !(mcode_sync_ppc = dlsym(vdso, "__kernel_sync_dicache")))
mcode_sync_ppc = mcode_sync_dummy;
}
mcode_sync_ppc(start, end);
#elif defined(__GNUC__) && !LJ_TARGET_PPC
__clear_cache(start, end); __clear_cache(start, end);
#else #else
#error "Missing builtin to flush instruction cache" #error "Missing builtin to flush instruction cache"

View File

@ -27,6 +27,9 @@ LJ_ASMF void lj_vm_unwind_rethrow(void);
#if LJ_TARGET_X86ORX64 #if LJ_TARGET_X86ORX64
LJ_ASMF int lj_vm_cpuid(uint32_t f, uint32_t res[4]); LJ_ASMF int lj_vm_cpuid(uint32_t f, uint32_t res[4]);
#endif #endif
#if LJ_TARGET_PPC
void lj_vm_cachesync(void *start, void *end);
#endif
LJ_ASMF double lj_vm_foldarith(double x, double y, int op); LJ_ASMF double lj_vm_foldarith(double x, double y, int op);
#if LJ_HASJIT #if LJ_HASJIT
LJ_ASMF double lj_vm_foldfpm(double x, int op); LJ_ASMF double lj_vm_foldfpm(double x, int op);