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
|
||||
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
|
||||
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
|
||||
#define assert(cond)
|
||||
#endif
|
||||
|
||||
#define trap() __builtin_trap()
|
||||
|
||||
#define assert_always(x) do { if((x) == false) {trap();} } while(0)
|
||||
#pragma endregion Debug
|
||||
|
||||
+92
-25
@@ -9,6 +9,7 @@ Standard: c23
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
#pragma clang diagnostic ignored "-Wmicrosoft-enum-forward-reference"
|
||||
// #pragma comment(lib, "Advapi32.lib")
|
||||
// #pragma comment(lib, "gdi32.lib")
|
||||
// #pragma comment(lib, "Kernel32.lib")
|
||||
@@ -16,8 +17,19 @@ Standard: c23
|
||||
// #pragma comment(lib, "user32.lib")
|
||||
// #pragma comment(lib, "ucrt.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 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 static_assert _Static_assert
|
||||
#define typeof __typeof__
|
||||
@@ -67,7 +79,7 @@ Standard: c23
|
||||
|
||||
#define EUB_ restrict // Execute Unit Bound: Data is siloed in the ALU Register File. The Load/Store Unit is bypassed. (Route to Execution Unit. Keep in registers)
|
||||
#define ISO_ restrict // Isolated Provenance: Alternative to Exu_. Guarantees electrical memory isolation,
|
||||
// unlocking the compiler’s ability to safely pack data across multiple parallel SIMD lanes (vectorization).
|
||||
// unlocking the compiler’s ability to safely pack data across multiple parallel SIMD lanes (vectorization).
|
||||
#define LSU_ volatile // Load/Store Unit Bound: The compiler is forbidden from caching in registers. Forces physical L1 Cache matrix sampling.
|
||||
#define LIVE_ volatile // Live External Data: Alternative to Lsu_ emphasizing the memory is tapped by an external electrical actor.
|
||||
|
||||
@@ -107,7 +119,7 @@ Standard: c23
|
||||
#define Array_expand(type,len) type Array_sym(type, len)[len]; typedef PtrSet_(Array_sym(type, len))
|
||||
#define Array_(type,len) Array_expand(type,len)
|
||||
#define Bit_(id,b) id = (1 << b), tmpl(id,pos) = b
|
||||
#define Enum_(underlying_type, symbol) underlying_type TSet_(symbol); enum symbol
|
||||
#define Enum_(underlying_type, symbol) underlying_type TSet_(symbol); enum symbol
|
||||
#define Proc_(symbol) symbol
|
||||
#define Relative_(symbol) // Does nothing but annotate that a symbol is associated with another.
|
||||
#define Struct_(symbol) struct symbol TSet_(symbol); struct symbol
|
||||
@@ -206,14 +218,17 @@ def_signed_ops(le, <=)
|
||||
#define dbg_args(...) __VA_ARGS__
|
||||
|
||||
#pragma region Control Flow & Iteration
|
||||
#define unreachable() __builtin_unreachable()
|
||||
|
||||
#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 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 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_info(type,expr, ...) for(type info= {__VA_ARGS__}; info.once!=1;++info.once,(expr)) // Defer with tracked state
|
||||
#define defer(expr) for(U4 once= 1; once!=1;++ once,(expr)) // Basic do something after body
|
||||
#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 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)
|
||||
|
||||
@@ -225,35 +240,87 @@ def_signed_ops(le, <=)
|
||||
++ iter.cursor \
|
||||
)
|
||||
#define Span_(type) \
|
||||
Struct_(tmpl( Span,type)) { type begin; type end; }; \
|
||||
Struct_(tmpl( Span,type)) { type begin; type end; }; \
|
||||
typedef Struct_(tmpl(Iter_Span,type)) { tmpl(Span,type) r; type cursor; }
|
||||
#pragma endregion Control Flow & Iteration
|
||||
|
||||
typedef Span_(S4);
|
||||
typedef Span_(U4);
|
||||
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
|
||||
#define u8_max 0xffffffffffffffffull
|
||||
// x86-64
|
||||
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))
|
||||
#define max(A,B) (((A) > (B)) ? (A) : (B))
|
||||
#define clamp_bot(X,B) max(X, B) // Clamp "X" by "B"
|
||||
#pragma region Misc
|
||||
enum {
|
||||
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 Struct_(R1_U2){ U2 p0; U2 p1; };
|
||||
typedef Struct_(R1_U4){ U4 p0; U2 p4; };
|
||||
typedef Struct_(R1_U8){ U8 p0; U8 p4; };
|
||||
typedef Enum_(U4, Month) {
|
||||
Month_Jan,
|
||||
Month_Feb,
|
||||
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); }
|
||||
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); }
|
||||
#pragma endregion Math
|
||||
typedef Struct_(DateTime) {
|
||||
U4 micro_sec; // [0,999]
|
||||
U4 msec; // [0,999]
|
||||
U4 sec; // [0,60]
|
||||
U4 min; // [0,59]
|
||||
U4 hour; // [0,24]
|
||||
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"
|
||||
#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) {
|
||||
static const char hex_chars[] = "0123456789ABCDEF";
|
||||
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
|
||||
# include "dsl.h"
|
||||
# include "memory.h"
|
||||
# include "analysis.h"
|
||||
#endif
|
||||
|
||||
#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_ 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
|
||||
|
||||
#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 Struct_(Slice_Str8) { Str8* ptr; U8 len; };
|
||||
#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
|
||||
FI_ Slice slice_ut_(U8 ptr, U8 len) { return (Slice){ptr, 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_end(slice) ((slice).ptr + (slice).len)
|
||||
#define S_slice(s) ((s).len * S_((s).ptr[0]))
|
||||
|
||||
#define slice_ut(ptr,len) slice_ut_(u4_(ptr), u4_(len))
|
||||
#define slice_ut_arr(a) slice_ut_(u4_(a), S_(a))
|
||||
#define slice_to_ut(s) slice_ut_(u4_((s).ptr), S_slice(s))
|
||||
#define slice_ut(ptr,len) slice_ut_(u8_(ptr), u8_(len))
|
||||
#define slice_ut_arr(a) slice_ut_(u8_(a), S_(a))
|
||||
#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_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) }
|
||||
|
||||
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);
|
||||
}
|
||||
#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)); \
|
||||
} while(0)
|
||||
|
||||
typedef Slice_(B1);
|
||||
typedef Slice_(U1);
|
||||
typedef Slice_(U2);
|
||||
typedef Slice_(U4);
|
||||
typedef Slice_(U8);
|
||||
|
||||
#pragma endregion Slice
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# include "dsl.h"
|
||||
# include "memory.h"
|
||||
# include "hashing.h"
|
||||
# include "analysis.h"
|
||||
#endif
|
||||
|
||||
#pragma region Key Table Linear (KTL)
|
||||
|
||||
+30
-1
@@ -2,12 +2,14 @@
|
||||
# pragma once
|
||||
# include "dsl.h"
|
||||
# include "memory.h"
|
||||
# include "encoding.h"
|
||||
# include "hashing.h"
|
||||
# include "tables.h"
|
||||
# include "analysis.h"
|
||||
#endif
|
||||
|
||||
// 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,
|
||||
@@ -203,3 +205,30 @@ FI_ void str8gen_append_fmt(Str8Gen_R gen, Str8 fmt, KTL_Str8 tbl) {
|
||||
gen->len += result.len;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
+219
-61
@@ -17,17 +17,61 @@ typedef Struct_(MS_Handle){U8 id;};
|
||||
#pragma endregion IO
|
||||
|
||||
// --- 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 {
|
||||
U4 style;
|
||||
S8 (*lpfnWndProc)(void*, U4, U8, S8);
|
||||
S4 cbClsExtra;
|
||||
S4 cbWndExtra;
|
||||
void* hInstance;
|
||||
void* hIcon;
|
||||
void* hCursor;
|
||||
void* hbrBackground;
|
||||
char const* lpszMenuName;
|
||||
char const* lpszClassName;
|
||||
U4 style;
|
||||
S8 (*lpfnWndProc)(void*, U4, U8, S8);
|
||||
S4 cbClsExtra;
|
||||
S4 cbWndExtra;
|
||||
void* hInstance;
|
||||
void* hIcon;
|
||||
void* hCursor;
|
||||
void* hbrBackground;
|
||||
char const* lpszMenuName;
|
||||
char const* lpszClassName;
|
||||
} MS_WNDCLASSA;
|
||||
typedef struct MS_POINT { S4 x, y; } MS_POINT;
|
||||
typedef struct MS_MSG { void* hwnd; U4 message; U8 wParam; S8 lParam; U4 time; MS_POINT pt; } MS_MSG;
|
||||
@@ -35,39 +79,47 @@ 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;
|
||||
|
||||
// --- Kernel32 ---
|
||||
WinAPI U4 ms_get_last_error() asm("GetLastError");
|
||||
WinAPI void ms_exit_process(U4 uExitCode) asm("ExitProcess");
|
||||
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 B4 ms_read_console(
|
||||
MS_Handle handle,
|
||||
UTF8_R buffer,
|
||||
U4 to_read,
|
||||
U4_R num_read,
|
||||
U8 reserved_input_control
|
||||
MS_Handle handle,
|
||||
UTF8_R buffer,
|
||||
U4 to_read,
|
||||
U4_R num_read,
|
||||
U8 reserved_input_control
|
||||
) asm("ReadConsoleA");
|
||||
WinAPI B4 ms_write_console(
|
||||
MS_Handle handle,
|
||||
UTF8 const*R_ buffer,
|
||||
U4 chars_to_write,
|
||||
U4_V chars_written,
|
||||
U8 reserved
|
||||
MS_Handle handle,
|
||||
UTF8 const*R_ buffer,
|
||||
U4 chars_to_write,
|
||||
U4_V chars_written,
|
||||
U8 reserved
|
||||
) 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 ---
|
||||
WinAPI U2 ms_register_class_a(MS_WNDCLASSA const* lpWndClass) asm("RegisterClassA");
|
||||
WinAPI void* ms_create_window_ex_a(
|
||||
U4 dwExStyle,
|
||||
char const* lpClassName,
|
||||
char const* lpWindowName,
|
||||
U4 dwStyle,
|
||||
S4 X,
|
||||
S4 Y,
|
||||
S4 nWidth,
|
||||
S4 nHeight,
|
||||
void* hWndParent,
|
||||
void* hMenu,
|
||||
void* hInstance,
|
||||
void* lpParam
|
||||
U4 dwExStyle,
|
||||
char const* lpClassName,
|
||||
char const* lpWindowName,
|
||||
U4 dwStyle,
|
||||
S4 X,
|
||||
S4 Y,
|
||||
S4 nWidth,
|
||||
S4 nHeight,
|
||||
void* hWndParent,
|
||||
void* hMenu,
|
||||
void* hInstance,
|
||||
void* lpParam
|
||||
) asm("CreateWindowExA");
|
||||
WinAPI S4 ms_show_window(void* hWnd, S4 nCmdShow) asm("ShowWindow");
|
||||
WinAPI S4 ms_get_message_a(MS_MSG* lpMsg, void* hWnd, U4 wMsgFilterMin, U4 wMsgFilterMax) asm("GetMessageA");
|
||||
@@ -86,37 +138,54 @@ WinAPI U4 ms_set_bk_color(void* hdc, U4 color) as
|
||||
WinAPI S4 ms_text_out_a(void* hdc, S4 x, S4 y, char const* lpString, S4 c) asm("TextOutA");
|
||||
WinAPI void* ms_get_stock_object(S4 i) asm("GetStockObject");
|
||||
WinAPI void* ms_create_font_a(
|
||||
S4 cHeight,
|
||||
S4 cWidth,
|
||||
S4 cEscapement,
|
||||
S4 cOrientation,
|
||||
S4 cWeight,
|
||||
U4 bItalic,
|
||||
U4 bUnderline,
|
||||
U4 bStrikeOut,
|
||||
U4 iCharSet,
|
||||
U4 iOutPrecision,
|
||||
U4 iClipPrecision,
|
||||
U4 iQuality,
|
||||
U4 iPitchAndFamily,
|
||||
char const* pszFaceName
|
||||
S4 cHeight,
|
||||
S4 cWidth,
|
||||
S4 cEscapement,
|
||||
S4 cOrientation,
|
||||
S4 cWeight,
|
||||
U4 bItalic,
|
||||
U4 bUnderline,
|
||||
U4 bStrikeOut,
|
||||
U4 iCharSet,
|
||||
U4 iOutPrecision,
|
||||
U4 iClipPrecision,
|
||||
U4 iQuality,
|
||||
U4 iPitchAndFamily,
|
||||
char const* pszFaceName
|
||||
) asm("CreateFontA");
|
||||
WinAPI void* ms_create_compatible_dc(void* hdc) asm("CreateCompatibleDC");
|
||||
WinAPI void* ms_create_compatible_bitmap(void* hdc, S4 cx, S4 cy) asm("CreateCompatibleBitmap");
|
||||
WinAPI B4 ms_bit_blt(void* hdcDest, S4 x, S4 y, S4 w, S4 h, void* hdcSrc, S4 xSrc, S4 ySrc, U4 rop) asm("BitBlt");
|
||||
WinAPI B4 ms_delete_dc(void* hdc) asm("DeleteDC");
|
||||
WinAPI B4 ms_get_client_rect(void* hwnd, MS_RECT* lpRect) asm("GetClientRect");
|
||||
WinAPI void* ms_select_object(void* hdc, void* h) asm("SelectObject");
|
||||
WinAPI S4 ms_rectangle(void* hdc, S4 left, S4 top, S4 right, S4 bottom) asm("Rectangle");
|
||||
WinAPI S4 ms_set_bk_mode(void* hdc, S4 mode) asm("SetBkMode");
|
||||
WinAPI void* ms_create_solid_brush(U4 color) asm("CreateSolidBrush");
|
||||
WinAPI S4 ms_delete_object(void* ho) asm("DeleteObject");
|
||||
WinAPI void* ms_select_object(void* hdc, void* h) asm("SelectObject");
|
||||
WinAPI S4 ms_rectangle(void* hdc, S4 left, S4 top, S4 right, S4 bottom) asm("Rectangle");
|
||||
WinAPI S4 ms_set_bk_mode(void* hdc, S4 mode) asm("SetBkMode");
|
||||
WinAPI void* ms_create_solid_brush(U4 color) asm("CreateSolidBrush");
|
||||
WinAPI S4 ms_delete_object(void* ho) asm("DeleteObject");
|
||||
|
||||
#define MS_INVALID_HANDLE_VALUE ((MS_Handle*)(U8) - 1)
|
||||
|
||||
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_RESERVE = 0x00002000,
|
||||
MS_PAGE_READWRITE = 0x04,
|
||||
MS_SRCCOPY = 0x00CC0020,
|
||||
|
||||
MS_WM_DESTROY = 0x0002,
|
||||
MS_WM_SIZE = 0x0005,
|
||||
MS_WM_PAINT = 0x000F,
|
||||
@@ -133,26 +202,115 @@ enum {
|
||||
MS_WM_MOUSEWHEEL = 0x020A,
|
||||
MS_WS_OVERLAPPEDWINDOW = 0x00CF0000,
|
||||
MS_WS_VISIBLE = 0x10000000,
|
||||
MS_VK_LEFT = 0x25,
|
||||
MS_VK_UP = 0x26,
|
||||
MS_VK_RIGHT = 0x27,
|
||||
MS_VK_DOWN = 0x28,
|
||||
|
||||
MS_PAGE_EXECUTE_READWRITE = 0x40,
|
||||
|
||||
MS_WM_CHAR = 0x0102,
|
||||
MS_VK_RETURN = 0x0D,
|
||||
MS_VK_BACK = 0x08,
|
||||
MS_VK_TAB = 0x09,
|
||||
MS_VK_RETURN = 0x0D,
|
||||
MS_VK_SHIFT =0x10,
|
||||
MS_VK_SPACE = 0x20,
|
||||
MS_VK_F5 = 0x74,
|
||||
MS_VK_PRIOR = 0x21,
|
||||
MS_VK_NEXT = 0x22,
|
||||
|
||||
MS_VK_SHIFT =0x10,
|
||||
MS_VK_LEFT = 0x25,
|
||||
MS_VK_UP = 0x26,
|
||||
MS_VK_RIGHT = 0x27,
|
||||
MS_VK_DOWN = 0x28,
|
||||
MS_VK_F1 = 0x70,
|
||||
MS_VK_F2 = 0x71,
|
||||
MS_VK_F5 = 0x74,
|
||||
MS_WM_CHAR = 0x0102,
|
||||
};
|
||||
|
||||
|
||||
#if BUILD_DEBUG
|
||||
FI_ void assert(U8 cond) { if(cond){return;} else{debug_trap(); ms_exit_process(1);} }
|
||||
#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/analysis.h"
|
||||
#include "duffle/math.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"
|
||||
|
||||
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()
|
||||
{
|
||||
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);
|
||||
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'
|
||||
'user32.lib'
|
||||
'gdi32.lib'
|
||||
'vcruntime.lib'
|
||||
)
|
||||
|
||||
# --- Functions ---
|
||||
@@ -291,11 +292,12 @@ function compile-unit {
|
||||
)
|
||||
$compile_args = @()
|
||||
$compile_args += $f_std_c11
|
||||
$compile_args += $f_all_c
|
||||
$compile_args += $f_ms_ex
|
||||
$compile_args += $f_wall
|
||||
$compile_args += $f_wno_attributes
|
||||
$compile_args += $f_exceptions_disabled
|
||||
$compile_args += $f_diagnostics_absolute
|
||||
$compile_args += $f_optimize_none
|
||||
$compile_args += $f_debug
|
||||
foreach ($p in $include_paths) {
|
||||
$compile_args += ($f_include + $p)
|
||||
@@ -306,7 +308,8 @@ function compile-unit {
|
||||
$compile_args += ($f_output + $link_module)
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
@@ -340,7 +343,8 @@ function link-modules {
|
||||
$link_args += $user_link_args
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
@@ -355,6 +359,9 @@ function build-part_1 {
|
||||
$module_c = join-path $path_build 'sim_8086.o'
|
||||
|
||||
$compile_args = @()
|
||||
$compile_args += $f_debug
|
||||
$compile_args += $f_optimize_none
|
||||
# $compile_args += $f_optimize_size
|
||||
$compile_args += ($f_define + 'BUILD_DEBUG=1')
|
||||
|
||||
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) {
|
||||
# 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 {
|
||||
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