use vectorized memory functions in the base strings

This commit is contained in:
Nikita Smith
2026-06-19 20:12:23 -07:00
committed by Ryan Fleury
parent ba32d7fdec
commit 871f94a202
7 changed files with 2738 additions and 69 deletions
+20
View File
@@ -692,6 +692,26 @@ u64_array_bsearch(U64 *arr, U64 count, U64 value)
////////////////////////////////
internal U32
idx_of_zero_byte64(U8 *ptr, U64 size)
{
Assert(size == 8);
#if ARCH_X64
__m128i v = _mm_loadl_epi64((__m128i*)ptr);
__m128i m = _mm_cmpeq_epi8(v, _mm_setzero_si128());
U32 bits = _mm_movemask_epi8(m);
return ctz32(bits);
#else
U64 x;
MemoryCopyStruct(&x, ptr);
U64 splat = ~0ULL / 255;
U64 mask_lsb = 0x01 * splat;
U64 mask_msb = 0x80 * splat;
U64 t = (x - mask_lsb) & (~x & mask_msb);
return ctz64(t) / 8;
#endif
}
internal U64
index_of_zero_u32(U32 *ptr, U64 count)
{
+1
View File
@@ -1125,6 +1125,7 @@ internal U64 u64_array_bsearch(U64 *arr, U64 count, U64 value);
////////////////////////////////
internal U32 idx_of_zero_byte64(U8 *ptr, U64 size); // size must be exactly 8 bytes
internal U64 index_of_zero_u32(U32 *ptr, U64 count);
internal U64 index_of_zero_u64(U64 *ptr, U64 count);
internal U64 count_digits_u64(U64 v, U64 radix);
+29 -56
View File
@@ -1,6 +1,13 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
#if !defined(MEM_STATIC)
# define MEM_STATIC
# include "third_party/martins_memfun/memfun.h"
#endif
////////////////////////////////
//~ rjf: Character Classification & Conversion Functions
@@ -211,12 +218,9 @@ str32_cstring(U32 *c)
internal String8
str8_cstring_capped(void *cstr, void *cap)
{
char *ptr = (char *)cstr;
char *opl = (char *)cap;
for (;ptr < opl && *ptr != 0; ptr += 1);
U64 size = (U64)(ptr - (char *)cstr);
String8 result = str8((U8*)cstr, size);
return result;
U64 cap_size = (U64)((U8 *)cap - (U8 *)cstr);
U64 size = MemFind(cstr, cap_size, 0);
return str8(cstr, size);
}
internal String16
@@ -230,24 +234,6 @@ str16_cstring_capped(void *cstr, void *cap)
return result;
}
internal String8
str8_cstring_capped_reverse(void *raw_start, void *raw_cap)
{
U8 *start = raw_start;
U8 *ptr = raw_cap;
for(; ptr > start; )
{
ptr -= 1;
if (*ptr == '\0')
{
break;
}
}
U64 size = (U64)(ptr - start);
String8 result = str8(start, size);
return result;
}
////////////////////////////////
//~ rjf: String Stylization
@@ -293,7 +279,11 @@ str8_match(String8 a, String8 b, StringMatchFlags flags)
B32 result = 0;
if(a.size == b.size && flags == 0)
{
result = MemoryMatch(a.str, b.str, b.size);
result = MemIsEqual(a.str, b.str, b.size);
}
else if(a.size == b.size && flags == StringMatchFlag_CaseInsensitive)
{
result = MemCompareI(a.str, b.str, a.size) == 0;
}
else if(a.size == b.size || (flags & StringMatchFlag_RightSideSloppy))
{
@@ -3088,45 +3078,28 @@ str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out)
internal int
str8_compar(String8 a, String8 b, B32 ignore_case)
{
int cmp = 0;
int cmp = 0;
U64 size = Min(a.size, b.size);
if (ignore_case) {
for (U64 i = 0; i < size; ++i) {
U8 la = lower_from_char(a.str[i]);
U8 lb = lower_from_char(b.str[i]);
if (la < lb) {
cmp = -1;
break;
} else if (la > lb) {
cmp = +1;
break;
}
}
} else {
for (U64 i = 0; i < size; ++i) {
if (a.str[i] < b.str[i]) {
cmp = -1;
break;
} else if (a.str[i] > b.str[i]) {
cmp = +1;
break;
}
}
if (ignore_case)
{
cmp = MemCompareI(a.str, b.str, size);
}
else
{
cmp = MemCompare(a.str, b.str, size);
}
if (cmp == 0) {
// shorter prefix must precede longer prefixes
if (a.size > b.size) {
cmp = +1;
} else if (b.size > a.size) {
cmp = -1;
}
// shorter prefix must precede longer prefixes
if (cmp == 0)
{
cmp = (a.size > b.size) - (b.size - a.size);
}
return cmp;
}
internal int str8_compar_ignore_case(const void *a, const void *b)
internal int
str8_compar_ignore_case(const void *a, const void *b)
{
return str8_compar(*(String8*)a, *(String8*)b, 1);
}
-1
View File
@@ -185,7 +185,6 @@ internal String16 str16_cstring(U16 *c);
internal String32 str32_cstring(U32 *c);
internal String8 str8_cstring_capped(void *cstr, void *cap);
internal String16 str16_cstring_capped(void *cstr, void *cap);
internal String8 str8_cstring_capped_reverse(void *raw_start, void *raw_cap);
////////////////////////////////
//~ rjf: String Stylization
+2 -7
View File
@@ -92,13 +92,8 @@ coff_read_symbol_name(String8 string_table, COFF_SymbolName *name)
if (name->long_name.zeroes == 0) {
str8_deserial_read_cstr(string_table, name->long_name.string_table_offset, &name_str);
} else {
U32 i;
for (i = 0; i < sizeof(name->short_name); ++i) {
if (name->short_name[i] == '\0') {
break;
}
}
name_str = str8(name->short_name, i);
U32 name_size = idx_of_zero_byte64(name->short_name, sizeof(name->short_name));
name_str = str8(name->short_name, name_size);
}
return name_str;
}
+3 -5
View File
@@ -142,18 +142,16 @@ cv_type_server_info_from_leaf(CV_Leaf leaf)
CV_TypeServerInfo result = {0};
switch (leaf.kind) {
case CV_LeafKind_TYPESERVER: {
CV_LeafTypeServer *ts = (CV_LeafTypeServer *) leaf.data.str;
result.name = str8_cstring_capped_reverse(ts + 1, leaf.data.str + leaf.data.size);
CV_LeafTypeServer *ts = (CV_LeafTypeServer *) leaf.data.str;
result.name = str8_cstring_capped(ts + 1, leaf.data.str + leaf.data.size);
result.sig.data1 = ts->sig;
result.age = ts->age;
} break;
case CV_LeafKind_TYPESERVER2: {
CV_LeafTypeServer2 *ts = (CV_LeafTypeServer2 *) leaf.data.str;
Assert(sizeof(result.sig) == sizeof(ts->sig70));
MemoryCopy(&result.sig, &ts->sig70, sizeof(ts->sig70));
result.name = str8_cstring_capped_reverse(ts + 1, leaf.data.str + leaf.data.size);
result.name = str8_cstring_capped(ts + 1, leaf.data.str + leaf.data.size);
result.age = ts->age;
} break;
case CV_LeafKind_TYPESERVER_ST: {
File diff suppressed because it is too large Load Diff