GCC 16.2 for the Amiga, fixed properly.
OpenAmigaGCC is our port of GCC 16.2 to AmigaOS 3.x on the 68k. It compiles the Open family and the open ROM, and getting it right meant finding and fixing 21 bugs in the compiler, its C library and its threads.
Release 16.2.0-open2 came out on 12 October 2026. It builds on bebbo's amiga-gcc line, which brought modern GCC to the Amiga, and adds our fixes, each with a test that fails on the old compiler and passes on the new one.
Why we needed our own compiler.
Everything we write for the Amiga, from OpenUp's apps to the open exec in the ROM, is built as lean C++ with GCC 16.2. A compiler bug there is a crash on someone's Amiga, and a bug in exec is a machine that won't start. So we didn't work around problems when we hit them. We tracked each one to its cause, fixed it where it lived and kept a test so it can't come back.
21 bugs
In GCC's 68k code generation, its defaults, libnix, libpthread and the AmigaOS headers.
32 of 32 tests
Our compiler qualification suite on AmigaOS 3.2 on a 68040: exceptions, RTTI, threads, atomics, floating point and encryption vectors.
20 of 20 runs
The thread race that used to crash or hang about half the time, run 20 times in a row with no failure.
Everything we fixed.
In plain words, grouped by where the bug was. Each link opens our write-up of how we found it.
Code the compiler got wrong
Bugs in GCC's 68k back end and middle end: the program compiled, then did the wrong thing.
- Float to integer on a 68040. GCC could save the FPU control register into the very register a store was using as its address, so the number landed in the wrong place. How we found it
- memmove copying the wrong way. An overlapping block move of a known size copied forwards and overwrote what it was about to read. It broke shift-up loops,
__builtin_memmoveandstd::copy_backward. How we found it - 64-bit arguments read from the wrong word. A 64-bit value pushed from the stack for a library call read the word next to it, so some 64-bit divides returned 0 or -1. How we found it
- A calloc that calls itself. GCC turned a hand-written calloc (malloc then memset) into a call to calloc, which recursed until the stack ran out. How we found it
- Base-relative C++ exceptions. In
-fbasereland-residentprograms the exception tables could not reach their type information, so catching by type failed to link.
Defaults that suit an Amiga
GCC assumes things about memory that are not true on a 68k Amiga. We changed the defaults so ordinary code is safe.
- Address 0 is real memory. At -O2 GCC replaced provable NULL reads with
trap #7, which AmigaOS shows as Software Failure 80000027. Our driver turns that off by default. How we found it - Loop distribution back on. With the memmove fix in place, shift and insert loops can safely become block moves again, which made them up to 3.8 times faster on the AC090. How we found it
- C++ destructors registered properly.
-fuse-cxa-atexitis now the default, sothread_localdestructors run and static objects are destroyed in the right order. How we found it -resident32links the right libraries. It used to pick the plain libraries instead of the base-relative ones. How we found it
Starting and stopping a program
Fixes in libnix, the small C library every program links with.
- Asking for a bigger stack.
__stackdid not give a program its stack, and the stack swap clobbered a register (Software Failure 80000004). How we found it - Returning to the Shell. Plain
-fbaserel32programs returned their stack size instead of their exit code. How we found it - 32-bit maths on a 68000. A program's own
UtilityBase, still NULL, made the first multiply or divide jump to address 0. How we found it - Doubles rounded to floats. On an Amiga with an FPU, OS 3.2's maths libraries left the FPU in single precision, so software doubles lost their accuracy. How we found it
- C++ start-up in base-relative programs. Start-up read its constructor and exception lists from the wrong place, so these programs failed to link or hung before
main.
Threads
C++ threads on AmigaOS 3.x, made dependable enough for the Open family's own code.
- A thread's record moved under it. Starting a new thread could move the records of running ones, so
thread_localandcall_oncecrashed or hung about half the time. How we found it - Detach, join and signals.
pthread_detachwas a stub, a finished thread's slot was never given back, andpthread_joincould swallow a Ctrl-F the program was waiting for. Join now has a signal of its own. - Numbers in several threads at once. C++ streams formatting numbers in parallel hung the program, and sometimes the whole machine, because
setlocale()was not safe to call from two threads. How we found it - Threads in base-relative programs. A new thread started with no data pointer of its own and hung on its first global variable.
The AmigaOS headers
Two fixes to headers that GCC 16 reads differently from older compilers. The build fixes them for you.
- A library call inside another. In
Stricmp(FilePart(name), ...)the outer call ran with the inner library's base in A6. The bug was in the tool that makes the NDK's inline headers. How we found it - Network calls refused. Roadshow's socket headers listed argument registers as clobbered, which GCC 15 and later reject, so 31 network calls did not compile. How we found it
How we know it's right.
A test for every fix
Each bug has a small program that goes wrong on the old compiler and right on ours. The code-generation ones run under qemu-m68k with tests/repro/prove.sh.
Checked on every change
Continuous integration builds the whole toolchain from source and runs the tests on every pull request.
Run on a real AmigaOS
The qualification suite runs on AmigaOS 3.2 on a 68040 inside AmigaChrome, through Cradle, before a release goes out.
Get it, and what's next.
The toolchain for x86-64 Linux and the complete source are on the release. Unpack it, put bin/ on your path and add the AmigaOS 3.2 NDK, which you supply yourself. GCC, binutils and our patches are GPL-3.0, with the GCC Runtime Library Exception for libgcc and libstdc++.
ARM64 Linux
An open2 build for ARM64 Linux, so the same compiler runs on a Raspberry Pi.
PowerPC and AmigaOS 4.1
A GCC 16.2 for AmigaOS 4.1 built the same way: from GNU's own sources, with open patches, and no borrowed toolchains.