Compare commits

...
16 Commits
Author SHA1 Message Date
ed aa9c4d48f6 starting to prep to decode instructions 2026-08-07 10:01:20 -04:00
ed 823ec3d499 Add update_deps.ps1 (clone computer enhance repo) 2026-08-07 01:32:51 -04:00
ed 77bda7741f Picture! 2026-08-07 01:08:26 -04:00
ed 8b4c8a2c71 got file reading working for the binary. 2026-08-07 01:06:57 -04:00
ed 6feff68b33 Some more prep 2026-08-06 21:10:04 -04:00
ed ac1fffa422 flag catalogue 2026-08-06 19:17:52 -04:00
ed 030876da48 working build. (not run) 2026-08-06 19:04:14 -04:00
ed 8b3e6f5ef3 wip: rusty with the build scripts 2026-08-06 17:08:56 -04:00
ed ce3206393a fix for str8gen_append_str8 2026-08-06 16:38:11 -04:00
ed 008d5e12b3 build.ps1 skeleton 2026-08-06 16:33:42 -04:00
ed b09b51fdf5 add gencpp c11 as dependency 2026-08-06 16:33:23 -04:00
ed 154c85f253 vs code setup 2026-08-06 16:33:09 -04:00
ed f49fcbe510 boostrap duffle (not compiled, unverified) 2026-08-06 16:33:00 -04:00
ed 31f81ec8e3 lua 2026-08-06 14:35:35 -04:00
ed f116f02503 Starter stuff 2026-08-06 14:18:09 -04:00
ed 57154dc801 Wiping repo clean, starting anew 2026-08-06 14:04:18 -04:00
50 changed files with 31045 additions and 20078 deletions
+34 -3
View File
@@ -1,11 +1,42 @@
[*.md]
root = true
[*.s]
indent_style = tab
indent_size = 2
[*.asm]
indent_style = tab
indent_size = 2
[*.refactor]
indent_style = space
indent_size = 4
[*.md]
indent_style = space
indent_size = 4
[*.h]
indent_style = tab
indent_size = 2
[*.c]
indent_style = tab
indent_size = 4
indent_size = 2
[*.cpp]
[*.{ps1, psm1}]
indent_style = tab
indent_size = 4
[*.odin]
indent_style = tab
indent_size = 2
charset = utf-8
[*.{natvis, natstepfilter}]
indent_style = tab
indent_size = 4
[*.lua]
indent_style = tab
indent_size = 2
+3
View File
@@ -0,0 +1,3 @@
code/8086/* linguist-language=C
code/duffle/* linguist-language=C
code/part_1/* linguist-language=C
+2
View File
@@ -0,0 +1,2 @@
build
course_content
+11 -6
View File
@@ -1,18 +1,23 @@
{
"configurations": [
{
"name": "Win32",
"name": "The Usual (clang)",
"includePath": [
"${workspaceFolder}/**"
"${workspaceFolder}/code/",
"${workspaceFolder}/code/8086",
"${workspaceFolder}/code/duffle",
"${workspaceFolder}/code/part_1"
],
"defines": [
"_DEBUG",
"BUILD_DEBUG",
"UNICODE",
"_UNICODE"
"_UNICODE",
"INTELLISENSE_DIRECTIVES"
],
"windowsSdkVersion": "10.0.22621.0",
"compilerPath": "cl.exe",
"compileCommands": "${workspaceFolder}/part_1/build/compile_commands.json"
"compilerPath": "clang",
"cStandard": "c11",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
-19
View File
@@ -1,19 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/part_1/build/sim_8086.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}/part_1",
"environment": [],
"console": "externalTerminal"
}
]
}
+1 -7
View File
@@ -1,9 +1,3 @@
{
"files.associations": {
"*.rmd": "markdown",
"zpl.h": "c",
"cstddef": "cpp",
"xtr1common": "cpp",
"*.inline": "cpp"
}
"C_Cpp.default.compilerPath": "C:\\Program Files\\LLVM\\bin\\clang.exe",
}
-51
View File
@@ -1,51 +0,0 @@
#include "bloat.hpp"
namespace Op
{
enum Code : u8
{
#define D_Entry( Entry_ ) Entry,
#include "opcodes.inline"
Num,
#undef D_Entry
};
char const* str( Code code )
{
static
char const* code_to_str[ Num] =
{
#define D_Entry( Entry_ ) ZPL_STRINGIFY( Entry_ ),
#include "opcodes.inline"
#undef D_Entry
};
return code_to_str[ code ];
}
char const* meumonic( Code code )
{
static
char const* code_to_str[ Num] =
{
#define D_Entry( Entry_ ) ZPL_STRINGIFY( Entry_ ),
#include "opcodes.meumonics.inline"
#undef D_Entry
};
return code_to_str[ code ];
}
char const* intuitive( Code code )
{
static
char const* code_to_str[ Num] =
{
#define D_Entry( Entry_ ) ZPL_STRINGIFY( Entry_ ),
#include "opcodes.intuitive.inline"
#undef D_Entry
};
return code_to_str[ Num];
}
}
-146
View File
@@ -1,146 +0,0 @@
D_Entry( add_00 )
D_Entry( add_01 )
D_Entry( add_02 )
D_Entry( add_04 )
D_Entry( add_05 )
D_Entry( push_06 )
D_Entry( pop_07 )
D_Entry( or_10 )
D_Entry( or_11 )
D_Entry( or_12 )
D_Entry( or_13 )
D_Entry( or_14 )
D_Entry( or_15 )
D_Entry( push_16 )
D_Entry( _17 )
D_Entry( adc_20 )
D_Entry( adc_21 )
D_Entry( adc_22 )
D_Entry( adc_23 )
D_Entry( adc_24 )
D_Entry( adc_25 )
D_Entry( push_26 )
D_Entry( pop_27 )
D_Entry( sbb_30 )
D_Entry( sbb_31 )
D_Entry( sbb_32 )
D_Entry( sbb_33 )
D_Entry( sbb_34 )
D_Entry( sbb_35 )
D_Entry( push_36 )
D_Entry( pop_37 )
D_Entry( and_40 )
D_Entry( and_41 )
D_Entry( and_42 )
D_Entry( and_43 )
D_Entry( and_44 )
D_Entry( and_45 )
D_Entry( es_46 )
D_Entry( daa_47 )
D_Entry( sub_50 )
D_Entry( sub_51 )
D_Entry( sub_52 )
D_Entry( sub_53 )
D_Entry( sub_54 )
D_Entry( sub_55 )
D_Entry( cs_56 )
D_Entry( das_57 )
D_Entry( xor_60 )
D_Entry( xor_61 )
D_Entry( xor_62 )
D_Entry( xor_63 )
D_Entry( xor_64 )
D_Entry( xor_65 )
D_Entry( ss_66 )
D_Entry( aaa_67 )
D_Entry( cmp_70 )
D_Entry( cmp_71 )
D_Entry( cmp_72 )
D_Entry( cmp_73 )
D_Entry( cmp_74 )
D_Entry( cmp_75 )
D_Entry( ds_75 )
D_Entry( ds_76 )
D_Entry( aas_107 )
D_Entry( inc_100 )
D_Entry( inc_101 )
D_Entry( inc_102 )
D_Entry( inc_103 )
D_Entry( inc_104 )
D_Entry( inc_105 )
D_Entry( inc_106 )
D_Entry( inc_107 )
D_Entry( dec_100 )
D_Entry( dec_101 )
D_Entry( dec_102 )
D_Entry( dec_103 )
D_Entry( dec_104 )
D_Entry( dec_105 )
D_Entry( dec_106 )
D_Entry( dec_107 )
D_Entry( push_110 )
D_Entry( push_111 )
D_Entry( push_112 )
D_Entry( push_113 )
D_Entry( push_114 )
D_Entry( push_115 )
D_Entry( push_116 )
D_Entry( push_117 )
D_Entry( pop_120 )
D_Entry( pop_121 )
D_Entry( pop_122 )
D_Entry( pop_123 )
D_Entry( pop_124 )
D_Entry( pop_125 )
D_Entry( pop_126 )
D_Entry( pop_127 )
D_Entry( pop_130 )
D_Entry( pop_131 )
D_Entry( pop_132 )
D_Entry( pop_133 )
D_Entry( pop_134 )
D_Entry( pop_135 )
D_Entry( pop_136 )
D_Entry( pop_137 )
D_Entry( _140 )
D_Entry( _141 )
D_Entry( _142 )
D_Entry( _143 )
D_Entry( _144 )
D_Entry( _145 )
D_Entry( _146 )
D_Entry( _147 )
D_Entry( _150 )
D_Entry( _151 )
D_Entry( _152 )
D_Entry( _153 )
D_Entry( _154 )
D_Entry( _155 )
D_Entry( _156 )
D_Entry( _157 )
D_Entry( jo_160 )
D_Entry( jno_161 )
D_Entry( jb_jnae_jc_162 )
D_Entry( jnb_jae_jnc_163 )
D_Entry( je_jz_164 )
D_Entry( jne_jnz_165 )
D_Entry( jbe_jna_166 )
D_Entry( jnbe_ja_167 )
D_Entry( js_170 )
D_Entry( jns_171 )
D_Entry( jp_jpe_172 )
D_Entry( jnp_jpo_173 )
D_Entry( jl_jnge_174 )
D_Entry( jnl_jge_175 )
D_Entry( jle_jng_176 )
D_Entry( jnle_jg_177 )
D_Entry( add_200 )
D_Entry( or_201 )
D_Entry( adc_201 )
D_Entry( sbb_202 )
D_Entry( sub_203 )
D_Entry( cmp_204 )
D_Entry( add_205 )
D_Entry( adc_206 )
D_Entry( sbb_207 )
D_Entry( sub_210 )
View File
View File
-16
View File
@@ -1,16 +0,0 @@
# perfaware
Homework for Casey's [Performance Aware Programming course](https://www.computerenhance.com/p/table-of-contents)
[Material Source](https://github.com/cmuratori/computer_enhance)
Thirdparty Libraries:
* [zpl](https://github.com/zpl-c) - Used instead of the C/C++ standard library.
Tools:
* [scoop](https://scoop.sh) : Windows package manager
* clang : C/C++ compiler
```scoop install llvm```
* meson : Build system
```scoop install meson```
* nasm : x86 Assembler
```scoop install nasm```
+16
View File
@@ -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!
![Part 1: File read!](./docs/assets/raddbg_2026-08-07_01-06-36.png)
+18
View File
@@ -0,0 +1,18 @@
# C Duffle Library
```txt
ISA: amd64
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
```
+21
View File
@@ -0,0 +1,21 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
# if _WIN32
# include "win32.h"
# endif
#endif
#pragma region Debug
#define debug_trap() __builtin_debugtrap()
#if BUILD_DEBUG
FI_ void assert(U8 cond);
#else
#define assert(cond)
#endif
#define trap() __builtin_trap()
#define assert_always(x) do { if((x) == false) {trap();} } while(0)
#pragma endregion Debug
+326
View File
@@ -0,0 +1,326 @@
/*
C DSL Duffle
ISA: amd64
Sandbox: Windows 11
Compiler: clang
Standard: c23
*/
#pragma clang diagnostic ignored "-Wunused-function"
#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")
// #pragma comment(lib, "msvcrt.lib")
// #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__
#define typeof_ptr(ptr) typeof((ptr)[0])
#define typeof_same(a, b) _Generic((a), typeof((b)): 1, default: 0)
#define m_expand(...) __VA_ARGS__
#define glue_impl(A, B) A ## B
#define glue(A, B) glue_impl(A, B)
#define tmpl(prefix, type) prefix ## _ ## type
#define stringify_impl(S) #S
#define stringify(S) stringify_impl(S)
#define VA_Sel_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
#define VA_Sel_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
#define VA_Sel_3( _1, _2, _3, ... ) _3 // etc..
#define global static // Mark global data
#define gknown // Mark global data used in procedure
#define LP_ static // static data within procedure scope
#define internal static // internal
#define asm __asm__
#define align_(value) __attribute__((aligned (value))) // for easy alignment
#define C_(type,data) ((type)(data)) // for enforced precedence
#define expect_(x, y) __builtin_expect(x, y) // so compiler knows the common path
#define cexpr_ __builtin_constant_p
#define I_ internal inline
#define FI_ inline __attribute__((always_inline)) // inline always
#define NI_ internal __attribute__((noinline)) // inline never
#define RO_ __attribute__((section(".rodata"))) // Read only data allocation
#define T_ typeof //
#define T_same(a,b) _Generic((a), typeof((b)): 1, default: 0)
#define R_ restrict
#define V_ volatile
// R_ (restrict) establishes an "Eigen" or "Proprius" mapping.
// Unlike volatile (V_), which assumes the memory can be changed by anything,
// R_ tells the compiler that this pointer holds the *sole*, private (idios) ownership of the memory slice.
// Writes to this memory are exclusively bound to this single symbolic mapping for the duration of the scope, guaranteeing zero aliasing.
#pragma region Fictional //, used for intiution
#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 compilers 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.
#define latch_store /* ~: atomic_store*/ // Blasts voltages from the Store Buffer into the L1 SRAM, physically flipping the cross-coupled inverters to lock the state.
#define pulse_rfo /* ~: atomic_xchg*/ // Broadcasts an electrical RFO (Request For Ownership) pulse across the CPU mesh network to invalidate other L1 caches.
#define tact_acquire /* ~: memory_order_acquire*/ // Clamp. Sends a voltage signal to the instruction decoder to halt the Out-of-Order engine until the load resolves.
#define tact_release /* ~: memory_order_release*/ // Drain. Forces the Store Buffer flip-flops to completely empty into the L1 cache before proceeding.
// -----------------------------------------------------------------------------
// Out-of-Order (OoO) Pipeline Modifiers
// -----------------------------------------------------------------------------
#define ooo_drift_ __ATOMIC_RELAXED // OoO engine allowed to drift
#define ooo_anchor_ __ATOMIC_ACQUIRE // Anchor the Load Queue (halt spec lookahead)
#define ooo_drain_ __ATOMIC_RELEASE // Drain the Store Buffer (force writeback)
#define ooo_weld_ __ATOMIC_SEQ_CST // Weld pipeline (total order bus lock)
// Latch operations with physical queue modifiers
#define latch_load_anchor(ptr) //__atomic_load_n(ptr, ooo_anchor_)
#define latch_store_drain(ptr, val) //__atomic_store_n(ptr, val, ooo_drain_)
#define pulse_xchg_weld(ptr, val) //__atomic_exchange_n(ptr, val, ooo_weld_)
#pragma endregion Fictional
#define r_(ptr) C_(T_(ptr[0])*R_, ptr) // Constrain pointer to restrict
#define v_(ptr) C_(T_(ptr[0])V_*, ptr) //
#define tr_(type, ptr) C_(type *R_, ptr)
#define tv_(type, ptr) C_(type V_*, ptr)
#define TypeR_(type) type *R_ type ## _R // type *restrict type_R
#define TypeV_(type) type V_* type ## _V // type volatile* type_V
#define PtrSet_(type) TypeR_(type); typedef TypeV_(type)
#define TSet_(type) type; typedef PtrSet_(type)
#define Array_len(a) (U4)(sizeof(a) / sizeof(typeof((a)[0])))
#define Array_decl(type, ...) (type[]){__VA_ARGS__}
#define Array_sym(type,len) A ## len ## _ ## type
#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 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
#define Union_(symbol) union symbol TSet_(symbol); union symbol
#define Opt_(proc) Struct_(tmpl(Opt,proc))
#define opt_(symbol, ...) (tmpl(Opt,symbol)){__VA_ARGS__}
#define Ret_(proc) Struct_(tmpl(Ret,proc))
#define ret_(proc) tmpl(Ret,proc) proc
// Using Byte-Width convention for the fundamental types.
typedef __UINT8_TYPE__ TSet_(U1);
typedef __UINT16_TYPE__ TSet_(U2);
typedef __UINT32_TYPE__ TSet_(U4);
typedef __UINT64_TYPE__ TSet_(U8);
typedef __INT8_TYPE__ TSet_(S1);
typedef __INT16_TYPE__ TSet_(S2);
typedef __INT32_TYPE__ TSet_(S4);
typedef __INT64_TYPE__ TSet_(S8);
typedef unsigned char TSet_(B1);
typedef __UINT16_TYPE__ TSet_(B2);
typedef __UINT32_TYPE__ TSet_(B4);
typedef __UINT64_TYPE__ TSet_(B8);
typedef float F4_2 __attribute__((vector_size(16)));
#define u1_(value) C_(U1, value)
#define u2_(value) C_(U2, value)
#define u4_(value) C_(U4, value)
#define u8_(value) C_(U8, value)
#define s1_(value) C_(S1, value)
#define s2_(value) C_(S2, value)
#define s4_(value) C_(S4, value)
#define s8_(value) C_(S8, value)
#define u1_r(value) C_(U1 *R_, value)
#define u2_r(value) C_(U2 *R_, value)
#define u4_r(value) C_(U4 *R_, value)
#define u8_r(value) C_(U8 *R_, value)
#define u1_v(value) C_(U1 V_*, value)
#define u2_v(value) C_(U2 V_*, value)
#define u4_v(value) C_(U4 V_*, value)
#define u8_v(value) C_(U8 V_*, value)
enum { false = 0, true = 1, true_overflow, };
#define u4_lo(value) ((value) & 0xFFFFU)
#define u4_hi(value) ((value) >> 12)
typedef void Proc_(VoidFn) (void);
#define kilo(n) (n << 10)
#define mega(n) (n << 20)
#define giga(n) (n << 30)
#define tera(n) (n << 40)
#define null C_(U8, 0)
#define nullptr C_(void*, 0)
#define O_(type, field) C_(U8, & C_(type*,0)->field)
#define OA_(type, member, idx) C_(U8, & C_(type*,0)->member[idx])
#define OT_(field) O_(typeof_ptr(& field), filed))
#define S_(data) C_(U8, sizeof(data))
#define sop_1(op,a,b) C_(U1, s1_(a) op s1_(b))
#define sop_2(op,a,b) C_(U2, s2_(a) op s2_(b))
#define sop_4(op,a,b) C_(U4, s4_(a) op s4_(b))
#define sop_8(op,a,b) C_(U8, s8_(a) op s8_(b))
#undef def_signed_op
#define def_signed_op(id,op,width) FI_ U ## width id ## _s ## width(U ## width a, U ## width b) {return sop_ ## width(op, a, b); }
#define def_signed_ops(id,op) def_signed_op(id, op, 1) def_signed_op(id, op, 2) def_signed_op(id, op, 4) def_signed_op(id, op, 8)
def_signed_ops(add, +)
def_signed_ops(sub, -)
def_signed_ops(mut, *)
def_signed_ops(div, /)
def_signed_ops(gt, >)
def_signed_ops(lt, <)
def_signed_ops(ge, >=)
def_signed_ops(le, <=)
#undef def_signed_ops
#undef def_signed_op
#define def_generic_sop(op, a, ...) _Generic((a), U1: op ## _s1, U2: op ## _s2, U4: op ## _s4, U8: op ## _s8) (a, __VA_ARGS__)
#define add_s(a,b) def_generic_sop(add,a,b)
#define sub_s(a,b) def_generic_sop(sub,a,b)
#define mut_s(a,b) def_generic_sop(mut,a,b)
#define gt_s(a,b) def_generic_sop(gt, a,b)
#define lt_s(a,b) def_generic_sop(lt, a,b)
#define ge_s(a,b) def_generic_sop(ge, a,b)
#define le_s(a,b) def_generic_sop(le, a,b)
#undef def_generic_sop
#define alignas _Alignas
#define alignof _Alignof
#define byte_pad(amount, ...) B1 glue(_PAD_, __VA_ARGS__) [amount]
#define pcast(type, data) (C_(type*, & (data)) [0])
#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 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)
#define span_iter(type, iter, m_begin, op, m_end) ( \
tmpl(Iter_Span,type) iter = { \
.r = {(m_begin), (m_end)}, \
.cursor = (m_begin) }; \
iter.cursor op iter.r.end; \
++ iter.cursor \
)
#define Span_(type) \
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
// 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
#pragma region Misc
enum {
Bitmask_3 = 0x00000007,
Bitmask_4 = 0x0000000f,
Bitmask_5 = 0x0000001f,
Bitmask_6 = 0x0000003f,
Bitmask_10 = 0x000003ff,
};
typedef Enum_(U4, WeekDay) {
WeekDay_Sun,
WeekDay_Mon,
WeekDay_Tue,
WeekDay_Wed,
WeekDay_Thu,
WeekDay_Fri,
WeekDay_Sat,
WeekDay_Num,
};
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 U8 DenseTime;
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
+72
View File
@@ -0,0 +1,72 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
#endif
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; }
}
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;
}
+70
View File
@@ -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
+18
View File
@@ -0,0 +1,18 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
# include "memory.h"
# include "analysis.h"
#endif
#pragma region Hashing
FI_ void hash64_fnv1a(U8_R hash, Slice data, U8 seed) {
LP_ U8 const default_seed = 0xcbf29ce484222325;
if (seed == 0) seed = default_seed;
hash[0] = seed; for (U8 elem = data.ptr; elem != slice_end(data); elem += 1) {
hash[0] ^= u1_r(elem)[0];
hash[0] *= 0x100000001b3;
}
}
FI_ U8 hash64_fnv1a_ret(Slice data, U8 seed) { U8 h = 0; hash64_fnv1a(& h, data, seed); return h; }
#pragma endregion Hashing
+43
View File
@@ -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
+139
View File
@@ -0,0 +1,139 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
#endif
#define MEM_ALIGNMENT_DEFAULT 4
#define assert_bounds(point, start, end) for(;0;){ \
assert((start) <= (point)); \
assert((point) <= (end)); \
} while(0)
I_ U8 align_pow2(U8 x, U8 b) {
assert(b != 0);
assert((b & (b - 1)) == 0); // Check power of 2
return ((x + b - 1) & (~(b - 1)));
}
#define align_struct(type_width) ((U8)(((type_width) + 3) & ~3))
FI_ void mem_bump_u4(U4 start, U4 cap, U4_R used, U4 amount) {
assert(amount <= (cap - used[0]));
used[0] += amount;
}
FI_ void mem_bump_u8(U8 start, U8 cap, U8_R used, U8 amount) {
assert(amount <= (cap - used[0]));
used[0] += amount;
}
#define mem_bump(start, cap, used, amount) _Generic(start, U4: mem_bump_u4, U8: mem_bump_u8)(start, cap, used, amount)
FI_ U8 mem_copy (U8 dest, U8 src, U8 len) { return (U8)(__builtin_memcpy ((void*)dest, (void const*)src, len)); }
FI_ U8 mem_copy_overlapping(U8 dest, U8 src, U8 len) { return (U8)(__builtin_memmove((void*)dest, (void const*)src, 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_ 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)
#define set_nil(nil, p) ((p) = nil)
#define sll_stack_push_n(f, n, next) do { (n)->next = (f); (f) = (n); } while(0)
#define sll_queue_push_nz(nil, f, l, n, next) \
( \
check_nil(nil, f) ? ( \
(f) = (l) = (n), \
set_nil(nil, (n)->next) \
) \
: ( \
(l)->next=(n), \
(l) = (n), \
set_nil(nil,(n)->next) \
) \
)
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz(0, f, l, n, next)
#pragma endregion DAG
#pragma region Slice
typedef unsigned char TSet_(UTF8);
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; }
#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_(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_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); }
#define slice_zero(s) slice_zero_(slice_to_ut(s))
FI_ void slice_copy_(Slice dest, Slice src) {
assert(dest.len >= src.len);
slice_assert(dest);
slice_assert(src);
mem_copy(dest.ptr, src.ptr, src.len);
}
#define slice_copy(dest, src) do { \
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
#pragma region FArena
typedef Opt_(farena) { U8 alignment, type_width; };
typedef Struct_(FArena) { U8 start, capacity, used; };
FI_ void farena_init(FArena_R arena, Slice mem) { assert(arena != nullptr);
arena->start = mem.ptr;
arena->capacity = mem.len;
arena->used = 0;
}
FI_ FArena farena_make(Slice mem) { FArena a; farena_init(& a, mem); return a; }
I_ Slice farena_push(FArena_R arena, U8 amount, Opt_farena o) {
if (amount == 0) { return (Slice){}; }
U8 desired = amount * (o.type_width == 0 ? 1 : o.type_width);
U8 to_commit = align_pow2(desired, o.alignment ? o.alignment : MEM_ALIGNMENT_DEFAULT);
U8 ptr = arena->start + arena->used;
mem_bump_u8(arena->start, arena->capacity, & arena->used, to_commit);
return (Slice){ ptr, to_commit };
}
FI_ void farena_reset (FArena_R arena) { arena->used = 0; }
FI_ void farena_rewind(FArena_R arena, U4 save_point) {
U8 end = arena->start + arena->used; assert_bounds(save_point, arena->start, end);
arena->used -= save_point - arena->start;
}
FI_ U8 farena_save(FArena arena) { return arena.used; }
#define farena_push_(arena, amount, ...) farena_push((arena), (amount), opt_(farena, __VA_ARGS__))
#define farena_push_type(arena, type, ...) C_(type*, farena_push((arena), 1, opt_(farena, .type_width=S_(type), __VA_ARGS__)).ptr)
#define farena_push_array(arena, type, amount, ...) (tmpl(Slice,type)){ C_(type*, farena_push((arena), (amount), opt_(farena, .type_width=S_(type), __VA_ARGS__)).ptr), (amount) }
#pragma endregion FArena
+40
View File
@@ -0,0 +1,40 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
# include "memory.h"
# include "hashing.h"
# include "analysis.h"
#endif
#pragma region Key Table Linear (KTL)
enum { KT_SLot_value = S_(U8), };
#define KTL_Slot_(type) Struct_(tmpl(KTL_Slot,type)) { \
U8 key; \
type value; \
}
#define KTL_(type) Slice_(tmpl(KTL_Slot,type)); \
typedef tmpl(Slice_KTL_Slot,type) tmpl(KTL,type)
typedef Slice KTL_Byte;
typedef Struct_(KTL_Meta) {
U8 slot_size;
U8 type_width;
};
typedef Array_(Str8, 2);
typedef Slice_(A2_Str8);
typedef KTL_Slot_(Str8);
typedef KTL_(Str8);
FI_ void ktl_populate_slice_a2_str8(KTL_Str8* kt, Slice_A2_Str8 values) {
assert(kt != null); slice_assert(* kt);
if (values.len == 0) return;
assert(kt->len == values.len);
for index_iter(U4, id, 0, <, values.len) {
hash64_fnv1a(& kt->ptr[id].key, slice_to_ut(values.ptr[id][0]), 0);
mem_copy(u8_(& kt->ptr[id].value), u8_(& values.ptr[id][1]), S_(Str8));
}
}
#define ktl_str8_key(str) hash64_fnv1a_ret(slice_to_ut(str8(str)), 0)
#define ktl_str8_from_arr(arr) (KTL_Str8){arr, array_len(arr)}
#pragma endregion KTL
+234
View File
@@ -0,0 +1,234 @@
#ifdef INTELLISENSE_DIRECTIVES
# 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_ 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,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,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,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,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,
};
FI_ B4 char_is_upper(UTF8 c) { return('A' <= c && c <= 'Z'); }
FI_ UTF8 char_to_lower(UTF8 c) { if (char_is_upper(c)) { c += ('a' - 'A'); } return(c); }
FI_ B4 char_is_digit(UTF8 c, U4 base) {
B4 result = 0; if (0 < base && base <= 16) {
if (integer_symbol_reverse[c] < base) result = 1;
}
return result;
}
FI_ UTF8 integer_symbols(UTF8 value) {
LP_ UTF8 lookup_table[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', };
return lookup_table[C_(UTF8, value)];
}
FI_ U8 u8_from_str8(Str8 str, U4 radix) {
U8 x = 0; if(1 < radix && radix <= 16) {
for each_iter(U8, cursor, str.len) {
x *= radix;
x += integer_symbol_reverse[str.ptr[cursor] & 0x7F];
}
}
return x;
}
typedef Struct_(Info_str8_from_u4) {
Str8 prefix;
U4 digit_group_size;
U4 needed_leading_zeros;
U4 size_required;
};
I_ Info_str8_from_u4 str8_from_u4_info(U4 num, U4 radix, U4 min_digits, U4 digit_group_separator)
{
Info_str8_from_u4 info = {0};
LP_ Str8 tbl_prefix[] = { slit8("0x"), slit8("0o"), slit8("0b") };
switch (radix) {
case 16: { info.prefix = tbl_prefix[0]; } break;
case 8: { info.prefix = tbl_prefix[1]; } break;
case 2: { info.prefix = tbl_prefix[2]; } break;
}
info.digit_group_size = 3;
switch (radix) {
default: break;
case 2:
case 8:
case 16: {
info.digit_group_size = 4;
}
break;
}
info.needed_leading_zeros = 0;
{
U4 needed_digits = 1;
{
U4 u32_reduce = num;
for(;;)
{
u32_reduce /= radix;
if (u32_reduce == 0) {
break;
}
needed_digits += 1;
}
}
info.needed_leading_zeros = (min_digits > needed_digits) ? min_digits - needed_digits : 0;
U4 needed_separators = 0;
if (digit_group_separator != 0)
{
needed_separators = (needed_digits + info.needed_leading_zeros) / info.digit_group_size;
if (needed_separators > 0 && (needed_digits + info.needed_leading_zeros) % info.digit_group_size == 0) {
needed_separators -= 1;
}
}
info.size_required = info.prefix.len + info.needed_leading_zeros + needed_separators + needed_digits;
}
return info;
}
I_ Str8 str8_from_u4_buf(Slice buf, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator, Info_str8_from_u4 info)
{
assert(buf.len >= info.size_required);
Str8 result = { C_(UTF8*, buf.ptr), info.size_required };
/*Fill Content*/ {
U4 num_reduce = num;
U4 digits_until_separator = info.digit_group_size;
for (U8 idx = 0; idx < result.len; idx += 1)
{
U8 separator_pos = result.len - idx - 1;
if (digits_until_separator == 0 && digit_group_separator != 0) {
result.ptr[separator_pos] = u1_(digit_group_separator);
digits_until_separator = info.digit_group_size + 1;
}
else {
result.ptr[separator_pos] = (U1) char_to_lower(integer_symbols(u1_(num_reduce % radix)));
num_reduce /= radix;
}
digits_until_separator -= 1;
if (num_reduce == 0) break;
}
for (U8 leading_0_idx = 0; leading_0_idx < info.needed_leading_zeros; leading_0_idx += 1) {
result.ptr[info.prefix.len + leading_0_idx] = '0';
}
}
/*Fill Prefix*/ if (info.prefix.len > 0) { slice_copy(result, info.prefix); }
return result;
}
I_ Str8 str8_fmt_ktl_buf(Slice buffer, KTL_Str8 table, Str8 fmt_template)
{
slice_assert(buffer);
slice_assert(table);
slice_assert(fmt_template);
UTF8_R cursor_buffer = C_(UTF8_R, buffer.ptr);
U8 buffer_remaining = buffer.len;
UTF8_R cursor_fmt = fmt_template.ptr;
U8 left_fmt = fmt_template.len;
while (left_fmt && buffer_remaining)
{
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
U8 copy_offset = 0;
if (cursor_fmt[0] == '<')
{
UTF8_R potential_token_cursor = cursor_fmt + 1; // Skip '<'
U8 potential_token_len = 0;
B4 fmt_overflow = false;
while(true) {
UTF8_R cursor = potential_token_cursor + potential_token_len;
fmt_overflow = cursor >= slice_end(fmt_template);
B4 found_terminator = potential_token_cursor[potential_token_len] == '>';
if (fmt_overflow || found_terminator) { break; }
++ potential_token_len;
}
if (fmt_overflow) {
// Failed to find a subst and we're at end of fmt, just copy segment.
copy_offset = 1 + potential_token_len; // '<' + token
goto write_to_buffer;
}
// Hashing the potential token and cross checking it with our token table
U8 key = hash64_fnv1a_ret(slice_ut(u8_(potential_token_cursor), potential_token_len), 0);
Str8_R value = nullptr; for slice_iter(table, token) {
// We do a linear iteration instead of a hash table lookup because the user should never subst with more than 100 unqiue tokens..
if (token->key == key) { value = & token->value; break; }
}
if (value)
{
// We're going to appending the string, make sure we have enough space in our buffer.
// NOTE(Ed): this version doesn't support growing the buffer (No Allocator Interface)
assert((buffer_remaining - potential_token_len) > 0);
copy_offset = min(buffer_remaining, value->len); // Prevent Buffer overflow.
mem_copy(u8_(cursor_buffer), u8_(value->ptr), buffer_remaining);
// Sync cursor format to after the processed token
cursor_buffer += copy_offset;
buffer_remaining -= copy_offset;
cursor_fmt = potential_token_cursor + 1 + potential_token_len; // '<' + token
left_fmt -= potential_token_len + 2; // The 2 here are the '<' & '>' delimiters being omitted.
continue;
}
// If not a subsitution, we copy the segment and continue.
copy_offset = 1 + potential_token_len; // '<' + token
goto write_to_buffer;
}
else do {
++ copy_offset;
}
while ( (cursor_fmt[copy_offset] != '<' && (cursor_fmt + copy_offset) < slice_end(fmt_template)) );
write_to_buffer:
assert((buffer_remaining - copy_offset) > 0);
copy_offset = min(buffer_remaining, copy_offset); // Prevent buffer overflow.
mem_copy(u8_(cursor_buffer), u8_(cursor_fmt), copy_offset);
buffer_remaining -= copy_offset;
left_fmt -= copy_offset;
cursor_buffer += copy_offset;
cursor_fmt += copy_offset;
}
return (Str8){C_(UTF8*, buffer.ptr), buffer.len - buffer_remaining};
}
typedef Struct_(Str8Gen) { UTF8* ptr; U8 cap, len; };
FI_ Slice str8gen_buf(Str8Gen_R gen) { return (Slice){u8_(gen->ptr) + gen->len, gen->cap - gen->len}; }
FI_ void str8gen_append_str8(Str8Gen_R gen, Str8 str) { assert(gen != nullptr);
mem_bump_u8(u8_(gen->ptr), gen->cap, & gen->len, str.len);
U8 ptr = u8_(gen->ptr) + gen->len;
mem_copy(ptr, u8_(str.ptr), str.len);
}
FI_ void str8gen_append_fmt(Str8Gen_R gen, Str8 fmt, KTL_Str8 tbl) {
Str8 result = str8_fmt_ktl_buf(str8gen_buf(gen), tbl, fmt);
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;
}
+316
View File
@@ -0,0 +1,316 @@
#if INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
# include "memory.h"
#endif
WinAPI void ms_exit_process(U4 uExitCode) asm("ExitProcess"); // Kernel 32
#pragma region IO
enum {
MS_STD_INPUT_CODE = u4_(-10),
MS_STD_OUTPUT_CODE = u4_(-11),
#define MS_STD_INPUT u4_(MS_STD_INPUT_CODE)
#define MS_STD_OUTPUT u4_(MS_STD_OUTPUT_CODE)
};
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;
} 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;
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
) asm("ReadConsoleA");
WinAPI B4 ms_write_console(
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
) 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");
WinAPI S4 ms_translate_message(MS_MSG const* lpMsg) asm("TranslateMessage");
WinAPI S8 ms_dispatch_message_a(MS_MSG const* lpMsg) asm("DispatchMessageA");
WinAPI S8 ms_def_window_proc_a(void* hWnd, U4 Msg, U8 wParam, S8 lParam) asm("DefWindowProcA");
WinAPI void ms_post_quit_message(S4 nExitCode) asm("PostQuitMessage");
WinAPI S4 ms_invalidate_rect(void* hWnd, MS_RECT const* lpRect, S4 bErase) asm("InvalidateRect");
WinAPI S2 ms_get_async_key_state(S4 vKey) asm("GetAsyncKeyState");
// --- GDI32 ---
WinAPI void* ms_begin_paint(void* hWnd, MS_PAINTSTRUCT* lpPaint) asm("BeginPaint");
WinAPI S4 ms_end_paint(void* hWnd, MS_PAINTSTRUCT const* lpPaint) asm("EndPaint");
WinAPI U4 ms_set_text_color(void* hdc, U4 color) asm("SetTextColor");
WinAPI U4 ms_set_bk_color(void* hdc, U4 color) asm("SetBkColor");
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
) 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");
#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,
MS_WM_ERASEBKGND = 0x0014,
MS_WM_KEYDOWN = 0x0100,
MS_WM_KEYUP = 0x0101,
MS_WM_MOUSEMOVE = 0x0200,
MS_WM_LBUTTONDOWN = 0x0201,
MS_WM_LBUTTONUP = 0x0202,
MS_WM_RBUTTONDOWN = 0x0204,
MS_WM_RBUTTONUP = 0x0205,
MS_WM_MBUTTONDOWN = 0x0207,
MS_WM_MBUTTONUP = 0x0208,
MS_WM_MOUSEWHEEL = 0x020A,
MS_WS_OVERLAPPEDWINDOW = 0x00CF0000,
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_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
+88
View File
@@ -0,0 +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

