diff options
author | thegeorg <[email protected]> | 2025-08-24 15:59:56 +0300 |
---|---|---|
committer | thegeorg <[email protected]> | 2025-08-24 16:16:25 +0300 |
commit | 44b8a2e37ee4a558fdbcb5cc4ebd38f3c624586f (patch) | |
tree | 104fc4605093a1fdfb55d15a20003cef3b91e802 /contrib/libs/pcre/sljit | |
parent | 70416efb6bec4e0daeb6f70711260a2185e18fa5 (diff) |
Bump nixpkgs revision to 24.05
commit_hash:5adc9b27af48577e01225ed6df2f1cc0c2d7e7db
Diffstat (limited to 'contrib/libs/pcre/sljit')
-rw-r--r-- | contrib/libs/pcre/sljit/sljitConfigInternal.h | 3 | ||||
-rw-r--r-- | contrib/libs/pcre/sljit/sljitNativePPC_common.c | 67 |
2 files changed, 65 insertions, 5 deletions
diff --git a/contrib/libs/pcre/sljit/sljitConfigInternal.h b/contrib/libs/pcre/sljit/sljitConfigInternal.h index acba9da4be4..2d5ff425e91 100644 --- a/contrib/libs/pcre/sljit/sljitConfigInternal.h +++ b/contrib/libs/pcre/sljit/sljitConfigInternal.h @@ -284,7 +284,8 @@ /****************************/ #if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) -#if __has_builtin(__builtin___clear_cache) +#if __has_builtin(__builtin___clear_cache) && \ + !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) #define SLJIT_CACHE_FLUSH(from, to) \ __builtin___clear_cache((char*)from, (char*)to) diff --git a/contrib/libs/pcre/sljit/sljitNativePPC_common.c b/contrib/libs/pcre/sljit/sljitNativePPC_common.c index 8103d7322a5..680cbef7b8f 100644 --- a/contrib/libs/pcre/sljit/sljitNativePPC_common.c +++ b/contrib/libs/pcre/sljit/sljitNativePPC_common.c @@ -46,6 +46,39 @@ typedef sljit_u32 sljit_ins; #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 #endif +#ifdef __linux__ +#include <sys/auxv.h> + +/* Return the instruction cache line size, in bytes. */ +static SLJIT_INLINE sljit_u32 get_icache_line_size() +{ + static sljit_u32 icache_line_size = 0; + if (SLJIT_UNLIKELY(!icache_line_size)) { + icache_line_size = (sljit_u32) getauxval(AT_ICACHEBSIZE); + SLJIT_ASSERT(icache_line_size != 0); + } + return icache_line_size; +} + +/* Cache and return the first hardware capabilities word. */ +static SLJIT_INLINE unsigned long get_hwcap() +{ + static unsigned long hwcap = 0; + if (SLJIT_UNLIKELY(!hwcap)) { + hwcap = getauxval(AT_HWCAP); + SLJIT_ASSERT(hwcap != 0); + } + return hwcap; +} + +/* Return non-zero if this CPU has the icache snoop feature. */ +static SLJIT_INLINE unsigned long has_feature_icache_snoop() +{ + return (get_hwcap() & PPC_FEATURE_ICACHE_SNOOP); +} + +#endif /* __linux__ */ + #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) @@ -68,14 +101,40 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) # error "Cache flush is not implemented for PowerPC/POWER common mode." # else /* Cache flush for PowerPC architecture. */ - while (from < to) { + /* For POWER5 and up with icache snooping, only one icbi in the range + * is required. The sync flushes the store queue, and the icbi/isync + * kills the local prefetch. + */ + if (has_feature_icache_snoop()) { __asm__ volatile ( - "dcbf 0, %0\n" "sync\n" "icbi 0, %0\n" - : : "r"(from) + "isync\n" + : : "r"(from) : "memory" + ); + return; + } + + sljit_u32 cache_line_bytes = get_icache_line_size(); + sljit_u32 cache_line_words = cache_line_bytes / sizeof(sljit_ins); + uintptr_t cache_line_mask = ~(uintptr_t)(cache_line_bytes - 1); + + /* Round down to start of cache line to simplify the end condition. */ + sljit_ins* start = (sljit_ins*)((uintptr_t)(from) & cache_line_mask); + + for (from = start; from < to; from += cache_line_words) { + __asm__ volatile ( + "dcbf 0, %0" + : : "r"(from) : "memory" + ); + } + __asm__ volatile ( "sync" ); + + for (from = start; from < to; from += cache_line_words) { + __asm__ volatile ( + "icbi 0, %0" + : : "r"(from) : "memory" ); - from++; } __asm__ volatile ( "isync" ); # endif |