Skip to content

Commit 76aab53

Browse files
committed
📝 docs: add backend architecture and multi-target strategy document
1 parent 1d5fc1b commit 76aab53

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

docs/backend-architecture.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Backend Architecture & Multi-Target Strategy
2+
3+
This document details the architectural strategies for expanding the Ship compiler backend to multiple architectures and operating systems (such as RISC-V and macOS/Mach-O) without compromising compiler simplicity or introducing target contamination.
4+
5+
---
6+
7+
## 1. Decoupling the Intermediate Representation (IR)
8+
9+
To prevent target contamination, the Ship compiler enforces a strict boundary between the frontend/middle-end and the code generation backends:
10+
11+
* **Target-Agnostic IR:** The type checker and AST parser have no knowledge of host registers, page sizes, or executable formats. They emit a flat, linear IR representing 3-address instructions.
12+
* **Modular Code Generation:** Each target (e.g., `compiler/emitter/elf`, `compiler/emitter/macho`) operates solely on the lowered IR. Adding a new architecture only requires consuming this IR.
13+
14+
---
15+
16+
## 2. Register Allocation and Calling Conventions
17+
18+
Currently, the compiler uses a naive stack-allocated register model. To scale performance and support multiple ABIs:
19+
20+
* **Linear Scan Register Allocation (Phase 3):** We will transition from stack-only allocations to a register allocator that maps active IR variables to a target's general-purpose registers (GPRs).
21+
* **Decoupled ABIs:**
22+
* **System V AMD64 ABI (Linux/macOS x86_64):** Arguments passed via `RDI`, `RSI`, `RDX`, `RCX`, `R8`, `R9`.
23+
* **Windows x64 ABI (PE Target):** Arguments passed via `RCX`, `RDX`, `R8`, `R9`.
24+
* **ARM64 AAPCS (Apple Silicon / Linux ARM64):** Arguments passed via `x0` through `x7`.
25+
26+
---
27+
28+
## 3. RISC-V Targeting Strategy
29+
30+
Adding a RISC-V (`RV64GC`) backend is a key milestone for validating our backend decoupling:
31+
32+
* **Simpler ISA:** Unlike x86_64's variable-length instruction prefix complexity, RISC-V uses a clean load/store architecture with uniform 32-bit (or compressed 16-bit) instruction widths.
33+
* **Uniform GPRs:** Direct mapping of 32 orthogonal registers (`x0` through `x31`, where `x0` is hardwired to zero) simplifies register allocator state machines.
34+
35+
---
36+
37+
## 4. macOS Mach-O & Linux Cross-Compilation Logistics
38+
39+
Ship enables native cross-compilation from Linux to macOS (`macho`) without external LLVM or macOS dependencies:
40+
41+
### Dynamic Linking over Direct Syscalls
42+
Apple does not guarantee syscall ABI stability across minor OS updates. Therefore, the Mach-O emitter will:
43+
* Dynamically link against `/usr/lib/libSystem.dylib` (which wraps stable system calls like `exit`, `write`, `read`).
44+
* Emit Mach-O dynamic import tables (`LC_LOAD_DYLIB`, `LC_DYLD_INFO_ONLY`) so that `dyld` resolves these symbols at runtime.
45+
46+
### Ad-hoc Code Signing
47+
Apple Silicon machines immediately `SIGKILL` unsigned Mach-O binaries. We will append ad-hoc signature blocks using the `LC_CODE_SIGNATURE` load command directly inside the Mach-O generator or recommend open-source tools like `rcodesign` inside our toolchain distribution workflow.

0 commit comments

Comments
 (0)