mirror of
https://github.com/Ed94/perfaware.git
synced 2026-08-14 11:28:08 +00:00
Compare commits
5
Commits
ac1fffa422
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa9c4d48f6 | ||
|
|
823ec3d499 | ||
|
|
77bda7741f | ||
|
|
8b4c8a2c71 | ||
|
|
6feff68b33 |
@@ -0,0 +1,3 @@
|
|||||||
|
code/8086/* linguist-language=C
|
||||||
|
code/duffle/* linguist-language=C
|
||||||
|
code/part_1/* linguist-language=C
|
||||||
@@ -1 +1,2 @@
|
|||||||
build
|
build
|
||||||
|
course_content
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Computer Enhance: Performance Aware Programming Course
|
||||||
|
|
||||||
|
Progressing with company team.
|
||||||
|
|
||||||
|
Disable latency of submodules:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
git -C . config --local diff.ignoreSubmodules all
|
||||||
|
git -C . config --local status.submoduleSummary false
|
||||||
|
git -C . config --local submodule.recurse false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Gallery
|
||||||
|
|
||||||
|
Part 1: File read!
|
||||||
|

|
||||||
@@ -6,3 +6,13 @@ Sandbox: Windows 11 (for now)
|
|||||||
Compiler: clang
|
Compiler: clang
|
||||||
Standard: c11
|
Standard: c11
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Scrapped togther stuff from several repos and studies.
|
||||||
|
|
||||||
|
Some of my favorite C code:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
stb
|
||||||
|
gb or zpl
|
||||||
|
raddebugger
|
||||||
|
```
|
||||||
|
|||||||
@@ -14,4 +14,8 @@
|
|||||||
#else
|
#else
|
||||||
#define assert(cond)
|
#define assert(cond)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define trap() __builtin_trap()
|
||||||
|
|
||||||
|
#define assert_always(x) do { if((x) == false) {trap();} } while(0)
|
||||||
#pragma endregion Debug
|
#pragma endregion Debug
|
||||||
|
|||||||
+86
-19
@@ -9,6 +9,7 @@ Standard: c23
|
|||||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||||
#pragma clang diagnostic ignored "-Wswitch"
|
#pragma clang diagnostic ignored "-Wswitch"
|
||||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||||
|
#pragma clang diagnostic ignored "-Wmicrosoft-enum-forward-reference"
|
||||||
// #pragma comment(lib, "Advapi32.lib")
|
// #pragma comment(lib, "Advapi32.lib")
|
||||||
// #pragma comment(lib, "gdi32.lib")
|
// #pragma comment(lib, "gdi32.lib")
|
||||||
// #pragma comment(lib, "Kernel32.lib")
|
// #pragma comment(lib, "Kernel32.lib")
|
||||||
@@ -16,8 +17,19 @@ Standard: c23
|
|||||||
// #pragma comment(lib, "user32.lib")
|
// #pragma comment(lib, "user32.lib")
|
||||||
// #pragma comment(lib, "ucrt.lib")
|
// #pragma comment(lib, "ucrt.lib")
|
||||||
// #pragma comment(lib, "vcruntime.lib")
|
// #pragma comment(lib, "vcruntime.lib")
|
||||||
|
|
||||||
|
#pragma region Platform
|
||||||
|
#define CLANG_OPTIMIZE_DISABLE _Pragma("clang optimize off")
|
||||||
|
#define CLANG_OPTIMIZE_ENABLE _Pragma("clang optimize on")
|
||||||
|
|
||||||
|
#define DUFFLE_x86_64 1
|
||||||
|
#define DUFFLE_WINDOWS 1
|
||||||
|
|
||||||
#define WinAPI __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__)) // Win32 Syscall FFI
|
#define WinAPI __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__)) // Win32 Syscall FFI
|
||||||
|
|
||||||
|
#define os_layer // Marker for interface resolved by os platform layer.
|
||||||
|
#pragma endregion Platform
|
||||||
|
|
||||||
#define offset_of(type, member) cast(U8,__builtin_offsetof(type,member))
|
#define offset_of(type, member) cast(U8,__builtin_offsetof(type,member))
|
||||||
#define static_assert _Static_assert
|
#define static_assert _Static_assert
|
||||||
#define typeof __typeof__
|
#define typeof __typeof__
|
||||||
@@ -206,14 +218,17 @@ def_signed_ops(le, <=)
|
|||||||
#define dbg_args(...) __VA_ARGS__
|
#define dbg_args(...) __VA_ARGS__
|
||||||
|
|
||||||
#pragma region Control Flow & Iteration
|
#pragma region Control Flow & Iteration
|
||||||
|
#define unreachable() __builtin_unreachable()
|
||||||
|
|
||||||
#define each_iter(type, iter, end) (type iter = 0; iter < end; ++ iter)
|
#define each_iter(type, iter, end) (type iter = 0; iter < end; ++ iter)
|
||||||
#define index_iter(type, iter, begin, op, end) (type iter = begin; iter op end; (begin < end ? ++ iter : -- iter))
|
#define index_iter(type, iter, begin, op, end) (type iter = begin; iter op end; (begin < end ? ++ iter : -- iter))
|
||||||
#define range_iter(iter,op,range) (T_((range).p0) iter = (range).p0; iter op (range).p1; ((range).p0 < (range).p1 ? ++ iter : -- iter))
|
#define range_iter(iter,op,range) (T_((range).p0) iter = (range).p0; iter op (range).p1; ((range).p0 < (range).p1 ? ++ iter : -- iter))
|
||||||
|
|
||||||
#define defer(expr) for(U4 once= 1; once!=1;++ once,(expr)) // Basic do something after body
|
#define defer(expr) for(U4 once= 1; once!=1;++ once,(expr)) // Basic do something after body
|
||||||
#define scope(begin,end) for(U4 once=(1,(begin)); once!=1;++ once,(end )) // Do things before or after a scope
|
|
||||||
#define defer_rewind(cursor) for(T_(cursor) sp=cursor,once=0; once!=1;++ once,cursor=sp) // Used with arenas/stacks
|
#define defer_rewind(cursor) for(T_(cursor) sp=cursor,once=0; once!=1;++ once,cursor=sp) // Used with arenas/stacks
|
||||||
#define defer_info(type,expr, ...) for(type info={__VA_ARGS__}; info.once!=1;++info.once,(expr)) // Defer with tracked state
|
#define defer_info(type,expr, ...) for(type info={__VA_ARGS__}; info.once!=1;++info.once,(expr)) // Defer with tracked state
|
||||||
|
#define scope(begin,end) for(U4 once=(1,(begin)); once!=1;++ once,(end )) // Do things before or after a scope
|
||||||
|
#define scope_info(type,begin,end) for(type info=begin; info.once!=1;++info.once,(end ))
|
||||||
|
|
||||||
#define do_while(cond) for (U4 once=0; once!=1 || (cond); ++once)
|
#define do_while(cond) for (U4 once=0; once!=1 || (cond); ++once)
|
||||||
|
|
||||||
@@ -232,28 +247,80 @@ def_signed_ops(le, <=)
|
|||||||
typedef Span_(S4);
|
typedef Span_(S4);
|
||||||
typedef Span_(U4);
|
typedef Span_(U4);
|
||||||
typedef Span_(U8);
|
typedef Span_(U8);
|
||||||
|
#pragma region Thread Coherence
|
||||||
|
|
||||||
|
FI_ void barrier_compiler(void){asm volatile("::""memory");} // Compiler Barrier
|
||||||
|
FI_ void barrier_memory (void){__builtin_ia32_mfence();} // Memory Barrier
|
||||||
|
FI_ void barrier_read (void){__builtin_ia32_lfence();} // Read Barrier
|
||||||
|
FI_ void barrier_write (void){__builtin_ia32_sfence();} // Write Barrier
|
||||||
|
|
||||||
#pragma region Math
|
// x86-64
|
||||||
#define u8_max 0xffffffffffffffffull
|
FI_ U4 atm_add_u4 (U4_R addr, U4 value){asm volatile("lock xaddl %0,%1":"=r"(value),"=m"(addr[0]):"0"(value),"m"(addr[0]):"memory","cc");return value;}
|
||||||
|
FI_ U8 atm_add_u8 (U8_R addr, U8 value){asm volatile("lock xaddq %0,%1":"=r"(value),"=m"(addr[0]):"0"(value),"m"(addr[0]):"memory","cc");return value;}
|
||||||
|
FI_ U4 atm_swap_u4(U4_R addr, U4 value){asm volatile("lock xchgl %0,%1":"=r"(value),"=m"(addr[0]):"0"(value),"m"(addr[0]):"memory","cc");return value;}
|
||||||
|
FI_ U8 atm_swap_u8(U8_R addr, U8 value){asm volatile("lock xchgq %0,%1":"=r"(value),"=m"(addr[0]):"0"(value),"m"(addr[0]):"memory","cc");return value;}
|
||||||
|
#pragma endregion Thread Coherence
|
||||||
|
|
||||||
#define min(A,B) (((A) < (B)) ? (A) : (B))
|
#pragma region Misc
|
||||||
#define max(A,B) (((A) > (B)) ? (A) : (B))
|
enum {
|
||||||
#define clamp_bot(X,B) max(X, B) // Clamp "X" by "B"
|
Bitmask_3 = 0x00000007,
|
||||||
|
Bitmask_4 = 0x0000000f,
|
||||||
|
Bitmask_5 = 0x0000001f,
|
||||||
|
Bitmask_6 = 0x0000003f,
|
||||||
|
Bitmask_10 = 0x000003ff,
|
||||||
|
};
|
||||||
|
|
||||||
#define clamp_decrement(X) (((X) > 0) ? ((X) - 1) : 0)
|
typedef Enum_(U4, WeekDay) {
|
||||||
|
WeekDay_Sun,
|
||||||
|
WeekDay_Mon,
|
||||||
|
WeekDay_Tue,
|
||||||
|
WeekDay_Wed,
|
||||||
|
WeekDay_Thu,
|
||||||
|
WeekDay_Fri,
|
||||||
|
WeekDay_Sat,
|
||||||
|
WeekDay_Num,
|
||||||
|
};
|
||||||
|
|
||||||
typedef Struct_(R1_U1){ U1 p0; U1 p1; };
|
typedef Enum_(U4, Month) {
|
||||||
typedef Struct_(R1_U2){ U2 p0; U2 p1; };
|
Month_Jan,
|
||||||
typedef Struct_(R1_U4){ U4 p0; U2 p4; };
|
Month_Feb,
|
||||||
typedef Struct_(R1_U8){ U8 p0; U8 p4; };
|
Month_Mar,
|
||||||
|
Month_Apr,
|
||||||
|
Month_May,
|
||||||
|
Month_Jun,
|
||||||
|
Month_Jul,
|
||||||
|
Month_Aug,
|
||||||
|
Month_Sep,
|
||||||
|
Month_Oct,
|
||||||
|
Month_Nov,
|
||||||
|
Month_Dec,
|
||||||
|
Month_Num,
|
||||||
|
};
|
||||||
|
|
||||||
typedef Struct_(V2_U1){ U1 x; U1 y;};
|
typedef U8 DenseTime;
|
||||||
|
|
||||||
FI_ B8 add_of (U8 a, U8 b, U8*R_ res) { return __builtin_uaddll_overflow(a, b, res); }
|
typedef Struct_(DateTime) {
|
||||||
FI_ B8 sub_of (U8 a, U8 b, U8*R_ res) { return __builtin_usubll_overflow(a, b, res); }
|
U4 micro_sec; // [0,999]
|
||||||
FI_ B8 mul_of (U8 a, U8 b, U8*R_ res) { return __builtin_umulll_overflow(a, b, res); }
|
U4 msec; // [0,999]
|
||||||
FI_ B8 add_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_saddll_overflow(a, b, res); }
|
U4 sec; // [0,60]
|
||||||
FI_ B8 sub_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_ssubll_overflow(a, b, res); }
|
U4 min; // [0,59]
|
||||||
FI_ B8 mul_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_smulll_overflow(a, b, res); }
|
U4 hour; // [0,24]
|
||||||
#pragma endregion Math
|
U4 day; // [0,30]
|
||||||
|
WeekDay week_day;
|
||||||
|
Month month;
|
||||||
|
U4 year; // 1 = 1 CE, 0 = 1 BC
|
||||||
|
};
|
||||||
|
|
||||||
|
I_ DenseTime
|
||||||
|
dense_time_from_date_time(DateTime date_time) {
|
||||||
|
DenseTime result = 0;
|
||||||
|
result += date_time.year; result *= 12;
|
||||||
|
result += date_time.month; result *= 31;
|
||||||
|
result += date_time.day; result *= 24;
|
||||||
|
result += date_time.hour; result *= 60;
|
||||||
|
result += date_time.min; result *= 61;
|
||||||
|
result += date_time.sec; result *= 1000;
|
||||||
|
result += date_time.msec;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#pragma endregion Misc
|
||||||
|
|||||||
+63
-2
@@ -3,9 +3,70 @@
|
|||||||
# include "dsl.h"
|
# include "dsl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Encoding
|
typedef struct UnicodeDecode UnicodeDecode;
|
||||||
|
struct UnicodeDecode {
|
||||||
|
U4 inc;
|
||||||
|
U4 codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
RO_ global U1 utf8_class[32] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5, };
|
||||||
|
|
||||||
FI_ void u64_to_hex(U8 val, char* buf, S4 chars) {
|
FI_ void u64_to_hex(U8 val, char* buf, S4 chars) {
|
||||||
static const char hex_chars[] = "0123456789ABCDEF";
|
static const char hex_chars[] = "0123456789ABCDEF";
|
||||||
for(S1 i = chars - 1; i >= 0; --i) { buf[i] = hex_chars[val & 0xF]; val >>= 4; }
|
for(S1 i = chars - 1; i >= 0; --i) { buf[i] = hex_chars[val & 0xF]; val >>= 4; }
|
||||||
}
|
}
|
||||||
#pragma endregion Encoding
|
|
||||||
|
internal UnicodeDecode
|
||||||
|
utf8_decode(U1* str, U1 max) {
|
||||||
|
UnicodeDecode result = {1, Max_U4};
|
||||||
|
U1 byte = str[0];
|
||||||
|
U1 byte_class = utf8_class[byte >> 3];
|
||||||
|
switch(byte_class) {
|
||||||
|
case 1: { result.codepoint = byte; } break;
|
||||||
|
case 2: if (1 < max) {
|
||||||
|
U1 cont_byte = str[1];
|
||||||
|
if(utf8_class[cont_byte >> 3] == 0) {
|
||||||
|
result.codepoint = (byte & Bitmask_5) << 6;
|
||||||
|
result.codepoint |= (cont_byte & Bitmask_6);
|
||||||
|
result.inc = 2;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case 3: if(2 < max) {
|
||||||
|
U1 cont_byte[2] = {str[1], str[2]};
|
||||||
|
if ( utf8_class[cont_byte[0] >> 3] == 0
|
||||||
|
&& utf8_class[cont_byte[1] >> 3] == 0) {
|
||||||
|
result.codepoint = (byte & Bitmask_4) << 12;
|
||||||
|
result.codepoint |= ((cont_byte[0] & Bitmask_6) << 6);
|
||||||
|
result.codepoint |= (cont_byte[1] & Bitmask_6);
|
||||||
|
result.inc = 3;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 4: if(3 < max) {
|
||||||
|
U1 cont_byte[3] = {str[1], str[2], str[3]};
|
||||||
|
if ( utf8_class[cont_byte[0] >> 3] == 0
|
||||||
|
&& utf8_class[cont_byte[1] >> 3] == 0
|
||||||
|
&& utf8_class[cont_byte[2] >> 3] == 0) {
|
||||||
|
result.codepoint = (byte & Bitmask_3) << 18;
|
||||||
|
result.codepoint |= ((cont_byte[0] & Bitmask_6) << 12);
|
||||||
|
result.codepoint |= ((cont_byte[1] & Bitmask_6) << 6);
|
||||||
|
result.codepoint |= (cont_byte[2] & Bitmask_6);
|
||||||
|
result.inc = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ U4
|
||||||
|
utf16_encode(U2* str, U4 codepoint) {
|
||||||
|
U4 inc = 1;
|
||||||
|
if (codepoint == Max_U4) { str[0] = (U2)'?'; }
|
||||||
|
else if (codepoint < 0x10000) { str[0] = (U2)codepoint; }
|
||||||
|
else {
|
||||||
|
U4 v = codepoint - 0x10000;
|
||||||
|
str[0] = Csafe_u2u4(0xD800 + (v >> 10));
|
||||||
|
str[1] = Csafe_u2u4(0xDC00 + (v & Bitmask_10));
|
||||||
|
inc = 2;
|
||||||
|
}
|
||||||
|
return inc;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# pragma once
|
||||||
|
# include "dsl.h"
|
||||||
|
# include "memory.h"
|
||||||
|
# include "math.h"
|
||||||
|
# include "text.h"
|
||||||
|
#
|
||||||
|
# if DUFFLE_WINDOWS
|
||||||
|
# include "win32.h"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CLANG_OPTIMIZE_DISABLE
|
||||||
|
|
||||||
|
// Most of this referenced from the RAD Debugger codebase.
|
||||||
|
typedef Enum_(U4,AccessFlags) {
|
||||||
|
Bit_(AccessFlag_Read, 0),
|
||||||
|
Bit_(AccessFlag_Write, 1),
|
||||||
|
Bit_(AccessFlag_Execute, 2),
|
||||||
|
Bit_(AccessFlag_Append, 3),
|
||||||
|
Bit_(AccessFlag_ShareRead, 4),
|
||||||
|
Bit_(AccessFlag_ShareWrite, 5),
|
||||||
|
Bit_(AccessFlag_Inherited, 6),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef U4 FilePropertyFlags;
|
||||||
|
enum {
|
||||||
|
Bit_(FilePropertyFlag_IsFolder, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Struct_(FileProperties) {
|
||||||
|
U8 size;
|
||||||
|
DenseTime modified;
|
||||||
|
DenseTime created;
|
||||||
|
FilePropertyFlags flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Struct_(File) { U8 ptr[1]; };
|
||||||
|
|
||||||
|
FI_ File file_zero() { File f = {0}; return f; }
|
||||||
|
|
||||||
|
typedef Struct_(Scope_FileInfo) { File f; B4 once; };
|
||||||
|
|
||||||
|
FI_ B4 file_match(File a, File b) { return mem_match_struct(& a, & b); }
|
||||||
|
|
||||||
|
os_layer void file_close(File file);
|
||||||
|
os_layer File file_open(FArena* scratch, AccessFlags flags, Str8 path);
|
||||||
|
#define file_scope(scratch, flags, path) scope_info(Scope_FileInfo, {.f = file_open(scratch, flags, path)}, file_close(info.f))
|
||||||
|
|
||||||
|
os_layer FileProperties properties_from_file(File file);
|
||||||
|
os_layer U8 file_read(File file, R1_U8 rng, U1* out_data);
|
||||||
|
|
||||||
|
internal Slice_U1
|
||||||
|
data_from_file_range(FArena* arena, File file, R1_U8 range) {
|
||||||
|
U8 pre_pos = farena_save(arena[0]);
|
||||||
|
U8 len = span_r1u8(range);
|
||||||
|
Slice_U1 result = farena_push_array(arena, U1, len);
|
||||||
|
U8 actual_read_size = file_read(file, range, result.ptr); if (actual_read_size < result.len) {
|
||||||
|
farena_rewind(arena, pre_pos + actual_read_size); result.len = actual_read_size;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ Slice_U1
|
||||||
|
data_from_file_path(FArena* arena, Str8 path, FArena* scratch) { file_scope(scratch, AccessFlag_Read | AccessFlag_ShareRead, path) {
|
||||||
|
FileProperties props = properties_from_file(info.f);
|
||||||
|
Slice_U1 data = data_from_file_range(arena, info.f, r1u8(0, props.size)); return data;
|
||||||
|
} unreachable(); }
|
||||||
|
|
||||||
|
CLANG_OPTIMIZE_ENABLE
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
# pragma once
|
# pragma once
|
||||||
# include "dsl.h"
|
# include "dsl.h"
|
||||||
# include "memory.h"
|
# include "memory.h"
|
||||||
|
# include "analysis.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Hashing
|
#pragma region Hashing
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# pragma once
|
||||||
|
# include "dsl.h"
|
||||||
|
# include "analysis.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma region Math
|
||||||
|
#define u8_max 0xffffffffffffffffull
|
||||||
|
|
||||||
|
#define min(A,B) (((A) < (B)) ? (A) : (B))
|
||||||
|
#define max(A,B) (((A) > (B)) ? (A) : (B))
|
||||||
|
#define clamp_bot(X,B) max(X, B) // Clamp "X" by "B"
|
||||||
|
|
||||||
|
#define clamp_decrement(X) (((X) > 0) ? ((X) - 1) : 0)
|
||||||
|
|
||||||
|
typedef Struct_(R1_U1){ U1 p0; U1 p1; };
|
||||||
|
typedef Struct_(R1_U2){ U2 p0; U2 p1; };
|
||||||
|
typedef Struct_(R1_U4){ U4 p0; U2 p1; };
|
||||||
|
typedef Struct_(R1_U8){ U8 p0; U8 p1; };
|
||||||
|
|
||||||
|
#define r1u4(p0,p1) (R1_U4){p0,p1}
|
||||||
|
#define r1u8(p0,p1) (R1_U8){p0,p1}
|
||||||
|
|
||||||
|
typedef Struct_(V2_U1){ U1 x; U1 y;};
|
||||||
|
|
||||||
|
FI_ B8 add_of (U8 a, U8 b, U8*R_ res) { return __builtin_uaddll_overflow(a, b, res); }
|
||||||
|
FI_ B8 sub_of (U8 a, U8 b, U8*R_ res) { return __builtin_usubll_overflow(a, b, res); }
|
||||||
|
FI_ B8 mul_of (U8 a, U8 b, U8*R_ res) { return __builtin_umulll_overflow(a, b, res); }
|
||||||
|
FI_ B8 add_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_saddll_overflow(a, b, res); }
|
||||||
|
FI_ B8 sub_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_ssubll_overflow(a, b, res); }
|
||||||
|
FI_ B8 mul_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_smulll_overflow(a, b, res); }
|
||||||
|
|
||||||
|
FI_ U8 span_r1u8(R1_U8 r) {U8 c = ((r.p1 > r.p0) ? (r.p1 - r.p0) : 0); return c;}
|
||||||
|
#pragma endregion Math
|
||||||
|
|
||||||
|
#pragma region Numerics
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Max_U4 = 0xffffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
FI_ U2 Csafe_u2u4(U4 x) { assert_always(x <= Max_U4); return C_(U2, x); }
|
||||||
|
#pragma endregion Numerics
|
||||||
+15
-6
@@ -33,6 +33,11 @@ FI_ U8 mem_copy_overlapping(U8 dest, U8 src, U8 len) { return (U8)(__builtin_m
|
|||||||
FI_ U8 mem_fill (U8 dest, U8 value, U8 len) { return (U8)(__builtin_memset ((void*)dest, (int) value, len)); }
|
FI_ U8 mem_fill (U8 dest, U8 value, U8 len) { return (U8)(__builtin_memset ((void*)dest, (int) value, len)); }
|
||||||
FI_ B4 mem_zero (U8 dest, U8 len) { if(dest == 0){return false;} mem_fill(dest, 0, len); return true; }
|
FI_ B4 mem_zero (U8 dest, U8 len) { if(dest == 0){return false;} mem_fill(dest, 0, len); return true; }
|
||||||
|
|
||||||
|
FI_ U8 mem_compare(U8 a, U8 b, U8 len) { return (U8)(__builtin_memcmp((void const*)a, (void const*)b, len)); }
|
||||||
|
FI_ B4 mem_match (U8 a, U8 b, U8 z) { return mem_compare(a, b, z) == 0; }
|
||||||
|
|
||||||
|
#define mem_match_struct(a,b) mem_match(C_(U8,a), C_(U8,b), S_((a)[0]))
|
||||||
|
|
||||||
#pragma region DAG
|
#pragma region DAG
|
||||||
|
|
||||||
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
|
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
|
||||||
@@ -63,22 +68,22 @@ typedef Struct_(Str8) { UTF8* ptr; U8 len; };
|
|||||||
typedef Str8 Slice_UTF8;
|
typedef Str8 Slice_UTF8;
|
||||||
typedef Struct_(Slice_Str8) { Str8* ptr; U8 len; };
|
typedef Struct_(Slice_Str8) { Str8* ptr; U8 len; };
|
||||||
#define slit8(string_literal) (Str8){ (UTF8*) string_literal, S_(string_literal) - 1 }
|
#define slit8(string_literal) (Str8){ (UTF8*) string_literal, S_(string_literal) - 1 }
|
||||||
|
#define str8(p,l) (Str8){p,l}
|
||||||
|
|
||||||
typedef Struct_(Slice) { U8 ptr; U8 len; }; // Untyped Slice
|
typedef Struct_(Slice) { U8 ptr; U8 len; }; // Untyped Slice
|
||||||
FI_ Slice slice_ut_(U8 ptr, U8 len) { return (Slice){ptr, len}; }
|
FI_ Slice slice_ut_(U8 ptr, U8 len) { return (Slice){ptr, len}; }
|
||||||
|
|
||||||
#define Slice_(type) Struct_(tmpl(Slice,type)) { type* ptr; U8 len; }
|
#define Slice_(type) Struct_(tmpl(Slice,type)) { type* ptr; U8 len; }
|
||||||
typedef Slice_(B1);
|
|
||||||
#define slice_assert(s) do { assert((s).ptr != 0); assert((s).len > 0); } while(0)
|
#define slice_assert(s) do { assert((s).ptr != 0); assert((s).len > 0); } while(0)
|
||||||
#define slice_end(slice) ((slice).ptr + (slice).len)
|
#define slice_end(slice) ((slice).ptr + (slice).len)
|
||||||
#define S_slice(s) ((s).len * S_((s).ptr[0]))
|
#define S_slice(s) ((s).len * S_((s).ptr[0]))
|
||||||
|
|
||||||
#define slice_ut(ptr,len) slice_ut_(u4_(ptr), u4_(len))
|
#define slice_ut(ptr,len) slice_ut_(u8_(ptr), u8_(len))
|
||||||
#define slice_ut_arr(a) slice_ut_(u4_(a), S_(a))
|
#define slice_ut_arr(a) slice_ut_(u8_(a), S_(a))
|
||||||
#define slice_to_ut(s) slice_ut_(u4_((s).ptr), S_slice(s))
|
#define slice_to_ut(s) slice_ut_(u8_((s).ptr), S_slice(s))
|
||||||
|
|
||||||
#define slice_iter(container, iter) (T_((container).ptr) iter = (container).ptr; iter != slice_end(container); ++ iter)
|
#define slice_iter(container, iter) (T_((container).ptr) iter = (container).ptr; iter != slice_end(container); ++ iter)
|
||||||
#define slice_arg_from_array(type, ...) & (tmpl(Slice,type)) { .ptr = array_decl(type,__VA_ARGS__), .len = array_len( array_decl(type,__VA_ARGS__)) }
|
#define slice_arg_from_array(type, ...) & (tmpl(Slice,type)) { .ptr = Array_decl(type,__VA_ARGS__), .len = Array_len( Array_decl(type,__VA_ARGS__)) }
|
||||||
#define slice_from_array(type, array) (tmpl(Slice,type)) { .ptr = array, .len = S_(array) }
|
#define slice_from_array(type, array) (tmpl(Slice,type)) { .ptr = array, .len = S_(array) }
|
||||||
|
|
||||||
FI_ void slice_zero_(Slice s) { slice_assert(s); mem_zero(s.ptr, s.len); }
|
FI_ void slice_zero_(Slice s) { slice_assert(s); mem_zero(s.ptr, s.len); }
|
||||||
@@ -91,11 +96,15 @@ FI_ void slice_copy_(Slice dest, Slice src) {
|
|||||||
mem_copy(dest.ptr, src.ptr, src.len);
|
mem_copy(dest.ptr, src.ptr, src.len);
|
||||||
}
|
}
|
||||||
#define slice_copy(dest, src) do { \
|
#define slice_copy(dest, src) do { \
|
||||||
static_assert(T_same(dest, src)); \
|
static_assert(T_same(dest, src), "slices are not the same type"); \
|
||||||
slice_copy_(slice_to_ut(dest), slice_to_ut(src)); \
|
slice_copy_(slice_to_ut(dest), slice_to_ut(src)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
typedef Slice_(B1);
|
||||||
|
typedef Slice_(U1);
|
||||||
|
typedef Slice_(U2);
|
||||||
typedef Slice_(U4);
|
typedef Slice_(U4);
|
||||||
|
typedef Slice_(U8);
|
||||||
|
|
||||||
#pragma endregion Slice
|
#pragma endregion Slice
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
# include "dsl.h"
|
# include "dsl.h"
|
||||||
# include "memory.h"
|
# include "memory.h"
|
||||||
# include "hashing.h"
|
# include "hashing.h"
|
||||||
|
# include "analysis.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Key Table Linear (KTL)
|
#pragma region Key Table Linear (KTL)
|
||||||
|
|||||||
+30
-1
@@ -2,12 +2,14 @@
|
|||||||
# pragma once
|
# pragma once
|
||||||
# include "dsl.h"
|
# include "dsl.h"
|
||||||
# include "memory.h"
|
# include "memory.h"
|
||||||
|
# include "encoding.h"
|
||||||
# include "hashing.h"
|
# include "hashing.h"
|
||||||
# include "tables.h"
|
# include "tables.h"
|
||||||
|
# include "analysis.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE(rjf): Includes reverses for uppercase and lowercase hex.
|
// NOTE(rjf): Includes reverses for uppercase and lowercase hex.
|
||||||
RO_ global U8 integer_symbol_reverse[128] = {
|
RO_ U8 integer_symbol_reverse[128] = {
|
||||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||||
@@ -203,3 +205,30 @@ FI_ void str8gen_append_fmt(Str8Gen_R gen, Str8 fmt, KTL_Str8 tbl) {
|
|||||||
gen->len += result.len;
|
gen->len += result.len;
|
||||||
}
|
}
|
||||||
#define str8gen_append_str8_(gen, s) str8gen_append_str8(gen, str8(s))
|
#define str8gen_append_str8_(gen, s) str8gen_append_str8(gen, str8(s))
|
||||||
|
|
||||||
|
// Dealing with Wides (UTF16)
|
||||||
|
|
||||||
|
typedef U4 UTF16;
|
||||||
|
typedef Struct_(Str16) { UTF16* ptr; U8 len; };
|
||||||
|
typedef Str16 Slice_UTF16;
|
||||||
|
#define str16(p,l) (Str16){p,l}
|
||||||
|
|
||||||
|
internal Str16
|
||||||
|
str16_from_8(FArena* arena, Str8 in) {
|
||||||
|
Str16 result = {0}; if (in.len) {
|
||||||
|
U8 cap = in.len * 2;
|
||||||
|
Slice_U2 str = farena_push_array(arena, U2, cap + 1);
|
||||||
|
U1* ptr = in.ptr;
|
||||||
|
U1* opl = ptr + in.len;
|
||||||
|
U8 size = 0;
|
||||||
|
UnicodeDecode consume;
|
||||||
|
for(;ptr < opl; ptr += consume.inc)
|
||||||
|
{
|
||||||
|
consume = utf8_decode(ptr, opl - ptr);
|
||||||
|
size += utf16_encode(str.ptr + size, consume.codepoint);
|
||||||
|
}
|
||||||
|
str.ptr[size] = 0; farena_rewind(arena, (cap - size) * 2);
|
||||||
|
result = str16(C_(UTF16*, str.ptr), size);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
+171
-13
@@ -17,6 +17,50 @@ typedef Struct_(MS_Handle){U8 id;};
|
|||||||
#pragma endregion IO
|
#pragma endregion IO
|
||||||
|
|
||||||
// --- WinAPI Minimal Definitions ---
|
// --- WinAPI Minimal Definitions ---
|
||||||
|
typedef Struct_(MS_OVERLAPPED) {
|
||||||
|
void* Internal;
|
||||||
|
void* InternalHigh;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
U4 Offset;
|
||||||
|
U4 OffsetHigh;
|
||||||
|
};
|
||||||
|
void* Pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
MS_Handle hEvent;
|
||||||
|
};
|
||||||
|
typedef Struct_(MS_SECURITY_ATTRIBUTES) {
|
||||||
|
U4 nLength;
|
||||||
|
void* lpSecurityDescriptor;
|
||||||
|
B4 bInheritHandle;
|
||||||
|
};
|
||||||
|
typedef struct MS_SYSTEMTIME {
|
||||||
|
U2 wYear;
|
||||||
|
U2 wMonth;
|
||||||
|
U2 wDayOfWeek;
|
||||||
|
U2 wDay;
|
||||||
|
U2 wHour;
|
||||||
|
U2 wMinute;
|
||||||
|
U2 wSecond;
|
||||||
|
U2 wMilliseconds;
|
||||||
|
} MS_SYSTEMTIME;
|
||||||
|
typedef struct MS_FILETIME {
|
||||||
|
U4 dwLowDateTime;
|
||||||
|
U4 dwHighDateTime;
|
||||||
|
} MS_FILETIME;
|
||||||
|
typedef struct MS_BY_HANDLE_FILE_INFORMATION {
|
||||||
|
U4 dwFileAttributes;
|
||||||
|
MS_FILETIME ftCreationTime;
|
||||||
|
MS_FILETIME ftLastAccessTime;
|
||||||
|
MS_FILETIME ftLastWriteTime;
|
||||||
|
U4 dwVolumeSerialNumber;
|
||||||
|
U4 nFileSizeHigh;
|
||||||
|
U4 nFileSizeLow;
|
||||||
|
U4 nNumberOfLinks;
|
||||||
|
U4 nFileIndexHigh;
|
||||||
|
U4 nFileIndexLow;
|
||||||
|
} MS_BY_HANDLE_FILE_INFORMATION;
|
||||||
typedef struct MS_WNDCLASSA {
|
typedef struct MS_WNDCLASSA {
|
||||||
U4 style;
|
U4 style;
|
||||||
S8 (*lpfnWndProc)(void*, U4, U8, S8);
|
S8 (*lpfnWndProc)(void*, U4, U8, S8);
|
||||||
@@ -35,6 +79,7 @@ typedef struct MS_RECT { S4 left, top, right, bottom; } MS_RECT;
|
|||||||
typedef struct MS_PAINTSTRUCT { void* hdc; S4 fErase; MS_RECT rcPaint; S4 fRestore; S4 fIncUpdate; U1 rgbReserved[32]; } MS_PAINTSTRUCT;
|
typedef struct MS_PAINTSTRUCT { void* hdc; S4 fErase; MS_RECT rcPaint; S4 fRestore; S4 fIncUpdate; U1 rgbReserved[32]; } MS_PAINTSTRUCT;
|
||||||
|
|
||||||
// --- Kernel32 ---
|
// --- Kernel32 ---
|
||||||
|
WinAPI U4 ms_get_last_error() asm("GetLastError");
|
||||||
WinAPI void ms_exit_process(U4 uExitCode) asm("ExitProcess");
|
WinAPI void ms_exit_process(U4 uExitCode) asm("ExitProcess");
|
||||||
WinAPI MS_Handle ms_get_std_handle(U4 handle_type) asm("GetStdHandle");
|
WinAPI MS_Handle ms_get_std_handle(U4 handle_type) asm("GetStdHandle");
|
||||||
WinAPI void* ms_virtual_alloc(void* lpAddress, U8 dwSize, U4 flAllocationType, U4 flProtect) asm("VirtualAlloc");
|
WinAPI void* ms_virtual_alloc(void* lpAddress, U8 dwSize, U4 flAllocationType, U4 flProtect) asm("VirtualAlloc");
|
||||||
@@ -52,6 +97,13 @@ WinAPI B4 ms_write_console(
|
|||||||
U4_V chars_written,
|
U4_V chars_written,
|
||||||
U8 reserved
|
U8 reserved
|
||||||
) asm("WriteConsoleA");
|
) asm("WriteConsoleA");
|
||||||
|
WinAPI B4 ms_get_file_information_by_handle(MS_Handle* handle, MS_BY_HANDLE_FILE_INFORMATION* file_information) asm("GetFileInformationByHandle");
|
||||||
|
WinAPI MS_Handle* ms_create_file_a(char const* lpFileName, U4 dwDesiredAccess, U4 dwShareMode, void* lpSecurityAttributes, U4 dwCreationDisposition, U4 dwFlagsAndAttributes, void* hTemplateFile) asm("CreateFileA");
|
||||||
|
WinAPI MS_Handle* ms_create_file_w(U2 const* lpFileName, U4 dwDesiredAccess, U4 dwShareMode, void* lpSecurityAttributes, U4 dwCreationDisposition, U4 dwFlagsAndAttributes, void* hTemplateFile) asm("CreateFileW");
|
||||||
|
WinAPI B4 ms_write_file(void* hFile, void const* lpBuffer, U4 nNumberOfBytesToWrite, U4* lpNumberOfBytesWritten, void* lpOverlapped) asm("WriteFile");
|
||||||
|
WinAPI B4 ms_read_file(MS_Handle* hFile, void* lpBuffer, U4 nNumberOfBytesToRead, U4* lpNumberOfBytesRead, void* lpOverlapped) asm("ReadFile");
|
||||||
|
WinAPI B4 ms_close_handle(void* hObject) asm("CloseHandle");
|
||||||
|
WinAPI B4 ms_filetime_to_systemtime(void const* lpFileTime, void* lpSystemTime) asm("FileTimeToSystemTime");
|
||||||
|
|
||||||
// --- User32 ---
|
// --- User32 ---
|
||||||
WinAPI U2 ms_register_class_a(MS_WNDCLASSA const* lpWndClass) asm("RegisterClassA");
|
WinAPI U2 ms_register_class_a(MS_WNDCLASSA const* lpWndClass) asm("RegisterClassA");
|
||||||
@@ -112,11 +164,28 @@ WinAPI S4 ms_set_bk_mode(void* hdc, S4 mode) asm("
|
|||||||
WinAPI void* ms_create_solid_brush(U4 color) asm("CreateSolidBrush");
|
WinAPI void* ms_create_solid_brush(U4 color) asm("CreateSolidBrush");
|
||||||
WinAPI S4 ms_delete_object(void* ho) asm("DeleteObject");
|
WinAPI S4 ms_delete_object(void* ho) asm("DeleteObject");
|
||||||
|
|
||||||
|
#define MS_INVALID_HANDLE_VALUE ((MS_Handle*)(U8) - 1)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
MS_GENERIC_READ = 0x80000000,
|
||||||
|
MS_GENERIC_WRITE = 0x40000000,
|
||||||
|
MS_GENERIC_EXECUTE = 0x20000000L,
|
||||||
|
MS_CREATE_ALWAYS = 2,
|
||||||
|
MS_OPEN_EXISTING = 3,
|
||||||
|
MS_OPEN_ALWAYS = 4,
|
||||||
|
|
||||||
|
MS_FILE_APPEND_DATA = 0x0004,
|
||||||
|
MS_FILE_ATTRIBUTE_NORMAL = 0x80,
|
||||||
|
MS_FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
|
||||||
|
MS_FILE_SHARE_READ = 0x00000001,
|
||||||
|
MS_FILE_SHARE_WRITE = 0x00000002,
|
||||||
|
MS_FILE_SHARE_DELETE = 0x00000004,
|
||||||
|
|
||||||
MS_MEM_COMMIT = 0x00001000,
|
MS_MEM_COMMIT = 0x00001000,
|
||||||
MS_MEM_RESERVE = 0x00002000,
|
MS_MEM_RESERVE = 0x00002000,
|
||||||
MS_PAGE_READWRITE = 0x04,
|
MS_PAGE_READWRITE = 0x04,
|
||||||
MS_SRCCOPY = 0x00CC0020,
|
MS_SRCCOPY = 0x00CC0020,
|
||||||
|
|
||||||
MS_WM_DESTROY = 0x0002,
|
MS_WM_DESTROY = 0x0002,
|
||||||
MS_WM_SIZE = 0x0005,
|
MS_WM_SIZE = 0x0005,
|
||||||
MS_WM_PAINT = 0x000F,
|
MS_WM_PAINT = 0x000F,
|
||||||
@@ -133,26 +202,115 @@ enum {
|
|||||||
MS_WM_MOUSEWHEEL = 0x020A,
|
MS_WM_MOUSEWHEEL = 0x020A,
|
||||||
MS_WS_OVERLAPPEDWINDOW = 0x00CF0000,
|
MS_WS_OVERLAPPEDWINDOW = 0x00CF0000,
|
||||||
MS_WS_VISIBLE = 0x10000000,
|
MS_WS_VISIBLE = 0x10000000,
|
||||||
|
|
||||||
|
MS_PAGE_EXECUTE_READWRITE = 0x40,
|
||||||
|
|
||||||
|
MS_VK_BACK = 0x08,
|
||||||
|
MS_VK_TAB = 0x09,
|
||||||
|
MS_VK_RETURN = 0x0D,
|
||||||
|
MS_VK_SHIFT =0x10,
|
||||||
|
MS_VK_SPACE = 0x20,
|
||||||
|
MS_VK_PRIOR = 0x21,
|
||||||
|
MS_VK_NEXT = 0x22,
|
||||||
MS_VK_LEFT = 0x25,
|
MS_VK_LEFT = 0x25,
|
||||||
MS_VK_UP = 0x26,
|
MS_VK_UP = 0x26,
|
||||||
MS_VK_RIGHT = 0x27,
|
MS_VK_RIGHT = 0x27,
|
||||||
MS_VK_DOWN = 0x28,
|
MS_VK_DOWN = 0x28,
|
||||||
|
MS_VK_F1 = 0x70,
|
||||||
MS_PAGE_EXECUTE_READWRITE = 0x40,
|
MS_VK_F2 = 0x71,
|
||||||
|
|
||||||
MS_WM_CHAR = 0x0102,
|
|
||||||
MS_VK_RETURN = 0x0D,
|
|
||||||
MS_VK_BACK = 0x08,
|
|
||||||
MS_VK_TAB = 0x09,
|
|
||||||
MS_VK_SPACE = 0x20,
|
|
||||||
MS_VK_F5 = 0x74,
|
MS_VK_F5 = 0x74,
|
||||||
MS_VK_PRIOR = 0x21,
|
MS_WM_CHAR = 0x0102,
|
||||||
MS_VK_NEXT = 0x22,
|
|
||||||
|
|
||||||
MS_VK_SHIFT =0x10,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
FI_ void assert(U8 cond) { if(cond){return;} else{debug_trap(); ms_exit_process(1);} }
|
FI_ void assert(U8 cond) { if(cond){return;} else{debug_trap(); ms_exit_process(1);} }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Layer Implementation
|
||||||
|
|
||||||
|
|
||||||
|
#if DUFFLE_WINDOWS
|
||||||
|
I_ void
|
||||||
|
w32_date_time_from_system_time(DateTime* out, MS_SYSTEMTIME* in) {
|
||||||
|
out->year = in->wYear;
|
||||||
|
out->month = in->wMonth - 1;
|
||||||
|
out->week_day = in->wDayOfWeek;
|
||||||
|
out->day = in->wDay;
|
||||||
|
out->hour = in->wHour;
|
||||||
|
out->min = in->wMinute;
|
||||||
|
out->sec = in->wSecond;
|
||||||
|
out->msec = in->wMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ void
|
||||||
|
w32_dense_time_from_file_time(DenseTime* out, MS_FILETIME* in) {
|
||||||
|
MS_SYSTEMTIME systime = {0}; ms_filetime_to_systemtime(in, &systime); DateTime date_time = {0};
|
||||||
|
w32_date_time_from_system_time(&date_time, &systime); *out = dense_time_from_date_time(date_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ FilePropertyFlags
|
||||||
|
w32_file_property_flags_from_dwFileAttributes(U4 dwFileAttributes) {
|
||||||
|
FilePropertyFlags flags = 0; if (dwFileAttributes & MS_FILE_ATTRIBUTE_DIRECTORY) { flags |= FilePropertyFlag_IsFolder; } return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ FileProperties
|
||||||
|
properties_from_file(File file) {
|
||||||
|
if (file_match(file, file_zero())) { FileProperties r = {0}; return r; }
|
||||||
|
FileProperties props = {0}; MS_Handle* handle = C_(MS_Handle*,file.ptr[0]);
|
||||||
|
MS_BY_HANDLE_FILE_INFORMATION info; S4 info_good = ms_get_file_information_by_handle(handle, &info);
|
||||||
|
if (info_good) {
|
||||||
|
U4 size_lo = info.nFileSizeLow; U4 size_hi = info.nFileSizeHigh;
|
||||||
|
props.size = C_(U8,size_lo) | (C_(U8,size_hi)<<32);
|
||||||
|
w32_dense_time_from_file_time(& props.modified, & info.ftLastWriteTime);
|
||||||
|
w32_dense_time_from_file_time(& props.created, & info.ftCreationTime);
|
||||||
|
props.flags = w32_file_property_flags_from_dwFileAttributes(info.dwFileAttributes);
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal File
|
||||||
|
file_open(FArena* scratch, AccessFlags flags, Str8 path) {
|
||||||
|
File result = {0};
|
||||||
|
Str16 path16 = str16_from_8(scratch, path);
|
||||||
|
U4 access_flags = 0;
|
||||||
|
U4 share_mode = 0;
|
||||||
|
U4 creation_disposition = MS_OPEN_EXISTING;
|
||||||
|
MS_SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0};
|
||||||
|
if (flags & AccessFlag_Read) { access_flags |= MS_GENERIC_READ; }
|
||||||
|
if (flags & AccessFlag_Write) { access_flags |= MS_GENERIC_WRITE; }
|
||||||
|
if (flags & AccessFlag_Execute) { access_flags |= MS_GENERIC_EXECUTE; }
|
||||||
|
if (flags & AccessFlag_ShareRead) { share_mode |= MS_FILE_SHARE_READ; }
|
||||||
|
if (flags & AccessFlag_ShareWrite) { share_mode |= MS_FILE_SHARE_WRITE | MS_FILE_SHARE_DELETE; }
|
||||||
|
if (flags & AccessFlag_Write) { creation_disposition = MS_CREATE_ALWAYS; }
|
||||||
|
if (flags & AccessFlag_Append) { creation_disposition = MS_OPEN_ALWAYS; access_flags |= MS_FILE_APPEND_DATA; }
|
||||||
|
if (flags & AccessFlag_Inherited) { security_attributes.bInheritHandle = 1; }
|
||||||
|
MS_Handle* file = ms_create_file_w(C_(U2 const*,path16.ptr), access_flags, share_mode, &security_attributes, creation_disposition, MS_FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
if(file != MS_INVALID_HANDLE_VALUE) { result.ptr[0] = C_(U8,file); }
|
||||||
|
else {
|
||||||
|
U4 err = ms_get_last_error(); (void)err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void file_close(File file) {
|
||||||
|
if(file_match(file, file_zero())) { return; }
|
||||||
|
MS_Handle* handle = C_(MS_Handle*,file.ptr[0]);
|
||||||
|
B4 result = ms_close_handle(handle); (void)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal U8 file_read(File file, R1_U8 rng, U1* out_data) {
|
||||||
|
if (file_match(file, file_zero())) { return 0; }
|
||||||
|
MS_Handle* handle = C_(MS_Handle*,file.ptr[0]);
|
||||||
|
U1* ptr = out_data;
|
||||||
|
U8 off = rng.p0; while (off != rng.p1) {
|
||||||
|
U8 amt64 = rng.p1 - off;
|
||||||
|
U4 amt32 = C_(U4, min(mega(32), amt64));
|
||||||
|
U4 read_size = 0;
|
||||||
|
MS_OVERLAPPED overlapped = { .Offset = C_(U4,off), .OffsetHigh = (U4)(off >> 32) };
|
||||||
|
if( ! ms_read_file(handle, ptr, amt32, &read_size, &overlapped)) { break; }
|
||||||
|
ptr += read_size;
|
||||||
|
off += read_size;
|
||||||
|
}
|
||||||
|
U8 total_read_size = off - rng.p0; return total_read_size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,10 +1,88 @@
|
|||||||
#include "duffle/dsl.h"
|
#include "duffle/dsl.h"
|
||||||
#include "duffle/analysis.h"
|
#include "duffle/analysis.h"
|
||||||
|
#include "duffle/math.h"
|
||||||
#include "duffle/memory.h"
|
#include "duffle/memory.h"
|
||||||
|
#include "duffle/hashing.h"
|
||||||
|
#include "duffle/encoding.h"
|
||||||
|
#include "duffle/tables.h"
|
||||||
|
#include "duffle/text.h"
|
||||||
|
#include "duffle/files.h"
|
||||||
|
|
||||||
#include "duffle/win32.h"
|
#include "duffle/win32.h"
|
||||||
|
|
||||||
|
typedef Struct_(U2_HL) { U1 Low; U1 High; };
|
||||||
|
|
||||||
|
#define bitmask_(pos) (1 << pos)
|
||||||
|
#define bit_isolate(bitfield, pos) (bitmask_(pos) & value)
|
||||||
|
|
||||||
|
#define serialize_bit(bitfield, pos) (bit_isolate(bitfield, pos) == bitmask_(pos) ? '1' : '0')
|
||||||
|
|
||||||
|
typedef Enum_(U4, Endieaness) {
|
||||||
|
Little,
|
||||||
|
Big,
|
||||||
|
};
|
||||||
|
|
||||||
|
FI_ void a8utf8_from_u1_le(UTF8 out[8], U1 value) {
|
||||||
|
out[0] = serialize_bit(value, 7);
|
||||||
|
out[1] = serialize_bit(value, 6);
|
||||||
|
out[2] = serialize_bit(value, 5);
|
||||||
|
out[3] = serialize_bit(value, 4);
|
||||||
|
out[4] = serialize_bit(value, 3);
|
||||||
|
out[5] = serialize_bit(value, 2);
|
||||||
|
out[6] = serialize_bit(value, 1);
|
||||||
|
out[7] = serialize_bit(value, 0);
|
||||||
|
}
|
||||||
|
FI_ void a8utf8_from_u1_be(UTF8 out[8], U1 value) {
|
||||||
|
out[0] = serialize_bit(value, 0);
|
||||||
|
out[1] = serialize_bit(value, 1);
|
||||||
|
out[2] = serialize_bit(value, 2);
|
||||||
|
out[3] = serialize_bit(value, 3);
|
||||||
|
out[4] = serialize_bit(value, 4);
|
||||||
|
out[5] = serialize_bit(value, 5);
|
||||||
|
out[6] = serialize_bit(value, 6);
|
||||||
|
out[7] = serialize_bit(value, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ U4 binary_as_str8_eval_len(Slice_U1 data) { return data.len * 8; }
|
||||||
|
|
||||||
|
#define jump_lt(a,b,label) if (a < b) goto label
|
||||||
|
|
||||||
|
I_ Str8 binary_as_str8(Slice_U1 data, FArena* str8_mem) { Str8 result = {0};
|
||||||
|
U4 req_len = data.len * 8; jump_lt(str8_mem->capacity,req_len, jret);
|
||||||
|
result = farena_push_array(str8_mem, UTF8, req_len);
|
||||||
|
for index_iter(U4,cursor, 0,<,req_len) { a8utf8_from_u1_le(result.ptr + cursor, data.ptr[cursor]); }
|
||||||
|
jret: return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Enum_(U4, x86_Op) {
|
||||||
|
x86_mov
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Scratchpad_Len = kilo(1),
|
||||||
|
FileRam_Len = kilo(16),
|
||||||
|
};
|
||||||
|
typedef Struct_(SMemory) {
|
||||||
|
U1 Scratchpad [Scratchpad_Len];
|
||||||
|
U1 FileRam [FileRam_Len];
|
||||||
|
};
|
||||||
|
global SMemory smem;
|
||||||
|
|
||||||
|
#define path_course_content "./course_content/perfaware/"
|
||||||
|
#define path_part1 path_course_content "part1/"
|
||||||
|
|
||||||
|
CLANG_OPTIMIZE_DISABLE
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
FArena scratch = farena_make(slice_ut_arr(smem.Scratchpad));
|
||||||
|
FArena file_arena = farena_make(slice_ut_arr(smem.FileRam));
|
||||||
|
|
||||||
|
Str8 path_listing_0037_single_register_mov = slit8(path_part1 "listing_0037_single_register_mov");
|
||||||
|
Str8 path_listing_0037_single_register_mov_asm = slit8(path_part1 "listing_0037_single_register_mov.asm");
|
||||||
|
Slice_U1 data = data_from_file_path(& file_arena, path_listing_0037_single_register_mov, & scratch);
|
||||||
|
|
||||||
ms_exit_process(0);
|
ms_exit_process(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
CLANG_OPTIMIZE_ENABLE
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 451 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
// raddbg 0.9.28 project file
|
||||||
|
|
||||||
|
target:
|
||||||
|
{
|
||||||
|
executable: "build/sim_8086.exe"
|
||||||
|
working_directory: ""
|
||||||
|
enabled: 1
|
||||||
|
label: "Sim 8086"
|
||||||
|
}
|
||||||
+10
-3
@@ -278,6 +278,7 @@ $libraries_win32 = @(
|
|||||||
'kernel32.lib'
|
'kernel32.lib'
|
||||||
'user32.lib'
|
'user32.lib'
|
||||||
'gdi32.lib'
|
'gdi32.lib'
|
||||||
|
'vcruntime.lib'
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- Functions ---
|
# --- Functions ---
|
||||||
@@ -291,11 +292,12 @@ function compile-unit {
|
|||||||
)
|
)
|
||||||
$compile_args = @()
|
$compile_args = @()
|
||||||
$compile_args += $f_std_c11
|
$compile_args += $f_std_c11
|
||||||
|
$compile_args += $f_all_c
|
||||||
|
$compile_args += $f_ms_ex
|
||||||
$compile_args += $f_wall
|
$compile_args += $f_wall
|
||||||
$compile_args += $f_wno_attributes
|
$compile_args += $f_wno_attributes
|
||||||
$compile_args += $f_exceptions_disabled
|
$compile_args += $f_exceptions_disabled
|
||||||
$compile_args += $f_diagnostics_absolute
|
$compile_args += $f_diagnostics_absolute
|
||||||
$compile_args += $f_optimize_none
|
|
||||||
$compile_args += $f_debug
|
$compile_args += $f_debug
|
||||||
foreach ($p in $include_paths) {
|
foreach ($p in $include_paths) {
|
||||||
$compile_args += ($f_include + $p)
|
$compile_args += ($f_include + $p)
|
||||||
@@ -306,7 +308,8 @@ function compile-unit {
|
|||||||
$compile_args += ($f_output + $link_module)
|
$compile_args += ($f_output + $link_module)
|
||||||
|
|
||||||
write-host "Compiling '$unit' -> '$link_module'" -ForegroundColor DarkCyan
|
write-host "Compiling '$unit' -> '$link_module'" -ForegroundColor DarkCyan
|
||||||
& $compiler $compile_args
|
$time_to_compile = Measure-Command { & $compiler $compile_args }
|
||||||
|
write-host "Compilation took $($time_to_compile.TotalMilliseconds)ms"
|
||||||
if ($LASTEXITCODE -ne 0) { write-error "Compilation failed for $unit. Aborting."; exit 1 }
|
if ($LASTEXITCODE -ne 0) { write-error "Compilation failed for $unit. Aborting."; exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +343,8 @@ function link-modules {
|
|||||||
$link_args += $user_link_args
|
$link_args += $user_link_args
|
||||||
|
|
||||||
write-host "Linking modules into '$module'" -ForegroundColor DarkCyan
|
write-host "Linking modules into '$module'" -ForegroundColor DarkCyan
|
||||||
& $linker $link_args
|
$time_to_link = Measure-Command { & $linker $link_args }
|
||||||
|
write-host "Linking took $($time_to_link.TotalMilliseconds)ms"
|
||||||
if ($LASTEXITCODE -ne 0) { write-error "Linking failed. Aborting."; exit 1 }
|
if ($LASTEXITCODE -ne 0) { write-error "Linking failed. Aborting."; exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +359,9 @@ function build-part_1 {
|
|||||||
$module_c = join-path $path_build 'sim_8086.o'
|
$module_c = join-path $path_build 'sim_8086.o'
|
||||||
|
|
||||||
$compile_args = @()
|
$compile_args = @()
|
||||||
|
$compile_args += $f_debug
|
||||||
|
$compile_args += $f_optimize_none
|
||||||
|
# $compile_args += $f_optimize_size
|
||||||
$compile_args += ($f_define + 'BUILD_DEBUG=1')
|
$compile_args += ($f_define + 'BUILD_DEBUG=1')
|
||||||
|
|
||||||
compile-unit $source_c $module_c $includes $compile_args
|
compile-unit $source_c $module_c $includes $compile_args
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
function clone-gitrepo { param( [string] $path, [string] $url )
|
function clone-gitrepo { param( [string] $path, [string] $url, [switch] $NoPull )
|
||||||
if (test-path $path) {
|
if (test-path $path) {
|
||||||
# git -C $path pull
|
if ($NoPull) {
|
||||||
|
Write-Host "Skipping pull on $path (per -NoPull)."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# Already a checkout — refresh to upstream tip.
|
||||||
|
# --ff-only refuses to create a merge commit if the local branch has
|
||||||
|
# diverged, so a divergence surfaces as a clear git error instead of a
|
||||||
|
# silent merge. Preserves the read-only intent of update_deps.
|
||||||
|
Write-Host "Pulling latest into $path ..."
|
||||||
|
git -C $path pull --ff-only
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host "Cloning $url ..."
|
Write-Host "Cloning $url ..."
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# ════════════════════════════════════════════════════════════════════════════
|
||||||
|
# update_deps.ps1 — fetch / refresh.
|
||||||
|
# ════════════════════════════════════════════════════════════════════════════
|
||||||
|
param(
|
||||||
|
[switch] $NoPull # Skip the `git pull` step when the checkout already exists.
|
||||||
|
)
|
||||||
|
|
||||||
|
$path_root = split-path -Path $PSScriptRoot -Parent
|
||||||
|
$path_course_content = join-path $path_root 'course_content'
|
||||||
|
$misc = join-path $PSScriptRoot 'helpers/misc.ps1'; . $misc
|
||||||
|
|
||||||
|
# Halt on any error (instead of PowerShell's default `Continue`).
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
|
||||||
|
# --- Dependency Definition ---
|
||||||
|
# One external dep for now: Casey Muratori's computer_enhance course repo.
|
||||||
|
$url_computer_enhance = 'https://github.com/cmuratori/computer_enhance.git'
|
||||||
|
|
||||||
|
# --- Run ---
|
||||||
|
if ($NoPull) { clone-gitrepo $path_course_content $url_computer_enhance -NoPull }
|
||||||
|
else { clone-gitrepo $path_course_content $url_computer_enhance }
|
||||||
|
|
||||||
|
write-host ''
|
||||||
|
write-host 'Course content up to date.'
|
||||||
|
|||||||
Reference in New Issue
Block a user