diff options
Diffstat (limited to 'erts/emulator/hipe')
-rw-r--r-- | erts/emulator/hipe/hipe_arm.c | 26 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_x86.h | 25 |
2 files changed, 40 insertions, 11 deletions
diff --git a/erts/emulator/hipe/hipe_arm.c b/erts/emulator/hipe/hipe_arm.c index b61939724c..3e1d7e4d5e 100644 --- a/erts/emulator/hipe/hipe_arm.c +++ b/erts/emulator/hipe/hipe_arm.c @@ -18,6 +18,7 @@ * %CopyrightEnd% */ +#ifdef __arm__ #include <stddef.h> /* offsetof() */ #ifdef HAVE_CONFIG_H @@ -30,24 +31,39 @@ #include "hipe_native_bif.h" /* nbif_callemu() */ #include "hipe_bif0.h" +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + /* Flush dcache and invalidate icache for a range of addresses. */ void hipe_flush_icache_range(void *address, unsigned int nbytes) { -#if defined(__ARM_EABI__) + void* end = (char*)address + nbytes; + +#if ERTS_AT_LEAST_GCC_VSN__(4, 3, 0) || __has_builtin(__builtin___clear_cache) + __builtin___clear_cache(address, end); +#elif defined(__clang__) + void __clear_cache(void *start, void *end); + __clear_cache(address, end); +#elif defined(__linux__) +# if defined(__ARM_EABI__) register unsigned long beg __asm__("r0") = (unsigned long)address; - register unsigned long end __asm__("r1") = (unsigned long)address + nbytes; + register unsigned long end __asm__("r1") = (unsigned long)end; register unsigned long flg __asm__("r2") = 0; register unsigned long scno __asm__("r7") = 0xf0002; __asm__ __volatile__("swi 0" /* sys_cacheflush() */ : "=r"(beg) : "0"(beg), "r"(end), "r"(flg), "r"(scno)); -#else +# else register unsigned long beg __asm__("r0") = (unsigned long)address; - register unsigned long end __asm__("r1") = (unsigned long)address + nbytes; + register unsigned long end __asm__("r1") = (unsigned long)end; register unsigned long flg __asm__("r2") = 0; __asm__ __volatile__("swi 0x9f0002" /* sys_cacheflush() */ : "=r"(beg) : "0"(beg), "r"(end), "r"(flg)); +# endif +#else +# error "Don't know how to flush instruction cache" #endif } @@ -270,3 +286,5 @@ void hipe_arch_print_pcb(struct hipe_process_state *p) U("narity ", narity); #undef U } + +#endif /*__arm__*/ diff --git a/erts/emulator/hipe/hipe_x86.h b/erts/emulator/hipe/hipe_x86.h index 8967793171..a1fe75e792 100644 --- a/erts/emulator/hipe/hipe_x86.h +++ b/erts/emulator/hipe/hipe_x86.h @@ -22,17 +22,28 @@ #ifndef HIPE_X86_H #define HIPE_X86_H -static __inline__ void hipe_flush_icache_word(void *address) -{ - /* Do nothing. This works as long as compiled code is - executed by a single CPU thread. */ -} +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif static __inline__ void hipe_flush_icache_range(void *address, unsigned int nbytes) { - /* Do nothing. This works as long as compiled code is - executed by a single CPU thread. */ + void* end = (char*)address + nbytes; + +#if ERTS_AT_LEAST_GCC_VSN__(4, 3, 0) || __has_builtin(__builtin___clear_cache) + __builtin___clear_cache(address, end); +#elif defined(__clang__) + void __clear_cache(void *start, void *end); + __clear_cache(address, end); +#else +# warning "Don't know how to flush instruction cache" +#endif +} + +static __inline__ void hipe_flush_icache_word(void *address) +{ + hipe_flush_icache_range(address, sizeof(void*)); } /* for stack descriptor hash lookup */ |