-208
View File
@@ -1,208 +0,0 @@
#if __clang__
# pragma clang diagnostic ignored "-Wunused-const-variable"
# pragma clang diagnostic ignored "-Wswitch"
# pragma clang diagnostic ignored "-Wunused-variable"
#endif
#pragma region ZPL INCLUDE
#if __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wmissing-braces"
# pragma clang diagnostic ignored "-Wbraced-scalar-init"
#endif
#define ZPL_IMPLEMENTATION
// # define ZPL_HEAP_ANALYSIS
# define ZPL_NO_MATH_H
# define ZPL_CUSTOM_MODULES
# define ZPL_MODULE_ESSENTIALS
# define ZPL_MODULE_CORE
# define ZPL_MODULE_TIMER
// # define ZPL_MODULE_HASHING
// # define ZPL_MODULE_REGEX
// # define ZPL_MODULE_EVENT
// # define ZPL_MODULE_DLL
// # define ZPL_MODULE_OPTS
// # define ZPL_MODULE_PROCESS
// # define ZPL_MODULE_MATH
// # define ZPL_MODULE_THREADING
// # define ZPL_MODULE_JOBS
// # define ZPL_MODULE_PARSER
// extern "C" {
#include "zpl.h"
// }
#if __clang__
# pragma clang diagnostic pop
#endif
#pragma endregion ZPL INCLUDE
zpl_arena Global_Arena {};
#define g_allocator zpl_arena_allocator( & Global_Arena)
void setup()
{
zpl_arena_init_from_allocator( & Global_Arena, zpl_heap(), zpl_megabytes(10) );
if ( Global_Arena.total_size == 0 )
{
zpl_assert_crash( "Failed to reserve memory for Tests:: Global_Arena" );
}
}
void cleanup()
{
zpl_arena_free( & Global_Arena);
}
#pragma region ZPL Expose
zpl_string string_make(zpl_isize capacity)
{
zpl_isize header_size = zpl_size_of(zpl_string_header);
void *ptr = zpl_alloc(g_allocator, header_size + capacity + 1);
zpl_string str;
zpl_string_header *header;
if (ptr == NULL) return NULL;
zpl_zero_size(ptr, header_size + capacity + 1);
str = cast(char *) ptr + header_size;
header = ZPL_STRING_HEADER(str);
header->allocator = g_allocator;
header->length = 0;
header->capacity = capacity;
str[capacity] = '\0';
return str;
}
inline
zpl_string string_make(const char *str)
{
zpl_isize len = str ? zpl_strlen(str) : 0;
return zpl_string_make_length(g_allocator, str, len);
}
inline
zpl_string string_append(zpl_string str, zpl_string const other)
{
return zpl_string_append_length(str, other, zpl_string_length(other));
}
zpl_string string_format( char const* fmt, ... )
{
zpl_local_persist zpl_thread_local char buf[ZPL_PRINTF_MAXLEN] = { 0 };
va_list va;
va_start(va, fmt);
zpl_snprintf_va(buf, ZPL_PRINTF_MAXLEN, fmt, va);
va_end(va);
return zpl_string_make(g_allocator, buf);
}
zpl_string string_format( char* buffer, zpl_isize size, char const* fmt, ... )
{
va_list va;
va_start(va, fmt);
zpl_snprintf_va(buffer, size, fmt, va);
va_end(va);
return zpl_string_make(g_allocator, buffer);
}
#pragma endregion ZPL Expose
#define bit( Value_ ) ( 1 << Value_ )
#define bitfield_is_equal( Field_, Mask_ ) ( ( Mask_ & Field_ ) == Mask_ )
#undef cast
#define cast( Type_ , Value_ ) ( ( Type_ )( Value_ ) )
#define ct constexpr
#define gen( ... ) template< __VA_ARGS__ >
#define forceinline ZPL_ALWAYS_INLINE
#define print_nl( _) zpl_printf("\n")
#define Msg_Invalid_Value "INVALID VALUE PROVIDED"
#define scast static_cast
#define rcast reinterpret_cast
#define pcast( Type_, Value_ ) ( * (Type_*)( & Value_ ) )
using s8 = zpl_i8;
using u8 = zpl_u8;
using u16 = zpl_u16;
using u32 = zpl_u32;
using f64 = zpl_f64;
using uw = zpl_usize;
using sw = zpl_isize;
struct u16_Split
{
u8 Low;
u8 High;
operator u16()
{
return * cast( u16*, this );
}
};
ct inline
char char_binary( u8 value, u8 pos )
{
u8 mask = 1 << pos ;
return ( (1 << pos) & value) == mask ? '1' : '0';
}
inline
void str_binary( char* result, u8 value )
{
#if 0
result[0] = char_binary( value, 0);
result[1] = char_binary( value, 1);
result[2] = char_binary( value, 2);
result[3] = char_binary( value, 3);
result[4] = char_binary( value, 4);
result[5] = char_binary( value, 5);
result[6] = char_binary( value, 6);
result[7] = char_binary( value, 7);
#else
result[0] = char_binary( value, 7);
result[1] = char_binary( value, 6);
result[2] = char_binary( value, 5);
result[3] = char_binary( value, 4);
result[4] = char_binary( value, 3);
result[5] = char_binary( value, 2);
result[6] = char_binary( value, 1);
result[7] = char_binary( value, 0);
#endif
}
inline
void print_as_binary( u8* data, uw size, char const* byte_term )
{
char
binary_string[9];
binary_string[8] = '\0';
while ( size-- )
{
str_binary( binary_string, data[0]);
printf( "%s%s", binary_string, byte_term );
data += 1;
}
}
-29
View File
@@ -1,29 +0,0 @@
@echo off
if not exist build\nul (
meson setup build
)
echo:
if not exist tests\listing_0037_single_register_mov (
echo Assembling: listing_0037_single_register_mov.asm
call nasm ".\tests\listing_0037_single_register_mov.asm"
)
if not exist tests\listing_0038_many_register_mov (
echo Assembling: listing_0038_many_register_mov.asm
call nasm ".\tests\listing_0038_many_register_mov.asm"
)
if not exist tests\listing_0039_more_movs (
echo Assembling: listing_0039_more_movs.asm
call nasm ".\tests\listing_0039_more_movs.asm"
)
if not exist tests\listing_0040_challenge_movs (
echo Assembling: listing_0040_challenge_movs.asm
call nasm ".\tests\listing_0040_challenge_movs.asm"
)
echo:
ninja -C build
-22
View File
@@ -1,22 +0,0 @@
@echo off
if exist build\nul (
@RD /S /Q "build"
)
if exist tests\listing_0037_single_register_mov (
DEL /Q tests\listing_0037_single_register_mov
)
if exist tests\listing_0038_many_register_mov (
DEL /Q tests\listing_0038_many_register_mov
)
if exist tests\listing_0039_more_movs (
DEL /Q tests\listing_0039_more_movs
)
if exist tests\listing_0040_challenge_movs (
DEL /Q tests\listing_0040_challenge_movs
)
BIN
View File
Binary file not shown.
-13
View File
@@ -1,13 +0,0 @@
project( 'sim_8086', 'c', 'cpp', default_options : ['buildtype=debug'] )
include_thirdparty = include_directories( '../thirdparty' )
# add_global_arguments('-E', language : 'cpp')
if get_option('buildtype').startswith('debug')
add_project_arguments('-DBuild_Debug', language : 'cpp')
endif
executable( 'sim_8086', 'sim_8086.cpp', include_directories : include_thirdparty )
-756
View File
@@ -1,756 +0,0 @@
#include "bloat.hpp"
// Octal formatting is used heavily throughout
// See: https://gist.github.com/seanjensengrey/f971c20d05d4d0efc0781f2f3c0353da
// (x86 is an octal machine)
namespace Op
{
ct u8 Mask = 00210;
ct u8 Mask_Low = 0b11110000;
ct u8 Mask_High = 0b00001111;
ct u8 Mask_Imme = 0b00111000;
#define D_Opcodes \
D_Entry( mov_RM_R ) \
D_Entry( mov_Im_RM ) \
D_Entry( mov_Im_R ) \
D_Entry( mov_M_Acc ) \
D_Entry( mov_Acc_M ) \
D_Entry( mov_RM_SR ) \
D_Entry( mov_SR_RM ) \
enum Code : u8
{
mov_RM_R = 0b10001000,
mov_Im_RM = 0b11001100,
mov_Im_R = 0b10110000,
mov_M_Acc = 0b10100000,
mov_Acc_M = 0b10100010,
mov_RM_SR = 0b10001110,
mov_SR_RM = 0b10001100
};
char const* str( Code type )
{
switch ( type )
{
#define D_Entry( Entry_ ) \
case Entry_: \
return ZPL_STRINGIFY(Entry_); \
D_Opcodes
#undef D_Entry
}
return Msg_Invalid_Value;
}
char const* meumonic( Code type )
{
switch ( type )
{
case mov_RM_R :
case mov_Im_RM :
case mov_Im_R :
case mov_M_Acc :
case mov_Acc_M :
case mov_RM_SR :
case mov_SR_RM :
return "mov";
}
return Msg_Invalid_Value;
}
char const* intuitive( Code type )
{
switch ( type )
{
case mov_RM_R :
case mov_Im_RM :
case mov_Im_R :
case mov_M_Acc :
case mov_Acc_M :
case mov_RM_SR :
case mov_SR_RM :
return "move";
}
return Msg_Invalid_Value;
}
#undef D_Opcodes
}
namespace Field
{
inline
u8 offset_left_reg( u8 reg )
{
return reg << 3;
}
// https://i.imgur.com/drsyYnM.png
enum Direction : u8
{
Mask_Dir = 0b00000010,
Dir_Src = 0b00,
Dir_Dest = 0b10,
};
inline
char const* str_direction( Direction direction )
{
switch ( direction )
{
case Dir_Dest:
return "Destination";
case Dir_Src:
return "Source";
}
return Msg_Invalid_Value;
}
// https://i.imgur.com/9Op8Lnd.png
enum Width : u8
{
Mask_Width = 0b00000001,
Mask_Width_Imme = 0b00001000,
Width_Byte = 0b00,
Width_Word = 0b01,
};
inline
char const* str_width( Width width )
{
switch ( width )
{
case Width_Byte:
return "Byte";
case Width_Word:
return "Word";
}
return Msg_Invalid_Value;
}
// https://i.imgur.com/Job2oPd.png
enum Mode : u8
{
Mask_Mode = 0b11000000,
Mode_Mem = 0b00000000,
Mode_Mem8 = 0b01000000,
Mode_Mem16 = 0b10000000,
Mode_Reg = 0b11000000,
};
char const* str_mode( Mode mode )
{
switch (mode)
{
case Mode_Mem:
return "Memory: No Displacement";
case Mode_Mem8:
return "Memory: 8-bit Displacment";
case Mode_Mem16:
return "Memory: 16-bit Displacement";
case Mode_Reg:
return "Register";
}
return Msg_Invalid_Value;
}
ct u8 Mask_Memory = 0b00000111;
// https://i.imgur.com/Tm5roJu.png
enum Memory : u8
{
Add_BX_SI = 0b000,
Add_BX_DI = 0b001,
Add_BP_SI = 0b010,
Add_BP_DI = 0b011,
Add_SI = 0b100,
Add_DI = 0b101,
Add_Direct = 0b110,
Add_BX = 0b111,
Num_Memory
};
char const* str_memory( Memory mem )
{
char const* mem_to_str[Num_Memory] =
{
"BX + SI",
"BX + DI",
"BP + SI",
"BP + DI",
"SI",
"DI",
"BP",
"BX"
};
return mem_to_str[ mem ];
}
char const* str_memory_intuitive( Memory mem )
{
char const* mem_to_str[Num_Memory] =
{
"Base.16 + Stack.Index",
"Base.16 + Destination.Index",
"Stack.Base + Stack.Index",
"Stack.Base + Destination.Index",
"Stack.Index",
"Destination.Index",
"Stack.Base",
"BX"
};
return mem_to_str[ mem ];
}
}
namespace Register
{
ct u8 Mask_Imme = 0b00000111;
ct u8 Mask_Left = 0b00111000;
ct u8 Mask_Right = 0b00000111;
#define D_Opcodes \
D_Entry( AL ) \
D_Entry( CL ) \
D_Entry( DL ) \
D_Entry( BL ) \
D_Entry( AH ) \
D_Entry( CH ) \
D_Entry( DH ) \
D_Entry( BH ) \
D_Entry( AX ) \
D_Entry( CX ) \
D_Entry( DX ) \
D_Entry( BX ) \
D_Entry( SP ) \
D_Entry( BP ) \
D_Entry( SI ) \
D_Entry( DI ) \
enum Type : u8
{
AL = 0b000,
CL = 0b001,
DL = 0b010,
BL = 0b011,
AH = 0b100,
CH = 0b101,
DH = 0b110,
BH = 0b111,
AX = 0b000,
CX = 0b001,
DX = 0b010,
BX = 0b011,
SP = 0b100,
BP = 0b101,
SI = 0b110,
DI = 0b111,
Num = 16
};
char const* meumonic( Type type, u8 Width )
{
static char const*
Type_To_Meumonic[ Num ] =
{
#define D_Entry( Entry_ ) #Entry_,
D_Opcodes
#undef D_Entry
};
return Type_To_Meumonic[ type + Width * ( 7 + 1 ) ];
}
char const* intuitive( Type type, u8 Width )
{
static char const*
Type_To_Intuitive[ Num ] =
{
"Accumulator.Low",
"Count.Low",
"Data.Low",
"Base.Low",
"Accumulator.High",
"Count.High",
"Data.High",
"Base.High",
"Accumulator.16",
"Count.16",
"Data.16",
"Base.16",
"Stack.Pointer",
"Stack.Base",
"Source.Index",
"Destination.Index",
};
return Type_To_Intuitive[ type + Width * ( 7 + 1 ) ];
}
}
struct Octal
{
u8 Low : 3;
u8 High : 3;
u8 Dir : 1;
u8 Write : 1;
operator u8()
{
return * cast( u8*, this);
}
};
struct POD_Instruction
{
// 8086 Instructions are 1 to 6 bytes in length.
union
{
u8* Ptr;
u8 Byte[6];
Octal Instr;
struct
{
u8 Pad[2];
u16_Split Disp;
u16_Split Data;
}
EffAddr;
struct
{
u8 Pad[1];
u16_Split Data;
}
Imme;
struct
{
u8 Pad;
u16_Split Data;
}
Addr;
};
// If directly referencing blob data:
// Part of next instruction, do not use as stratch memory.
u16 Pad;
};
struct Instruction : public POD_Instruction
{
using Code = Op::Code;
using Direction = Field::Direction;
using Mode = Field::Mode;
using Memory = Field::Memory;
using Width = Field::Width;
using Reg = Register::Type;
inline
Direction get_direction()
{
Direction direction = cast(Direction, Byte[0] & Field::Mask_Dir);
return direction;
}
inline
Mode get_mode()
{
Mode mode = cast( Mode, Byte[1] & Field::Mask_Mode );
return mode;
}
inline
Code get_opcode( u8 mask )
{
Op::Code opcode = cast( Op::Code, Byte[0] & mask );
return opcode;
}
inline
Width get_width( u8 mask )
{
Width width = cast( Width, Byte[0] & mask );
return width;
}
inline
Reg mode_operand_left_reg()
{
u8
operand = Byte[1] & Register::Mask_Left;
operand >>= 3;
return cast(Reg, operand);
}
inline
Reg mode_operand_right_reg()
{
u8 operand = Byte[1] & Register::Mask_Right;
return cast( Reg, operand );
}
forceinline
void dissassemble_mode( char const*& str_operand, Width& width, u8& length )
{
using namespace Field;
using namespace Op;
using namespace Register;
switch ( get_mode() )
{
case Mode_Mem:
{
Memory operand_right = cast( Memory, Byte[1] & Mask_Memory );
length += 2;
if ( operand_right == Add_Direct )
{
u16 address = EffAddr.Disp;
str_operand = string_format( "[ %u ]", address );
}
else
{
str_operand = str_memory( operand_right );
}
}
break;
case Mode_Mem8:
{
Memory operand_right = cast( Memory, Byte[1] & Mask_Memory );
length += 1;
str_operand = string_format( "[ %s + %u ]", str_memory( operand_right), EffAddr.Disp.Low );
}
break;
case Mode_Mem16:
{
length += 2;
Memory operand_right = cast( Memory, Byte[1] & Mask_Memory );
u16 address = EffAddr.Disp;
str_operand = string_format( "[ %s + %u ]", str_memory( operand_right), address );
}
break;
case Mode_Reg:
str_operand = Register::meumonic( mode_operand_right_reg(), width );
break;
}
}
u8 dissassemble( zpl_string* result_out )
{
using namespace Field;
using namespace Op;
using namespace Register;
u8 length = 1;
zpl_string assembly = string_make( 32);
Code code = get_opcode( Op::Mask );
Direction dir = get_direction();
char const* str_operand_left = nullptr;
char const* str_operand_right = nullptr;
const u8 code_low = Byte[0] & Op::Mask_Low;
const u8 code_high = Byte[0] & Op::Mask_High;
const u8 sig_imme = Byte[0] & Op::Mask_Imme;
if ( get_opcode( Op::Mask_Low ) == mov_Im_R )
{
Width width = get_width( Mask_Width_Imme );
Reg reg = cast(Reg, Byte[0] & Register::Mask_Right );
u16 immediate = width == Width_Byte ?
Imme.Data.Low : Imme.Data;
str_operand_left = Register::meumonic( reg, width );
str_operand_right = string_format( "%u", immediate );
}
else
{
switch ( code )
{
#pragma region mov
case mov_RM_R:
{
length++;
Width width = get_width( Mask_Width );
str_operand_left = Register::meumonic( mode_operand_left_reg(), width );
dissassemble_mode( str_operand_right, width, length );
}
break;
case mov_Im_RM:
{
Width width = get_width( Mask_Width_Imme );
Memory operand_left = cast( Memory, Byte[1] & Mask_Memory );
u16 address = EffAddr.Disp;
u16 immediate = width == Width_Byte ?
EffAddr.Data.Low : EffAddr.Data;
dissassemble_mode( str_operand_left, width, length );
str_operand_right = string_format( "%u", immediate );
}
break;
case mov_M_Acc:
{
Width width = get_width( Mask_Width );
u16 address = width == Width_Byte ?
Addr.Data.Low : Addr.Data;
str_operand_left = Register::meumonic( Reg::AX, Width_Word );
str_operand_right = string_format( "%u", address );
}
break;
case mov_Acc_M:
{
Width width = get_width( Mask_Width );
u16 address = width == Width_Byte ?
Addr.Data.Low : Addr.Data;
str_operand_right = string_format( "%u", address );
str_operand_left = Register::meumonic( Reg::AX, Width_Word );
}
break;
case mov_RM_SR:
{
}
break;
case mov_SR_RM:
{
}
break;
#pragma endregion mov
}
}
assembly = string_format( assembly, 32, "\n%s %s, %s"
// opcode operand_right, operand_left
, Op::meumonic( code)
, str_operand_right
, str_operand_left
);
if ( result_out == nullptr )
return length;
if ( * result_out == nullptr )
* result_out = string_make( zpl_kilobytes(1) );
* result_out = string_append( * result_out, assembly );
zpl_printf("\n\nAssembly: %s\n\n", assembly);
return length;
}
};
namespace Tests
{
void try_mock_instruction()
{
using namespace Field;
using namespace Op;
using namespace Register;
Instruction
mock; // mov CX, BX
mock.Byte[0] = mov_RM_R | Dir_Src | Field::Width_Word;
mock.Byte[1] = Field::Mode_Reg | offset_left_reg(BX) | CX;
zpl_printf("\n\nAttempting Mock Instruction: mov CX, BX");
print_nl();
print_as_binary( & mock.Byte[0], 1, " " );
print_as_binary( & mock.Byte[1], 1, " " );
print_nl();
zpl_string dissasembly = nullptr;
mock.dissassemble( & dissasembly);
}
void try_blob_single_move()
{
zpl_printf("\n\nAttempting to read blob: listing_0037_single_register_mov");
zpl_file_contents
blob = zpl_file_read_contents( g_allocator, false, "tests/listing_0037_single_register_mov" );
if (blob.data == nullptr )
return;
u32 left = blob.size;
u8* data = cast( u8*, blob.data );
print_nl();
print_as_binary( data, left, " " );
print_nl();
zpl_string dissasembly = nullptr;
Instruction
instr;
instr.Byte[0] = data[0];
instr.Byte[1] = data[1];
instr.dissassemble( & dissasembly);
}
void try_blob_many_moves()
{
zpl_printf("\n\nAttempting to read blob: listing_0038_many_register_mov");
zpl_file_contents
blob = zpl_file_read_contents( g_allocator, false, "tests/listing_0038_many_register_mov" );
if (blob.data == nullptr )
return;
u32 left = blob.size;
u8* data = cast( u8*, blob.data );
print_nl();
print_as_binary( data, left, " " );
print_nl();
zpl_string dissasembly = string_make( "bits 16\n");
while ( left )
{
Instruction
instr;
instr.Byte[0] = data[0];
instr.Byte[1] = data[1];
instr.dissassemble( & dissasembly);
data += 2;
left -= 2;
}
zpl_printf("\n\nDissassemlby:\n%s", dissasembly);
dissasembly = zpl_string_append_fmt( dissasembly, "\n" );
zpl_printf("\n\nSaving to file");
zpl_file_write_contents("tests/listing_0038_many_register_mov.out.asm"
, dissasembly
, zpl_string_length(dissasembly)
, nullptr
);
}
void try_blob_more_moves()
{
zpl_printf("\n\nAttempting to read blob: listing_0039_more_movs");
zpl_file_contents
blob = zpl_file_read_contents( g_allocator, false, "tests/listing_0039_more_movs" );
if (blob.data == nullptr )
return;
u32 left = blob.size;
u8* data = cast( u8*, blob.data );
print_nl();
print_as_binary( data, left, " " );
print_nl();
zpl_string dissasembly = string_make( "bits 16\n");
while ( left )
{
Instruction
instr;
instr.Ptr = data;
u8 length = instr.dissassemble( & dissasembly);
data += length;
left -= length;
}
zpl_printf("\n\nDissassemlby:\n%s", dissasembly);
dissasembly = zpl_string_append_fmt( dissasembly, "\n" );
zpl_printf("\n\nSaving to file");
zpl_file_write_contents("tests/listing_0039_more_movs.asm.out.asm"
, dissasembly
, zpl_string_length(dissasembly)
, nullptr
);
}
}
int main()
{
zpl_printf("sim 8086!");
setup();
f64 start = zpl_time_rel();
// Tests::try_blob_single_move();
// Tests::try_blob_many_moves();
Tests::try_blob_more_moves();
f64 end = zpl_time_rel();
f64 ms = (end - start) * 100;
printf("\n\nElapsed Time: %lf ms", ms);
printf("\n\n");
cleanup();
return 0;
}
@@ -1 +0,0 @@
@@ -1,19 +0,0 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ======================================================================== */
; ========================================================================
; LISTING 37
; ========================================================================
bits 16
mov cx, bx
@@ -1 +0,0 @@
‰Ùˆå‰Ú‰Þ‰ûˆÈˆí‰Ã‰ó‰ü‰Å
@@ -1,29 +0,0 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ======================================================================== */
; ========================================================================
; LISTING 38
; ========================================================================
bits 16
mov cx, bx
mov ch, ah
mov dx, bx
mov si, bx
mov bx, di
mov al, cl
mov ch, ch
mov bx, ax
mov bx, si
mov sp, di
mov bp, ax
@@ -1,13 +0,0 @@
bits 16
mov CX, BX
mov CH, AH
mov DX, BX
mov SI, BX
mov BX, DI
mov AL, CL
mov CH, CH
mov BX, AX
mov BX, SI
mov SP, DI
mov BP, AX
Binary file not shown.
-47
View File
@@ -1,47 +0,0 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 39
; ========================================================================
bits 16
; Register-to-register
mov si, bx
mov dh, al
; 8-bit immediate-to-register
mov cl, 12
mov ch, -12
; 16-bit immediate-to-register
mov cx, 12
mov cx, -12
mov dx, 3948
mov dx, -3948
; Source address calculation
mov al, [bx + si]
mov bx, [bp + di]
mov dx, [bp]
; Source address calculation plus 8-bit displacement
mov ah, [bx + si + 4]
; Source address calculation plus 16-bit displacement
mov al, [bx + si + 4999]
; Dest address calculation
mov [bx + di], cx
mov [bp + si], cl
mov [bp], ch
@@ -1,43 +0,0 @@
bits 16
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
INVALID VALUE PROVIDED (null),
Binary file not shown.
@@ -1,38 +0,0 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 40
; ========================================================================
bits 16
; Signed displacements
mov ax, [bx + di - 37]
mov [si - 300], cx
mov dx, [bx - 32]
; Explicit sizes
mov [bp + di], byte 7
mov [di + 901], word 347
; Direct address
mov bp, [5]
mov bx, [3458]
; Memory-to-accumulator test
mov ax, [2555]
mov ax, [16]
; Accumulator-to-memory test
mov [2554], ax
mov [15], ax
-58
View File
@@ -1,58 +0,0 @@
<?xml version="1.0"?>
<N10X>
<Workspace>
<IncludeFilter>*.*,</IncludeFilter>
<ExcludeFilter>*.obj,*.lib,*.pch,*.dll,*.pdb,.vs,Debug,Release,x64,obj,*.user,Intermediate,</ExcludeFilter>
<SyncFiles>true</SyncFiles>
<Recursive>true</Recursive>
<ShowEmptyFolders>true</ShowEmptyFolders>
<IsVirtual>false</IsVirtual>
<IsFolder>false</IsFolder>
<BuildCommand>.\build.bat</BuildCommand>
<RebuildCommand></RebuildCommand>
<BuildFileCommand></BuildFileCommand>
<CleanCommand>.\clean.bat</CleanCommand>
<BuildWorkingDirectory>.\part_1</BuildWorkingDirectory>
<CancelBuild></CancelBuild>
<RunCommand>part_1/build/sim_8086.exe</RunCommand>
<DebugCommand>part_1/build/sim_8086.exe</DebugCommand>
<ExePathCommand>part_1/build/sim_8086.exe</ExePathCommand>
<DebugSln></DebugSln>
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
<Configurations>
<Configuration>Debug</Configuration>
<Configuration>Release</Configuration>
</Configurations>
<Platforms>
<Platform>x64</Platform>
</Platforms>
<AdditionalIncludePaths>
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\include</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\ATLMFC\include</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
</AdditionalIncludePaths>
<Defines></Defines>
<ConfigProperties>
<ConfigAndPlatform>
<Name>Debug:x64</Name>
<Defines></Defines>
<ForceIncludes></ForceIncludes>
</ConfigAndPlatform>
<Config>
<Name>Debug</Name>
<Defines></Defines>
</Config>
<Platform>
<Name>x64</Name>
<Defines></Defines>
</Platform>
</ConfigProperties>
<Children></Children>
</Workspace>
</N10X>
+9
View File
@@ -0,0 +1,9 @@
// raddbg 0.9.28 project file
target:
{
executable: "build/sim_8086.exe"
working_directory: ""
enabled: 1
label: "Sim 8086"
}
+375
View File
@@ -0,0 +1,375 @@
$path_root = split-path -Path $PSScriptRoot -Parent
$path_build = join-path $path_root 'build'
$path_code = join-path $path_root 'code'
$path_duffle = join-path $path_code 'duffle'
$path_8086 = join-path $path_code '8086'
$path_part_1 = join-path $path_code 'part_1'
$path_scripts = join-path $path_root 'scripts'
$path_toolchain = join-path $path_root 'toolchain'
if ((test-path $path_build) -eq $false) {
new-item -itemtype directory -path $path_build
}
# --- Toolchain Definition ---
# All tools default to LLVM/clang. The MIPS variables are kept for
# catalog parity with C:\projects\Pikuma\ps1\scripts\build_psyq.ps1,
# but are not used by the current Win32 build.
$compiler = "clang"
$linker = 'lld-link.exe'
$objcopy = 'llvm-objcopy'
$archiver = 'llvm-ar'
# --- Compiler Flags: General / Compilation Mode ---
$f_compile = '-c' # Compile to .o (no link)
$f_output = '-o' # Output path
$f_preprocess = '-E' # Preprocess to stdout
$f_syntax_only = '-fsyntax-only' # Parse + type-check, no codegen
$f_save_temps = '-save-temps' # Keep intermediate files
$f_show_includes = '-H' # Print include chain
$f_dependency_file = '-MF' # Write dep file (use with -MD)
$f_dependency_gen = '-MD' # Generate dep file alongside output
$f_emit_llvm = '-emit-llvm' # Emit LLVM IR
# --- Compiler Flags: Language Standard ---
$f_std_c11 = '-std=c11'
$f_std_c17 = '-std=c17'
$f_std_c23 = '-std=c23'
$f_std_gnu11 = '-std=gnu11'
$f_std_gnu17 = '-std=gnu17'
$f_std_gnu23 = '-std=gnu23'
$f_std_cpp17 = '-std=c++17'
$f_std_cpp20 = '-std=c++20'
$f_std_cpp23 = '-std=c++23'
$f_all_c = '-x','c' # Force C language
$f_all_cpp = '-x','c++' # Force C++ language
$f_all_asm = '-x','assembler' # Force asm
$f_all_asm_with_cpp = '-x','assembler-with-cpp'
# --- Compiler Flags: Preprocessor ---
$f_define = '-D' # #define NAME[=VALUE]
$f_undef = '-U' # #undef NAME
$f_include = '-I' # Add directory to search path
$f_include_system = '-isystem' # System header (suppresses warnings)
$f_include_quote = '-iquote' # Quote-only header path
$f_include_after = '-idirafter' # Append dir to search path
$f_include_file = '-include' # Force include file
$f_no_stdinc = '-nostdinc' # No standard include paths
$f_charset_utf8 = '-utf-8' # Source charset = UTF-8
# --- Compiler Flags: Warnings ---
# https://clang.llvm.org/docs/DiagnosticsReference.html
$f_wall = '-Wall'
$f_wextra = '-Wextra'
$f_werror = '-Werror'
$f_warnings_as_errors = '-Werror'
$f_wno_attributes = '-Wno-attributes'
$f_warnings_ignore = '-Wno-' # Prefix; usage: $f_warnings_ignore + 'unused'
$f_wno_unused_function = '-Wno-unused-function'
$f_wno_unused_variable = '-Wno-unused-variable'
$f_wno_switch = '-Wno-switch'
$f_wno_uninitialized = '-Wno-uninitialized'
$f_wno_implicit_function_declaration = '-Wno-implicit-function-declaration'
$f_wno_ms_include = '-Wno-microsoft-include'
$f_wno_return_type_c_linkage = '-Wno-return-type-c-linkage'
$f_wno_main_return_type = '-Wno-main-return-type'
$f_warning = '-W' # Prefix; usage: $f_warning + 'switch'
$f_pedantic = '-Wpedantic'
$f_doc_warnings = '-Wdocumentation'
# --- Compiler Flags: Optimization ---
$f_optimize_none = '-O0' # No optimization (debug default)
$f_optimize_debug = '-Og' # Optimize for debug
$f_optimize_size = '-Os' # Optimize for size
$f_optimize_fast = '-O2' # Optimize for speed (default release)
$f_optimize_max = '-O3' # Aggressive optimization
$f_optimize_intrinsics = '-Oi' # MSVC intrinsic hints (clang accepts; semantics ~ -O2)
$f_optimize_all = '-Ofast' # -O3 + non-IEEE-compliant math
$f_omit_frame_ptr = '-fomit-frame-pointer'
$f_no_omit_frame_ptr = '-fno-omit-frame-pointer'
$f_lto = '-flto' # Link-time optimization
$f_lto_thin = '-flto=thin'
# --- Compiler Flags: Debug / Profile ---
$f_debug = '-g' # Debug info (default DWARF)
$f_debug_codeview = '-gcodeview' # CodeView debug format (MS tools)
$f_debug_dwarf_4 = '-gdwarf-4' # Specific DWARF version
$f_debug_dwarf_5 = '-gdwarf-5'
$f_debug_line_tables_only = '-gline-tables-only'
$f_profiling_debug = '-fdebug-info-for-profiling'
$f_time_trace = '-ftime-trace' # Emit Chrome trace JSON
$f_coverage_generate = '-fprofile-instr-generate'
$f_coverage_use = '-fprofile-instr-use='
# --- Compiler Flags: Code Generation ---
$f_no_color_diagnostics = '-fno-color-diagnostics'
$f_color_diagnostics = '-fcolor-diagnostics'
$f_diagnostics_absolute = '-fdiagnostics-absolute-paths'
$f_exceptions_disabled = '-fno-exceptions'
$f_exceptions_enabled = '-fexceptions'
$f_RTTI_disabled = '-fno-rtti'
$f_RTTI_enabled = '-frtti'
$f_section_data = '-fdata-sections'
$f_section_functions = '-ffunction-sections'
$f_no_strict_alias = '-fno-strict-aliasing'
$f_strict_aliasing = '-fstrict-aliasing'
$f_signed_char = '-fsigned-char'
$f_unsigned_char = '-funsigned-char'
$f_pic = '-fPIC' # Position-independent code
$f_pie = '-fPIE' # Position-independent executable
$f_no_pic = '-fno-pic'
$f_no_pie = '-fno-pie'
$f_visible_hidden = '-fvisibility=hidden'
$f_visible_default = '-fvisibility=default'
$f_align_functions = '-falign-functions='
$f_align_loops = '-falign-loops='
$f_ms_extensions = '-fms-extensions' # Allow MSVC language extensions
$f_ms_compatibility = '-fms-compatibility'
$f_ms_runtime_lib_none = '-fno-ms-runtime'
$f_preprocess_non_integrated = '-no-integrated-cpp'
$f_stack_protector = '-fstack-protector'
$f_stack_protector_strong = '-fstack-protector-strong'
$f_stack_protector_all = '-fstack-protector-all'
$f_vptr = '-fvirtual-function-elimination'
$f_vectorize = '-vectorize-loops'
$f_vectorize_slp = '-vectorize-slp'
# --- Compiler Flags: Sanitizers ---
$f_sanitize_address = '-fsanitize=address'
$f_sanitize_undefined = '-fsanitize=undefined'
$f_sanitize_thread = '-fsanitize=thread'
$f_sanitize_memory = '-fsanitize=memory'
$f_sanitize_hwaddress = '-fsanitize=hwaddress'
$f_sanitize_address_safe = '-fsanitize=address,safe-stack'
$f_sanitize_cfi = '-fsanitize=cfi'
# --- Compiler Flags: Environment / Target ---
$f_no_stdlib = '-nostdlib'
$f_freestanding = '-ffreestanding'
$f_no_builtin = '-fno-builtin'
$f_target_arch = '-target' # Usage: $f_target_arch + 'x86_64-pc-windows-msvc'
$f_target_abi = '-mabi='
$f_target_march = '-march='
$f_target_mtune = '-mtune='
$f_target_mcpu = '-mcpu='
$f_target_mfloat_abi = '-mfloat-abi='
$f_target_x86 = '-m64'
$f_target_x86_32 = '-m32'
$f_target_arm = '-marm'
$f_target_thumb = '-mthumb'
# --- Compiler Flags: Verbosity / Misc ---
$f_verbose = '-v'
$f_set_stack_size = '-stack=' # Stack size (linker-side, but accepted by clang)
$f_symbol_prefix = '-femit-all-decls'
# --- Compiler Flags: MIPS Architecture (catalog parity with ps1/build_psyq.ps1) ---
# Used by the PS1 cross-compile path (C:\projects\Pikuma\ps1). Not used by
# the current Win32 build. Kept here so the catalog is complete.
$f_arch_mips1 = '-march=mips1'
$f_arch_mips2 = '-march=mips2'
$f_arch_mips3 = '-march=mips3'
$f_arch_abi32 = '-mabi=32'
$f_arch_abi64 = '-mabi=64'
$f_arch_little_endian = '-EL'
$f_arch_big_endian = '-EB'
$f_arch_fp32 = '-mfp32'
$f_arch_no_pic = '-fno-pic'
$f_arch_no_shared = '-mno-shared'
$f_arch_no_abicalls = '-mno-abicalls'
$f_arch_no_llsc = '-mno-llsc'
$f_arch_no_gpopt = '-mno-gpopt'
$f_arch_no_stack_prot = '-fno-stack-protector'
# --- Linker Flags (passed via -Wl, to clang; or directly to gcc-style linkers) ---
# These are GNU ld-style flags. When invoking lld-link.exe directly, prefer
# the Win32-flavored flags below.
$f_linker = '-Wl,' # Prefix; usage: $f_linker + '--gc-sections'
$f_link_mapfile = '--Map=' # Output map file (GNU ld)
$f_link_gc_sections = '--gc-sections' # Dead-strip unused sections
$f_link_format = '--oformat=' # Output format (e.g. elf32-littlemips)
$f_link_start_group = '--start-group' # Circular library resolution
$f_link_end_group = '--end-group'
$f_link_static = '-static' # Static linking
$f_link_script = '-T' # Linker script
$f_link_lib_path = '-L' # Library search path
$f_link_lib = '-l' # Library shorthand (foo.lib -> -lfoo)
$f_link_relaxable = '--relax' # Enable linker relaxation
$f_link_strip_all = '-s' # Strip all symbols
$f_link_strip_debug = '-S' # Strip debug symbols
$f_link_no_undefined = '--no-undefined' # Error on unresolved symbols
$f_link_undefined = '-u' # Force a symbol to be defined
$f_link_version_script = '--version-script='
$f_link_entry = '-e' # Entry point (GNU ld)
$f_link_hash_style = '--hash-style='
$f_link_as_needed = '--as-needed'
$f_link_no_as_needed = '--no-as-needed'
# --- Linker Flags (Win32 lld-link, used directly) ---
# https://lld.llvm.org/windows_support.html
$f_nologo = '/NOLOGO'
$f_link_win_no_incremental = '/INCREMENTAL:NO'
$f_link_win_no_default_lib = '/NODEFAULTLIB'
$f_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE'
$f_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS'
$f_link_win_subsystem_efi_app = '/SUBSYSTEM:EFI_APPLICATION'
$f_link_win_subsystem_native = '/SUBSYSTEM:NATIVE'
$f_link_win_machine_32 = '/MACHINE:X86'
$f_link_win_machine_64 = '/MACHINE:X64'
$f_link_win_machine_arm = '/MACHINE:ARM'
$f_link_win_machine_arm64 = '/MACHINE:ARM64'
$f_link_win_debug = '/DEBUG'
$f_link_win_pdb = '/PDB:'
$f_link_win_path_output = '/OUT:'
$f_link_win_map = '/MAP:'
$f_link_win_entry = '/ENTRY:'
$f_link_win_lib_path = '/LIBPATH:'
$f_link_win_default_lib = '/DEFAULTLIB:'
$f_link_win_dll = '/DLL'
$f_link_win_optimize_ref = '/OPT:REF' # Eliminate unreferenced data/functions
$f_link_win_optimize_no_icf = '/OPT:NOICF' # Disable identical COMDAT folding
$f_link_win_optimize_no_ref = '/OPT:NOREF' # Disable dead-strip
$f_link_win_stack = '/STACK:'
$f_link_win_heap = '/HEAP:'
$f_link_win_merge = '/MERGE:'
$f_link_win_align = '/ALIGN:'
$f_link_win_base = '/BASE:'
$f_link_win_version = '/VERSION:'
$f_link_win_dynamic_base = '/DYNAMICBASE'
$f_link_win_release = '/RELEASE'
$f_link_win_force = '/FORCE'
$f_link_win_verbose = '/VERBOSE'
$f_link_win_wholearchive = '/WHOLEARCHIVE:'
$f_link_win_export = '/EXPORT:'
$f_link_win_delay_load = '/DELAYLOAD:'
$f_link_win_import = '/IMPORT:'
$f_link_win_def = '/DEF:'
$f_link_win_manifest = '/MANIFEST'
$f_link_win_manifest_no = '/MANIFEST:NO'
$f_link_win_manifest_uac = '/MANIFESTUAC:'
$f_link_win_manifest_input = '/MANIFESTINPUT:'
$f_link_win_section = '/SECTION:'
$f_link_win_swaprun = '/SWAPRUN'
$f_link_win_driver = '/DRIVER'
$f_link_win_large_address_aware = '/LARGEADDRESSAWARE'
$f_link_win_fail_if_mismatch = '/FAILIFMISMATCH'
$f_link_win_through = '/THREADOPT'
$f_link_win_error_report = '/ERRORREPORT'
$f_link_win_repro = '/BREPRO'
$f_link_win_safeseh = '/SAFESEH'
$f_link_win_guard_cf = '/GUARD:CF'
$f_link_win_guard_no_cf = '/GUARD:NOCF'
$f_link_win_pgo_run = '/USEPROFILE'
$f_link_win_pgo_gen = '/PROFILE'
$f_link_win_idl = '/IDLOUT:'
$f_link_win_delay_unload = '/DELAY:UNLOAD'
$f_link_win_compat_property = '/CETCOMPAT'
$f_link_win_debug_fastlink = '/DEBUG:FASTLINK'
$f_link_win_lib_list = '/LIB'
# --- Objcopy Flags ---
$f_objcopy_format = '-O' # Output format
$f_objcopy_add_section = '--add-section'
$f_objcopy_update_section = '--update-section'
$f_objcopy_set_section_flags = '--set-section-flags'
# --- Baseline Libraries (lld-link, Win32) ---
$libraries_win32 = @(
'kernel32.lib'
'user32.lib'
'gdi32.lib'
'vcruntime.lib'
)
# --- Functions ---
function compile-unit {
param(
[string] $unit,
[string] $link_module,
[string[]] $include_paths,
[string[]] $user_compile_args
)
$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_debug
foreach ($p in $include_paths) {
$compile_args += ($f_include + $p)
}
$compile_args += $user_compile_args
$compile_args += $f_compile
$compile_args += $unit
$compile_args += ($f_output + $link_module)
write-host "Compiling '$unit' -> '$link_module'" -ForegroundColor DarkCyan
$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 }
}
function link-modules {
param(
[string[]] $link_modules,
[string] $module,
[string] $pdb,
[string[]] $user_link_args
)
$base_name = [System.IO.Path]::GetFileNameWithoutExtension($module)
$map = join-path $path_build "$base_name.map"
$link_args = @()
$link_args += $f_nologo
$link_args += $f_link_win_no_default_lib
$link_args += $f_link_win_machine_64
$link_args += $f_link_win_no_incremental
$link_args += ($f_link_win_path_output + $module)
$link_args += $f_link_win_subsystem_console
$link_args += $f_link_win_debug
$link_args += ($f_link_win_entry + 'main')
$link_args += ($f_link_win_pdb + $pdb)
$link_args += ($f_link_win_map + $map)
foreach ($lib in $libraries_win32) {
$link_args += $lib
}
$link_args += $link_modules
$link_args += $user_link_args
write-host "Linking modules into '$module'" -ForegroundColor DarkCyan
$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 }
}
function build-part_1 {
# The base lib uses subdir-prefixed includes (e.g. "duffle/dsl.h"),
# so the include root is <code>, not <code>/duffle.
$includes = @(
$path_code
)
$source_c = join-path $path_part_1 'sim_8086.c'
$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
$pdb = join-path $path_build 'sim_8086.pdb'
$exe = join-path $path_build 'sim_8086.exe'
link-modules $module_c $exe $pdb @()
}
build-part_1
+76
View File
@@ -0,0 +1,76 @@
function clone-gitrepo { param( [string] $path, [string] $url, [switch] $NoPull )
if (test-path $path) {
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 ..."
git clone --recursive $url $path
}
}
function Update-GitRepo
{
param( [string] $path, [string] $url, [string] $build_command )
if ( $build_command -eq $null ) {
write-host "Attempted to call Update-GitRepo without build_command specified"
return
}
$repo_name = $url.Split('/')[-1].Replace('.git', '')
$last_built_commit = join-path $path_build "last_built_commit_$repo_name.txt"
if ( -not(test-path -Path $path))
{
write-host "Cloining repo from $url to $path"
git clone $url $path
write-host "Building $url"
push-location $path
& "$build_command"
pop-location
git -C $path rev-parse HEAD | out-file $last_built_commit
$script:binaries_dirty = $true
write-host
return
}
git -C $path fetch
$latest_commit_hash = git -C $path rev-parse '@{u}'
$last_built_hash = if (Test-Path $last_built_commit) { Get-Content $last_built_commit } else { "" }
if ( $latest_commit_hash -eq $last_built_hash ) {
write-host
return
}
write-host "Build out of date for: $path, updating"
write-host 'Pulling...'
git -C $path pull
write-host "Building $url"
push-location $path
& $build_command
pop-location
$latest_commit_hash | out-file $last_built_commit
$script:binaries_dirty = $true
write-host
}
function verify-path { param( $path )
if (test-path $path) {return $true}
new-item -ItemType Directory -Path $path
return $false
}
+25
View File
@@ -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.'
-100
View File
@@ -1,100 +0,0 @@
# Format Style Options - Created with Clang Power Tools
---
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Right
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
AlignCompound: true
PadOperators: true
AlignConsecutiveBitFields: AcrossComments
AlignConsecutiveDeclarations: AcrossComments
AlignConsecutiveMacros: AcrossComments
AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortLambdasOnASingleLine: None
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BeforeLambdaBody: false
BeforeWhile: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: true
BreakInheritanceList: BeforeColon
BreakBeforeConceptDeclarations: true
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
ColumnLimit: 180
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth : 4
ContinuationIndentWidth: 4
DeriveLineEnding: true
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IncludeBlocks: Preserve
IndentCaseBlocks: true
IndentCaseLabels: true
IndentExternBlock: Indent
IndentGotoLabels: false
IndentPPDirectives: None
IndentRequires: false
IndentWidth: 4
IndentWrappedFunctionNames: false
Language: Cpp
NamespaceIndentation: All
PointerAlignment: Left
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: true
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: After
SpaceBeforeCaseColon: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: true
SpaceInEmptyParentheses: false
SpacesInAngles: true
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: true
SpacesInParentheses: true
SpacesInSquareBrackets: true
Standard: c++17
TabWidth: 4
UseTab: ForIndentation
...
-82
View File
@@ -1,82 +0,0 @@
<#
.DESCRIPTION
Helper script to format all header and source files in the repository.
By default, the script will recursively search under the repo root for
files to format. Users can give explicit parameters indicating how the
search should include and exclude filetypes.
If users don't want the search functionality, they can instead provide
an explicit list of files to format.
.PARAMETER RepoRoot
Full path to the root of the repository which is the target of the search.
Will default to the root of the current working directory.
.PARAMETER Include
Array of filetype extensions to target for formatting.
By default, targets standard extensions for header and source files.
Follows the same rules as the -Include parameter for Get-ChildItem.
.PARAMETER Exclude
Array of filetype extensions to exclude from formatting.
By default, excludes generated XAML files.
Follows the same rules as the -Exclude paramter for Get-ChildItem.
.PARAMETER Files
Array of files to format. The script will exit if one of the provided
filepaths does not exist.
.EXAMPLE
.\clang-format-all.ps1
Formats all header and source files under the repository root.
.EXAMPLE
.\clang-format-all.ps1 -RepoRoot 'S:\repos\calculator' -Include '*.h', '*.cpp' -Exclude '*.g.*'
Formats all *.h and *.cpp files under 'S:\repos\calculator', excluding files with an extension
like *.g.*
.EXAMPLE
.\clang-format-all.ps1 -File 'S:\repos\calculator\src\CalcViewModel\UnitConverterViewModel.h', 'S:\repos\calculator\src\CalcViewModel\MemoryItemViewModel.cpp'
Formats the specified files.
#>
[CmdletBinding( DefaultParameterSetName = 'Search' )]
param(
[Parameter( ParameterSetName = 'Search' )]
[ValidateScript({ Test-Path -PathType Container -Path $_ })]
[string] $RepoRoot = "$( (Get-Item .).FullName )/thirdparty",
[Parameter( ParameterSetName = 'Search' )]
[string[]] $Include = ( '*.h', '*.hh', '*.hpp', '*.c', '*.cc', '*.cpp' ),
[Parameter( ParameterSetName = 'Search' )]
[string[]] $Exclude = ( '*.g.*', "zpl.h" ),
[Parameter(
ParameterSetName = 'Explicit',
Mandatory)]
[ValidateScript({
$_ | Where-Object { -not (Test-Path -PathType Leaf -Path $_) } |
ForEach-Object { throw "Could not find file: [$_]" }
return $true
})]
[string[]] $Files
)
if ($PSCmdlet.ParameterSetName -eq 'Explicit')
{
# Use the file paths we were given.
$targetFiles = @($Files)
}
else
{
# Gather the files to be formatted.
$targetFiles = @(
Get-ChildItem -Recurse -Path $RepoRoot -Include $Include -Exclude $Exclude |
Select-Object -ExpandProperty FullName
)
}
# Format the files.
$formatParams = @(
'-i' # In-place
'-style=file' # Search for a .clang-format file in the parent directory of the source file.
'-verbose'
)
if ( $targetFiles )
{
clang-format $formatParams $targetFiles
}
-18369
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff