diff --git a/.vscode/settings.json b/.vscode/settings.json index f564e92..2dcbd88 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -39,7 +39,11 @@ "platform.h": "c", "macros.h": "c", "linkage.h": "c", - "context_cracking.h": "c" + "context_cracking.h": "c", + "stdarg.h": "c", + "intrin.h": "c", + "stddef.h": "c", + "wmmintrin.h": "c" }, "workbench.colorCustomizations": { "activityBar.activeBackground": "#713fb8", diff --git a/code/base/base_types.c b/code/base/base_types.c new file mode 100644 index 0000000..21e2ecf --- /dev/null +++ b/code/base/base_types.c @@ -0,0 +1,6 @@ +#ifdef INTELLISENSE_DIRECTIVES +# pragma once +# include "base_types.h" +#endif + + diff --git a/code/base/base_types.h b/code/base/base_types.h index c403145..f36466a 100644 --- a/code/base/base_types.h +++ b/code/base/base_types.h @@ -286,14 +286,14 @@ typedef void VoidProc(void); typedef union Guid Guid; union Guid { - struct - { - U32 data1; - U16 data2; - U16 data3; - U8 data4[8]; - }; - U8 v[16]; + struct + { + U32 data1; + U16 data2; + U16 data3; + U8 data4[8]; + }; + U8 v[16]; }; static_assert(size_of(Guid) == 16, "Guid is not 16 bytes"); @@ -303,71 +303,24 @@ static_assert(size_of(Guid) == 16, "Guid is not 16 bytes"); typedef struct U16Array U16Array; struct U16Array { - U64 count; - U16* v; + U64 count; + U16* v; }; typedef struct U32Array U32Array; struct U32Array { - U64 count; - U32* v; + U64 count; + U32* v; }; typedef struct U64Array U64Array; struct U64Array { - U64 count; - U64* v; + U64 count; + U64* v; }; typedef struct U128Array U128Array; struct U128Array { - U64 count; - U128* v; + U64 count; + U128* v; }; - -//////////////////////////////// -//~ rjf: Safe Casts - -internal U16 safe_cast_u16(U32 x); -internal U32 safe_cast_u32(U64 x); -internal S32 safe_cast_s32(S64 x); - -//////////////////////////////// -//~ rjf: Large Base Type Functions - -internal U128 u128_zero(void); -internal U128 u128_make(U64 v0, U64 v1); -internal B32 u128_match(U128 a, U128 b); - -//////////////////////////////// -//~ rjf: Bit Patterns - -internal U32 u32_from_u64_saturate(U64 x); -internal U64 u64_up_to_pow2(U64 x); -internal S32 extend_sign32(U32 x, U32 size); -internal S64 extend_sign64(U64 x, U64 size); - -internal F32 inf32(void); -internal F32 neg_inf32(void); - -internal U16 bswap_u16(U16 x); -internal U32 bswap_u32(U32 x); -internal U64 bswap_u64(U64 x); - -#if ARCH_LITTLE_ENDIAN -# define from_be_u16(x) bswap_u16(x) -# define from_be_u32(x) bswap_u32(x) -# define from_be_u64(x) bswap_u64(x) -#else -# define from_be_u16(x) (x) -# define from_be_u32(x) (x) -# define from_be_u64(x) (x) -#endif - -internal U64 count_bits_set32(U32 val); -internal U64 count_bits_set64(U64 val); - -internal U64 ctz32(U32 val); -internal U64 ctz64(U64 val); -internal U64 clz32(U32 val); -internal U64 clz64(U64 val); diff --git a/code/base/debug.h b/code/base/debug.h index c2cee19..6b5a607 100644 --- a/code/base/debug.h +++ b/code/base/debug.h @@ -1,6 +1,7 @@ #ifdef INTELLISENSE_DIRECTIVES # pragma once # include "context_cracking.h" +# include "linkage.h" # include "macros.h" # include "base_types.h" #endif diff --git a/code/base/math.h b/code/base/math.h index 4da0ced..a5b48b9 100644 --- a/code/base/math.h +++ b/code/base/math.h @@ -4,6 +4,9 @@ # include "linkage.h" # include "macros.h" # include "base_types.h" +# include "memory.h" +# include "memory_substrate.h" +# include "arena.h" #endif // Copyright (c) 2024 Epic Games Tools @@ -953,8 +956,6 @@ u32_from_rgba(Vec4F32 rgba) return result; } - - #define rgba_from_u32_lit_comp(h) \ { \ (((h) & 0xff000000) >> 24) / 255.f, \ @@ -966,29 +967,56 @@ u32_from_rgba(Vec4F32 rgba) //////////////////////////////// //~ rjf: List Type Functions -void rng1s64_list_push (Arena *arena, Rng1S64List *list, Rng1S64 rng); -Rng1S64Array rng1s64_array_from_list(Arena *arena, Rng1S64List *list); - inline void -rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng) +rng1s64_list_push(Arena* arena, Rng1S64List* list, Rng1S64 rng) { - Rng1S64Node* n = push_array(arena, Rng1S64Node, 1); - MemoryCopyStruct(&n->v, &rng); - SLLQueuePush(list->first, list->last, n); - list->count += 1; +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL + Rng1S64Node* n = push_array(arena, Rng1S64Node, 1); + memory_copy_struct(&n->v, &rng); + sll_queue_push(list->first, list->last, n); + list->count += 1; +#else + rng1s64_list_alloc(arena_allocator(arena), list, rng); +#endif } inline Rng1S64Array -rng1s64_array_from_list(Arena *arena, Rng1S64List *list) +rng1s64_array_from_list(Arena* arena, Rng1S64List* list) { - Rng1S64Array - arr = {0}; - arr.count = list->count; - arr.v = push_array_no_zero(arena, Rng1S64, arr.count); - U64 idx = 0; - for(Rng1S64Node *n = list->first; n != 0; n = n->next) { - arr.v[idx] = n->v; - idx += 1; - } - return arr; +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL + Rng1S64Array + arr = {0}; + arr.count = list->count; + arr.v = push_array_no_zero(arena, Rng1S64, arr.count); + U64 idx = 0; + for (Rng1S64Node *n = list->first; n != 0; n = n->next) { + arr.v[idx] = n->v; + idx += 1; + } + return arr; +#else + return rng1s64_array_from_list_alloc(arena_allocator(arena), list); +#endif +} + +inline void +rng1s64_list_alloc(AllocatorInfo ainfo, Rng1S64List* list, Rng1S64 rng) { + Rng1S64Node* n = alloc_array(ainfo, Rng1S64Node, 1); + memory_copy_struct(&n->v, &rng); + sll_queue_push(list->first, list->last, n); + list->count += 1; +} + +inline Rng1S64Array +rng1s64_array_from_list_alloc(AllocatorInfo ainfo, Rng1S64List* list) { + Rng1S64Array + arr = {0}; + arr.count = list->count; + arr.v = alloc_array_no_zero(ainfo, Rng1S64, arr.count); + U64 idx = 0; + for (Rng1S64Node *n = list->first; n != 0; n = n->next) { + arr.v[idx] = n->v; + idx += 1; + } + return arr; } diff --git a/code/base/memory.h b/code/base/memory.h index c7c637d..bdad99c 100644 --- a/code/base/memory.h +++ b/code/base/memory.h @@ -147,39 +147,40 @@ //~ rjf: Memory Functions inline B32 -memory_is_zero(void *ptr, U64 size){ - B32 result = 1; - - // break down size - U64 extra = (size&0x7); - U64 count8 = (size >> 3); - - // check with 8-byte stride - U64 *p64 = (U64*)ptr; - if(result) - { - for (U64 i = 0; i < count8; i += 1, p64 += 1){ - if (*p64 != 0){ - result = 0; - goto done; - } - } - } - - // check extra - if(result) - { - U8 *p8 = (U8*)p64; - for (U64 i = 0; i < extra; i += 1, p8 += 1){ - if (*p8 != 0){ - result = 0; - goto done; - } - } - } - - done:; - return(result); +memory_is_zero(void* ptr, U64 size) +{ + B32 result = 1; + + // break down size + U64 extra = (size & 0x7); + U64 count8 = (size >> 3); + + // check with 8-byte stride + U64* p64 = (U64*)ptr; + if (result) + { + for (U64 i = 0; i < count8; i += 1, p64 += 1) { + if (*p64 != 0){ + result = 0; + goto done; + } + } + } + + // check extra + if (result) + { + U8* p8 = (U8*)p64; + for (U64 i = 0; i < extra; i += 1, p8 += 1) { + if (*p8 != 0) { + result = 0; + goto done; + } + } + } + +done:; + return(result); } inline @@ -696,3 +697,142 @@ void* mem_set( void* destination, U8 fill_byte, SSIZE byte_count ) #else # error "No thread local support" #endif + + +//////////////////////////////// +//~ rjf: Safe Casts + +inline U16 +safe_cast_u16(U32 x) { + assert_always(x <= MAX_U16); + U16 result = (U16)x; + return result; +} + +inline U32 +safe_cast_u32(U64 x) { + assert_always(x <= MAX_U32); + U32 result = (U32)x; + return result; +} + +inline S32 +safe_cast_s32(S64 x) { + assert_always(x <= MAX_S32); + S32 result = (S32)x; + return result; +} + +//////////////////////////////// +//~ rjf: Large Base Type Functions + +inline U128 u128_zero (void) { U128 v = {0}; return v; } +inline U128 u128_make (U64 v0, U64 v1) { U128 v = {v0, v1}; return v; } +inline B32 u128_match(U128 a, U128 b) { return memory_match_struct(&a, &b); } + +//////////////////////////////// +//~ rjf: Bit Patterns + +inline U32 u32_from_u64_saturate(U64 x) { U32 x32 = (x > MAX_U32) ? MAX_U32 : (U32)x; return(x32); } + +inline U64 +u64_up_to_pow2(U64 x) { + if (x == 0) { + x = 1; + } + else { + x -= 1; + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + x |= (x >> 32); + x += 1; + } + return(x); +} + +inline S32 +extend_sign32(U32 x, U32 size) { + U32 high_bit = size * 8; + U32 shift = 32 - high_bit; + S32 result = ((S32)x << shift) >> shift; + return result; +} + +inline S64 +extend_sign64(U64 x, U64 size) { + U64 high_bit = size * 8; + U64 shift = 64 - high_bit; + S64 result = ((S64)x << shift) >> shift; + return result; +} + +inline F32 inf32 (void) { union { U32 u; F32 f; } x; x.u = EXPONENT32; return(x.f); } +inline F32 neg_inf32(void) { union { U32 u; F32 f; } x; x.u = SIGN32 | EXPONENT32; return(x.f); } + +inline U16 +bswap_u16(U16 x) +{ + U16 result = (((x & 0xFF00) >> 8) | + ((x & 0x00FF) << 8)); + return result; +} + +inline U32 +bswap_u32(U32 x) +{ + U32 result = (((x & 0xFF000000) >> 24) | + ((x & 0x00FF0000) >> 8) | + ((x & 0x0000FF00) << 8) | + ((x & 0x000000FF) << 24)); + return result; +} + +inline U64 +bswap_u64(U64 x) +{ + // TODO(nick): naive bswap, replace with something that is faster like an intrinsic + U64 result = (((x & 0xFF00000000000000ULL) >> 56) | + ((x & 0x00FF000000000000ULL) >> 40) | + ((x & 0x0000FF0000000000ULL) >> 24) | + ((x & 0x000000FF00000000ULL) >> 8) | + ((x & 0x00000000FF000000ULL) << 8) | + ((x & 0x0000000000FF0000ULL) << 24) | + ((x & 0x000000000000FF00ULL) << 40) | + ((x & 0x00000000000000FFULL) << 56)); + return result; +} + +#if ARCH_LITTLE_ENDIAN +# define from_be_u16(x) bswap_u16(x) +# define from_be_u32(x) bswap_u32(x) +# define from_be_u64(x) bswap_u64(x) +#else +# define from_be_u16(x) (x) +# define from_be_u32(x) (x) +# define from_be_u64(x) (x) +#endif + +#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) + inline U64 count_bits_set16(U16 val) { return __popcnt16(val); } + inline U64 count_bits_set32(U32 val) { return __popcnt (val); } + inline U64 count_bits_set64(U64 val) { return __popcnt64(val); } + + inline U64 ctz32(U32 mask) { unsigned long idx; _BitScanForward (&idx, mask); return idx; } + inline U64 ctz64(U64 mask) { unsigned long idx; _BitScanForward64(&idx, mask); return idx; } + inline U64 clz32(U32 mask) { unsigned long idx; _BitScanReverse (&idx, mask); return 31 - idx; } + inline U64 clz64(U64 mask) { unsigned long idx; _BitScanReverse64(&idx, mask); return 63 - idx; } +#elif COMPILER_CLANG || COMPILER_GCC + inline U64 count_bits_set16(U16 val) { NotImplemented; return 0; } + inline U64 count_bits_set32(U32 val) { NotImplemented; return 0; } + inline U64 count_bits_set64(U64 val) { NotImplemented; return 0; } + + inline U64 ctz32(U32 val) { NotImplemented; return 0; } + inline U64 ctz64(U32 val) { NotImplemented; return 0; } + inline U64 clz32(U32 val) { NotImplemented; return 0; } + inline U64 clz64(U64 val) { NotImplemented; return 0; } +#else +# error "Bit intrinsic functions not defined for this compiler." +#endif diff --git a/code/base/memory_substrate.h b/code/base/memory_substrate.h index 23f9f5c..54ae8c1 100644 --- a/code/base/memory_substrate.h +++ b/code/base/memory_substrate.h @@ -36,8 +36,6 @@ enum AllocatorMode AllocatorMode_Free, AllocatorMode_FreeAll, AllocatorMode_Resize, - // AllocatorMode_Pop, - // AllocatorMode_Pop_To, AllocatorMode_QueryType, AllocatorMode_QuerySupport, }; @@ -48,8 +46,6 @@ enum AllocatorQuery_Free = (1 << 1), AllocatorQuery_FreeAll = (1 << 2), AllocatorQuery_Resize = (1 << 3), - // AllocatorQuery_Pop = (1 << 3), - // AllocatorQuery_Pop_To = (1 << 3), }; typedef void*(AllocatorProc)( void* allocator_data, AllocatorMode type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags ); @@ -91,10 +87,6 @@ void* alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment ); // Free allocated memory. void alloc_free( AllocatorInfo a, void* ptr ); -// void alloc_pop(AllocatorInfo a, SSIZE amt); - -// void alloc_pop_to(AllocatorInfo a, SSIZE pos); - // Free all memory allocated by an allocator. void free_all( AllocatorInfo a ); @@ -271,22 +263,6 @@ void alloc_free( AllocatorInfo a, void* ptr ) { } } -// inline -// void alloc_pop(AllocatorInfo a, SSIZE amt) { -// if (a.proc == nullptr) { -// a = default_allocator(); -// } -// a.proc(a.data, AllocatorMode_Pop, amt, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS); -// } - -// inline -// void alloc_pop_to(AllocatorInfo a, SSIZE pos) { -// if (a.proc == nullptr) { -// a = default_allocator(); -// } -// a.proc(a.data, AllocatorMode_Pop_To, 0, 0, rcast(void*, pos), 0, 0); -// } - inline void free_all( AllocatorInfo a ) { if (a.proc == nullptr) { diff --git a/code/base/platform.h b/code/base/platform.h index e2dbd10..01fbd7a 100644 --- a/code/base/platform.h +++ b/code/base/platform.h @@ -1,8 +1,6 @@ #ifdef INTELLISENSE_DIRECTIVES # pragma once # include "context_cracking.h" -# include "linkage.h" -# include "macros.h" #endif #include diff --git a/code/base/space.h b/code/base/space.h index 2924686..f79a707 100644 --- a/code/base/space.h +++ b/code/base/space.h @@ -62,12 +62,5 @@ Dir2; //////////////////////////////// //~ rjf: Enum -> Sign -internal S32 -sign_from_side_S32(Side side){ - return((side == Side_Min)?-1:1); -} - -internal F32 -sign_from_side_F32(Side side){ - return((side == Side_Min)?-1.f:1.f); -} +inline S32 sign_from_side_S32(Side side) { return((side == Side_Min) ? -1 : 1 ); } +inline F32 sign_from_side_F32(Side side) { return((side == Side_Min) ? -1.f : 1.f); } diff --git a/code/base/strings.c b/code/base/strings.c index b5db535..66a0b44 100644 --- a/code/base/strings.c +++ b/code/base/strings.c @@ -367,7 +367,7 @@ str8_from_allocator_size(AllocatorInfo ainfo, U64 z) { String8 str8_from_u64(Arena* arena, U64 u64, U32 radix, U8 min_digits, U8 digit_group_separator) { - #if 0 +#if MD_DONT_MAP_ARENA_TO_ALLOCATOR_IMPL String8 result = {0}; { // rjf: prefix @@ -452,8 +452,9 @@ str8_from_u64(Arena* arena, U64 u64, U32 radix, U8 min_digits, U8 digit_group_se } } return result; - #endif +#else return str8_from_allocator_u64(arena_allocator(arena), u64, radix, min_digits, digit_group_separator); +#endif } String8 @@ -573,7 +574,7 @@ str8_from_alloctor_s64(AllocatorInfo ainfo, S64 s64, U32 radix, U8 min_digits, U if(s64 < 0) { U8 bytes[KB(8)]; FArena scratch = farena_from_memory(bytes, size_of(bytes)); - String8 numeric_part = str8__from_allocator_u64(farena_allocator(scratch), (U64)(-s64), radix, min_digits, digit_group_separator); + String8 numeric_part = str8_from_allocator_u64(farena_allocator(scratch), (U64)(-s64), radix, min_digits, digit_group_separator); result = str8f(ainfo, "-%S", numeric_part); } else { @@ -723,13 +724,9 @@ str8_list_copy(Arena *arena, String8List *list) { } String8List -str8_list_alloc_copy(AllocatorInfo ainfo, String8List* list) -{ +str8_list_alloc_copy(AllocatorInfo ainfo, String8List* list) { String8List result = {0}; - for (String8Node* node = list->first; - node != 0; - node = node->next) - { + for (String8Node* node = list->first; node != 0; node = node->next) { String8Node* new_node = alloc_array_no_zero(ainfo, String8Node, 1); String8 new_string = str8_copy(ainfo, node->string); str8_list_push_node_set_string(&result, new_node, new_string); @@ -857,7 +854,7 @@ str8_list_join_alloc(AllocatorInfo ainfo, String8List* list, StringJoin* optiona { StringJoin join = {0}; if (optional_params != 0){ - MemoryCopyStruct(&join, optional_params); + memory_copy_struct(&join, optional_params); } U64 sep_count = 0; diff --git a/code/base/strings.h b/code/base/strings.h index c2403ab..89fb267 100644 --- a/code/base/strings.h +++ b/code/base/strings.h @@ -710,7 +710,7 @@ internal OperatingSystem operating_system_from_string(String8 string); internal String8 string_from_dimension(Dimension dimension); internal String8 string_from_side(Side side); internal String8 string_from_operating_system(OperatingSystem os); -internal String8 string_from_architecture(Architecture arch); +internal String8 string_from_arch(Arch arch); //////////////////////////////// //~ rjf: Time Types -> String @@ -785,8 +785,8 @@ internal void* str8_deserial_get_raw_ptr (String8 string, U64 off internal U64 str8_deserial_read_cstr (String8 string, U64 off, String8* cstr_out); internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 off, String16* str_out); internal U64 str8_deserial_read_block (String8 string, U64 off, U64 size, String8* block_out); -internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out); -internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out); +internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out); +internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out); #define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr)) * (count), sizeof( *(ptr))) #define str8_deserial_read_struct(string, off, ptr) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr)), sizeof( *(ptr))) diff --git a/code/base/toolchain.h b/code/base/toolchain.h index 6d84965..4c91601 100644 --- a/code/base/toolchain.h +++ b/code/base/toolchain.h @@ -1,5 +1,6 @@ #ifdef INTELLISENSE_DIRECTIVES # pragma once +# include "base_types.h" #endif //////////////////////////////// @@ -24,16 +25,16 @@ typedef enum ImageType Image_Macho } ImageType; -typedef enum Architecture +typedef enum Arch { - Architecture_Null, - Architecture_x64, - Architecture_x86, - Architecture_arm64, - Architecture_arm32, - Architecture_COUNT, + Arch_Null, + Arch_x64, + Arch_x86, + Arch_arm64, + Arch_arm32, + Arch_COUNT, } -Architecture; +Arch; typedef enum Compiler { @@ -48,9 +49,66 @@ Compiler; //////////////////////////////// //~ rjf: Toolchain/Environment Enum Functions -internal U64 bit_size_from_arch(Arch arch); -internal U64 max_instruction_size_from_arch(Arch arch); +inline U64 +bit_size_from_arch(Arch arch) +{ + // TODO(rjf): metacode + U64 arch_bitsize = 0; + switch(arch) + { + case Arch_x64: arch_bitsize = 64; break; + case Arch_x86: arch_bitsize = 32; break; + case Arch_arm64: arch_bitsize = 64; break; + case Arch_arm32: arch_bitsize = 32; break; + default: break; + } + return arch_bitsize; +} -internal OperatingSystem operating_system_from_context(void); -internal Arch arch_from_context(void); -internal Compiler compiler_from_context(void); +inline U64 +max_instruction_size_from_arch(Arch arch) +{ + // TODO(rjf): make this real + return 64; +} + +inline OperatingSystem +operating_system_from_context(void) { + OperatingSystem os = OperatingSystem_Null; +#if OS_WINDOWS + os = OperatingSystem_Windows; +#elif OS_LINUX + os = OperatingSystem_Linux; +#elif OS_MAC + os = OperatingSystem_Mac; +#endif + return os; +} + +inline Arch +arch_from_context(void) { + Arch arch = Arch_Null; +#if ARCH_X64 + arch = Arch_x64; +#elif ARCH_X86 + arch = Arch_x86; +#elif ARCH_ARM64 + arch = Arch_arm64; +#elif ARCH_ARM32 + arch = Arch_arm32; +#endif + return arch; +} + +inline Compiler +compiler_from_context(void) { + Compiler compiler = Compiler_Null; +#if COMPILER_MSVC + compiler = Compiler_msvc; +#elif COMPILER_GCC + compiler = Compiler_gcc; +#elif COMPILER_CLANG + compiler = Compiler_clang; +#endif + return compiler; +} diff --git a/code/metadesk.h b/code/metadesk.h index 99797e9..b559588 100644 --- a/code/metadesk.h +++ b/code/metadesk.h @@ -7,10 +7,10 @@ // base #include "base/context_cracking.h" +#include "base/platform.h" #include "base/linkage.h" #include "base/macros.h" #include "base/generic_macros.h" -#include "base/platform.h" #include "base/namespace.h" MD_NS_BEGIN