diff --git a/.gitignore b/.gitignore index e69de29..4fcb459 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +build diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index b084de1..f46aa00 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,9 +3,10 @@ { "name": "The Usual (clang)", "includePath": [ - "${workspaceFolder}/8086", - "${workspaceFolder}/duffle", - "${workspaceFolder}/part_1" + "${workspaceFolder}/code/", + "${workspaceFolder}/code/8086", + "${workspaceFolder}/code/duffle", + "${workspaceFolder}/code/part_1" ], "defines": [ "BUILD_DEBUG", diff --git a/code/duffle/analysis.h b/code/duffle/analysis.h new file mode 100644 index 0000000..143057d --- /dev/null +++ b/code/duffle/analysis.h @@ -0,0 +1,17 @@ +#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 +#pragma endregion Debug diff --git a/code/duffle/dsl.h b/code/duffle/dsl.h index 06c57dc..9534456 100644 --- a/code/duffle/dsl.h +++ b/code/duffle/dsl.h @@ -257,12 +257,3 @@ FI_ B8 add_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_saddll_overflow(a, b, FI_ B8 sub_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_ssubll_overflow(a, b, res); } FI_ B8 mul_s_of(S8 a, S8 b, S8*R_ res) { return __builtin_smulll_overflow(a, b, res); } #pragma endregion Math - -#pragma region Debug -#define debug_trap() __builtin_debugtrap() -#if BUILD_DEBUG -FI_ void assert(U8 cond) { if(cond){return;} else{debug_trap(); ms_exit_process(1);} } -#else -#define assert(cond) -#endif -#pragma endregion Debug diff --git a/code/duffle/win32.h b/code/duffle/win32.h index 14f88f7..aec8262 100644 --- a/code/duffle/win32.h +++ b/code/duffle/win32.h @@ -151,3 +151,8 @@ enum { MS_VK_SHIFT =0x10, }; + + +#if BUILD_DEBUG +FI_ void assert(U8 cond) { if(cond){return;} else{debug_trap(); ms_exit_process(1);} } +#endif diff --git a/code/part_1/sim_8086.c b/code/part_1/sim_8086.c index b28b04f..f27836e 100644 --- a/code/part_1/sim_8086.c +++ b/code/part_1/sim_8086.c @@ -1,3 +1,10 @@ +#include "duffle/dsl.h" +#include "duffle/analysis.h" +#include "duffle/memory.h" +#include "duffle/win32.h" - - +int main() +{ + ms_exit_process(0); + return 0; +} diff --git a/scripts/build.ps1 b/scripts/build.ps1 index a87404a..5e0d581 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -1,3 +1,20 @@ +<# +.SYNOPSIS + Build script for the perfaware project (8086 simulator + tooling). + +.DESCRIPTION + Compiles the canonical source tree into a Win32 console executable + using clang and lld-link. No CRT (/ENTRY:main, /NODEFAULTLIB). + + Prerequisites: + - clang on PATH (LLVM install) + - lld-link.exe on PATH (LLVM install) + - Windows SDK (for kernel32.lib, user32.lib, gdi32.lib) + + Build artifacts land in /build/. The script is not + incremental -- every invocation recompiles every source file. +#> + $path_root = split-path -Path $PSScriptRoot -Parent $path_build = join-path $path_root 'build' $path_code = join-path $path_root 'code' @@ -8,160 +25,135 @@ $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 + new-item -itemtype directory -path $path_build } # --- Toolchain Definition --- -# Assumes 'mipsel-none-elf' toolchain is in your system's PATH. $compiler = "clang" $linker = 'lld-link.exe' -# General Compiler Flags -$f_compile = "-c" -$f_debug = "-g" -$f_define = "-D" -$f_include = "-I" -$f_output = "-o" -$f_std_c11 = "-std=c11" -$f_std_c23 = "-std=c23" +# --- Compiler Flags --- +$f_compile = "-c" +$f_debug = "-g" +$f_define = "-D" +$f_include = "-I" +$f_output = "-o" +$f_std_c11 = "-std=c11" +$f_std_c23 = "-std=c23" +$f_wall = "-Wall" +$f_wno_attributes = "-Wno-attributes" +$f_exceptions_disabled = "-fno-exceptions" +$f_diagnostics_absolute = "-fdiagnostics-absolute-paths" +$f_optimize_none = "-O0" +$f_optimize_size = "-Os" +$f_optimize_intrinsics = "-Oi" +$f_optimize_debug = "-Og" +$f_omit_frame_ptr = "-fomit-frame-pointer" +$f_code_sections = "-ffunction-sections" +$f_data_sections = "-fdata-sections" +$f_no_strict_alias = "-fno-strict-aliasing" -$f_exceptions_disabled = '-fno-exceptions' -$f_diagnostics_absolute_paths = '-fdiagnostics-absolute-paths' +# --- Linker Flags (Win32 lld-link) --- +# lld-link takes Win32-style flags directly (no `-Wl,` prefix). +$f_nologo = '/NOLOGO' +$f_no_default_lib = '/NODEFAULTLIB' +$f_link_win_machine_64 = '/MACHINE:X64' +$f_link_no_incremental = '/INCREMENTAL:NO' +$f_link_win_subsystem = '/SUBSYSTEM:CONSOLE' +$f_link_win_debug = '/DEBUG' +$f_link_win_entry = '/ENTRY:' +$f_link_win_pdb = '/PDB:' +$f_link_win_path_output = '/OUT:' +$f_link_win_map = '/MAP:' -# Warning Flags -$f_wall = "-Wall" -$f_wno_attributes = "-Wno-attributes" +# --- Functions --- -# Optimization Flags -$f_optimize_none = "-O0" -$f_optimize_size = "-Os" -$f_optimize_intrinsics = "-Oi" -$f_optimize_debug = "-Og" -$f_omit_frame_ptr = "-fomit-frame-pointer" - -$f_path_output = '-o' -$f_wall = '-Wall' -$f_nologo = '/nologo' - -# Environment & Standard Library Flags -$f_no_stdlib = "-nostdlib" -$f_freestanding = "-ffreestanding" -$f_no_builtin = "-fno-builtin" - -# Linker-related Flags (for Compiler) -$f_code_sections = "-ffunction-sections" -$f_data_sections = "-fdata-sections" -$f_no_strict_alias = "-fno-strict-aliasing" - - -# Linker Flags (passed via -Wl,) - -$f_link_pass_through_prefix = "-Wl," -$f_link_mapfile = "-Map=" # Usage: $flag_link_pass_through_prefix + $flag_link_mapfile + path -$f_link_gc_sections = "--gc-sections" -$f_link_format = "--oformat=" -$f_link_start_group = "--start-group" -$f_link_end_group = "--end-group" -$f_link_static = "-static" -$f_link_script = "-T" -$f_link_lib_path = "-L" -$f_link_lib = "-l" - -$f_link_no_incremental = '/INCREMENTAL:NO' -$f_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' -$f_link_win_machine_64 = '/MACHINE:X64' -$f_link_win_debug = '/DEBUG' -$f_link_win_pdb = '/PDB:' -$f_link_win_path_output = '/OUT:' - -function compile-unit { param( - [string] $unit, - [string] $link_module, - [string[]]$include_paths, - [string[]]$user_compile_args -) - $compile_args = @() - $compile_args += $f_wall - $compile_args += $f_c11 - $compile_args += $f_no_optimization - $compile_args += $f_diagnostics_absolute_paths - $compile_args += $f_exceptions_disabled - # $compiler_args += "-nostdlib" - # $compiler_args += "-ffreestanding" - - $compile_args += $user_compile_args - - $compile_args += $f_compile - $compile_args += $unit, ($f_output + $link_module) +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_wall + $compile_args += $f_wno_attributes + $compile_args += $f_exceptions_disabled + $compile_args += $f_diagnostics_absolute + $compile_args += $f_optimize_none + $compile_args += $f_debug + foreach ($p in $include_paths) { + $compile_args += ($f_include + $p) + } + $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 - # $compile_args | ForEach-Object { Write-Host "`t$_" -ForegroundColor Green } - & $compiler $compile_args + & $compiler $compile_args 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) - $link_args = @() - $link_args = @() - $link_args += $f_nologo - $link_args += $f_link_win_machine_64 - $link_args += $f_link_no_incremental - $link_args += ($f_link_win_path_output + $binary) - $link_args += $f_link_win_debug - $link_args += $f_link_win_pdb + $pdb - $link_args += $f_link_mapfile + $map - $link_args += $f_link_win_subsystem_console - # $link_args += "/nodefaultlib" +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" - $base_name = [System.IO.Path]::GetFileNameWithoutExtension($module) - $map = join-path $path_build "$base_name.map" - $link_args += ($f_link_pass_through_prefix + $f_link_mapfile + $map) + $link_args = @() + $link_args += $f_nologo + $link_args += $f_no_default_lib + $link_args += $f_link_win_machine_64 + $link_args += $f_link_no_incremental + $link_args += ($f_link_win_path_output + $module) + $link_args += $f_link_win_subsystem + $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) - $link_args += ($f_link_pass_through_prefix + $f_link_start_group) - $libraries = @( - 'kernel32.lib', - 'user32.lib', - 'gdi32.lib' - ) - foreach ($lib in $libraries) { - $link_args += ($f_link_lib + $lib) - } + $libraries = @( + 'kernel32.lib', + 'user32.lib', + 'gdi32.lib' + ) + foreach ($lib in $libraries) { + $link_args += $lib + } - $link_args += $link_modules + $link_args += $link_modules + $link_args += $user_link_args - $final_link_args = @($link_args) + ($f_output + $elf) - - write-host "Linking modules into '$elf'" -ForegroundColor DarkCyan - $final_link_args += ($f_link_pass_through_prefix + $f_link_end_group) - # $final_link_args | foreach-object { write-host $_ } - & $linker $final_link_args - if ($LASTEXITCODE -ne 0) { write-error "Linking failed. Aborting."; exit 1 } + write-host "Linking modules into '$module'" -ForegroundColor DarkCyan + & $linker $link_args + if ($LASTEXITCODE -ne 0) { write-error "Linking failed. Aborting."; exit 1 } } function build-part_1 { - $includes = @( - $path_duffle, - $path_8086, - $path_part_1 - ) + # The base lib uses subdir-prefixed includes (e.g. "duffle/dsl.h"), + # so the include root is , not /duffle. + $includes = @( + $path_code + ) - $source_c = join-path $path_part_1 'sim_8086.c' - $module_c = join-path $path_build 'sim_8086.o' + $source_c = join-path $path_part_1 'sim_8086.c' + $module_c = join-path $path_build 'sim_8086.o' - $compile_args = @() - $compile_args += ($flag_define + 'BUILD_DEBUG=1') - $compile_args += $f_debug - $compiler_args += $f_optimize_none - compile-unit $source_c $module_c $includes $compile_args + $compile_args = @() + $compile_args += ($f_define + 'BUILD_DEBUG=1') - $pdb = join-path $path_build 'sim_8086.pdb' - $exe = join-path $path_build 'sim_8086.exe' + compile-unit $source_c $module_c $includes $compile_args - $link_args = @() - $link_args += $f_debug - $link_modules = @( - $module_c - ) - link-modules $link_modules $exe $pdb $link_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