65816 IIgs Backend for LLVM-MOS.
Find a file
Scott Duensing 09f7405362 Updates
2026-06-03 16:08:42 -05:00
benchmarks Optimizations 2026-05-25 21:00:32 -05:00
compare C++, more gaps filled, source-level debugging. 2026-05-30 19:40:29 -05:00
demos Updates 2026-06-03 16:08:42 -05:00
docs Updated 2026-06-02 23:17:57 -05:00
patches Checkpoint 2026-05-13 15:48:34 -05:00
runtime Updates 2026-06-03 16:08:42 -05:00
screenshots Optimizations 2026-05-25 21:00:32 -05:00
scripts Updates 2026-06-03 16:08:42 -05:00
src Updates 2026-06-03 16:08:42 -05:00
tests Updates 2026-06-03 16:08:42 -05:00
.gitattributes ORCA/C demos seem to be working! 2026-05-18 14:43:35 -05:00
.gitignore Updates 2026-06-03 16:08:42 -05:00
LLVM_65816_DESIGN.md Checkpoint. 2026-04-25 17:07:28 -05:00
mame.ini Checkpoint 2026-05-13 15:48:34 -05:00
plugin.ini Checkpoint 2026-05-13 15:48:34 -05:00
README.md C++, more gaps filled, source-level debugging. 2026-05-30 19:40:29 -05:00
SESSION_RECOVERY.md More optimizations. 2026-05-27 19:37:26 -05:00
SESSION_STATE.md Initial check in. Lots of work yet to do. 2026-04-28 16:49:41 -05:00
setup.sh C++, more gaps filled, source-level debugging. 2026-05-30 19:40:29 -05:00
STATUS.md Updated 2026-06-02 23:17:57 -05:00
ui.ini Checkpoint 2026-05-13 15:48:34 -05:00

llvm816

LLVM/Clang C compiler for the WDC 65816 / Apple IIgs.

Compiles C (and a minimal subset of C++) to native 65816 machine code, links to a relocatable OMF binary, and runs under MAME's apple2gs. Speed-tuned: matches or beats hand-written 65816 assembly on the tight loops in benchmarks like sumOfSquares, popcount, and strcpy.

What you get

  • clang --target=w65816 — full C99 + parts of C11, optimized at -O2 by default. Soft-float and soft-double included.
  • C standard library subsetstdio.h, stdlib.h, string.h, math.h, time.h, setjmp.h, etc. See runtime/include/ for the complete list.
  • C++ via clang++ — single + multiple inheritance, virtual base diamonds, RTTI, dynamic_cast, new / delete / new[] / delete[], Meyers singletons (__cxa_guard_*), global ctors via .init_array, global / static-local dtors actually run at exit (__cxa_atexit + __run_cxa_atexit), SJLJ exceptions. Backed by runtime/libcxxabi.o
    • libcxxabiSjlj.o.
  • ETL — vendored Embedded Template Library at runtime/include/c++/etl/ (MIT, header-only). Fixed-capacity etl::vector<T,N>, etl::string<N>, etl::map<K,V,N>, etl::optional, etl::delegate, etc. — no malloc, no exceptions, fits the IIgs memory model.
  • link816 — relocating linker producing GS/OS-loadable OMF binaries (single- or multi-segment).
  • MAME integration scripts — compile, link, and run a program under MAME's apple2gs with one command.
  • Apple IIgs Toolbox bindings<iigs/toolbox_full.h> exposes ~1300 toolbox routines from 35 tool sets.

Quick start

After installation (see docs/INSTALL.md):

# Write a tiny C program that computes 1+2+...+10 = 55 and stores it.
cat > hello.c <<'EOF'
int main(void) {
    unsigned short x = 0;
    for (int i = 1; i <= 10; i++) x += i;        // x = 55 = 0x37
    // Write to a known 24-bit absolute address.  The compiler lowers
    // this to `sta long $025000` — no bank switching needed.  The MAME
    // test harness reads this cell to verify the program ran.
    *(volatile unsigned short *)0x025000 = x;
    while (1) {}
}
EOF

# Compile, link, run under MAME, check the result.
./tools/llvm-mos-build/bin/clang --target=w65816 -O2 -c hello.c -o hello.o
./tools/link816 -o hello.bin --text-base 0x1000 \
    runtime/crt0.o runtime/libc.o runtime/libgcc.o hello.o
bash scripts/runInMame.sh hello.bin --check 0x025000=0037

See docs/USAGE.md for a full walkthrough including multi-segment builds and the Apple IIgs Toolbox.

Project layout

runtime/         C standard library + crt0 startup
  src/           sources (C and .s)
  include/       headers
  *.o            built object files
src/             our LLVM/Clang sources (W65816 target backend)
  clang/         clang patches
  llvm/          LLVM patches + W65816 target
  link816/       relocating linker
patches/         patches against vanilla llvm-mos
scripts/         install scripts, MAME runners, benchmarks
tools/           installed compilers, MAME, ROMs, Calypsi (reference)
benchmarks/      cycle-count and instruction-count benchmarks
compare/         side-by-side asm vs Calypsi
docs/            this directory — INSTALL.md, USAGE.md, design notes

Status

Stable enough to build real programs. Per-call cycle measurements against commercial Calypsi 5.16, measured under MAME via emu.time() (IIgs slow-mode 1.023 MHz, -mllvm -w65816-dbr-safe-ptrs enabled):

Benchmark Ours Calypsi Ratio
dotProduct 1,534 5,712 0.27×
bsearch 682 2,387 0.29×
sumOfSquares 6,820 16,368 0.42×
bubbleSort 11,594 17,050 0.68×
strLen 767 1,023 0.75×
djb2Hash 2,046 2,643 0.77×
popcount 1,194 1,534 0.78×
strcpy 1,108 1,194 0.93×
memcmp 682 716 0.95×
fib 11,594 10,912 1.06×

Geomean: 0.62× Calypsi across this suite. Nine of ten benches beat Calypsi outright; only fib trails at 1.06×. Run scripts/benchCyclesPrecise.sh (ours, with W65816_CC_EXTRA="-mllvm -w65816-dbr-safe-ptrs") and scripts/benchCyclesCalypsi.sh (Calypsi) to reproduce.

On real programs:

  • Lua 5.1.5 (17K LoC, 24 source files) compiles + links clean. Object total 0.93× Calypsi.
  • CoreMark 1.0 (EEMBC standard benchmark) compiles + links clean. Linked binary 39.6 KB (0.73× Calypsi's 54.5 KB).
  • ETL containers (vector, string, map, optional, delegate) — full end-to-end probe in demos/etlProbe.cpp, ~20 KB total under GNO.

See STATUS.md for full language and runtime feature coverage, and LLVM_65816_DESIGN.md for backend internals.

Documentation

License

Apache 2.0 (matching the LLVM project's license). See tools/llvm-mos/LICENSE.TXT after install.