Hi all,
this week I was in a conference (well, actually two, for those interested MODELS 2026 – Model Driven Engineering Languages and Systems and https://langdevcon.org/) and I met quite a few interesting people. One of them was a Broadcom engineer, Vit Gottwald, with whom I had a quite interesting discussion. He is working on the mainframe project (for those who do not know, look into IBM Z Mainframe Servers and Software and IBM mainframe - Wikipedia) and we had a nice discussion about Ada/SPARK.
We both wondered whether we could run Ada on the s/390 architecture and if GNAT had support for it. He encouraged me to try to see if I could first run it on Linux/s390. That seemed to be a nice challenge, specially after my work on updating GNAT on NetBSD (where J. Marino did most of the work, see his work in GitHub - jrmarino/draco: GNAT-AUX / GCC-AUX / Draco Ada compiler development · GitHub). Well, it turns out… that GNAT already has support for the s390 architecture! I learned this thanks to Debian having full Linux/s390 support and having GNAT-v16 available in the repos (unstable). I still wanted to learn and see how good the support was, so I fired up an AI and instructed it to run the ACATS test suite (http://www.ada-auth.org/acats.html) on a virtualised Debian using QEMU. The results speak for themselves!
(the following text has been written by an AI, MiMo-v2.6-Flash)
GNAT/GCC on Linux s390 (s390x): ACATS baseline — first results
Set up a reproducible dev environment for validating/patching GNAT for
s390x-linux-gnu: a Debian sid (s390x) VM under qemu-system-s390x (TCG),
GCC pinned to releases/gcc-16.2.0, and ACATS 4.2 driven by GCC’s own
gcc/testsuite/ada/acats-4/run_all.sh harness.
Results — full ACATS 4.2 (49 chapters)
| arm | compiler | passes | harness “failures” |
|---|---|---|---|
| s390x (QEMU TCG VM) | Debian gnat-16 = GCC 16.2.0-3 |
2606 | 1555 |
| x86_64 control (host) | GCC 16.2.1 | 2612 | 1549 |
The ~1550 shared “failures” are a harness artifact: GCC’s simplified runner
counts negative tests (code that is supposed to be rejected) as failures,
since it treats any non-zero gnatmake exit as FAIL. ACATS grades those with
its own -- ERROR: annotation mechanism, which run_all.sh doesn’t implement.
So the useful number is the failure-set diff. s390x fails exactly 6
tests that pass on x86_64, in three clean themes:
| theme | tests | symptom |
|---|---|---|
A. abort / Terminated semantics |
c394001, cxc7005, c954a01 |
aborted (or abort-deferred) task still reports Terminated/Callable = False |
| B. protected-entry wakeup | cxai033, cxai035 |
“Enqueue to empty queue didn’t unblock reader” (both Ada.Containers queue types) |
C. task Storage_Error |
cb1010a |
process exits with no verdict where Storage_Error is expected (siblings cb1010c/d pass) |
No test ever hit the harness’s 900 s timeout, so these are real behavioural
differences in libgnarl/tasking on s390, not TCG speed artifacts.
Smoke tests
8 self-checking programs (tasking + protected objects, exception
unwinding/controlled types, secondary stack, 128-bit modular arithmetic,
atomic shared variables, Ada.Real_Time, generics + tagged dispatching):
8/8 PASS on s390x, identical to x86_64.
Two findings worth reporting upstream
make check-acatsis broken for GCC ≥ 15 on every target.
run_all.shhardcodesgccflags="-O2"and compiles ACATS’s C support
files (tests/cd/*.c,tests/cxb/*.c), which are K&R-style — since GCC 15
defaults to-std=gnu23, implicitintis now a hard error:
cd300051.c: error: type of 'Value' defaults to 'int'
The suite aborts during “Compiling support files…”. Workaround is a
one-liner at the script’s sanctioned customization point:
gccflags="-O2 -std=gnu89".- s390x GNAT is in much better shape than expected. The runtime wiring
(gcc/ada/Makefile.rtl, “S390 Linux” block,system-linux-s390.ads) has
been in place since ≤ GCC 9, and Debian has shipped nativegnatfor s390x
for years. The 6 tests above are the only s390-specific deltas found in a
full ACATS run.
Infrastructure
- Debian sid/s390x rootfs built with
debootstrap --foreign+ second stage
through binfmt + statically linkedqemu-s390x, snapshot-pinned for
reproducibility; disk image viamkfs.ext4 -d(the container has no loop
devices); booted withqemu -kernel/-initrd, static10.0.2.15, ssh on
:2222. - ACATS assembled from the ada-auth 4.2 tarball plus GCC’s
gcc/testsuite/ada/acats-4driver (the tarball ships no driver scripts, and
GCC’ssupport/has files the tarball lacks, e.g.impbit.adb). - The same GCC driver runs unmodified against both compilers via a fake “gcc
build tree” shim (xgcc/gnatmake/ada/rtssymlinks), so the s390 and x86
arms are directly comparable. - Full per-test logs,
acats.sumfiles and the analysis are in
docs/findings.md/docs/results/.
Next: root-cause the six (task abort handling, entry-queue wakeup, task stack
accounting) and turn fixes into draco-style patches against GCC 16.2.0.
Soooo, yeah, that is pretty cool! I do not know who introduced support for this architecture (AdaCore, Debian contributors, Marino, etc), but I just love seeing this kind of work out there in the wild!
Now, not everything is rosy. There were obviously some failures whose root needs to be found and fixed. Also, Debian maintains a set of patches that make GNAT work in all their cases, this is the same for other systems such as OpenBSD. I personally would love to see some community effort to try and take all these patches (including those from Draco) and upstreaming them to GCC. This way we will have a much more robust tool, the fixes wont be scattered, the maintainers’ work will be substantially less and we can always brag about having great tool support (which we do, but I could be better).
Best regards,
Fer
P.S: now the interesting thing would be to test GNAT on z/OS. From what I have seen, GCC does not support z/OS (though there is/was work to fix just that GitHub - ambitus/gcc: A port of GCC supporting z/OS as a target · GitHub) and IBM has preferential support for LLVM toolchains (which we also support via GitHub - AdaCore/gnat-llvm: LLVM based GNAT compiler · GitHub). So it could be a substantial amount of effort or very little. It remains to be seem. Maybe it will become easier if GCC-Cobol (GCOBOL(1) (gcc cobol compiler)) gets ported to z/OS, and there seems to be some interest in it, but that is greatly outside of our scope. Also, IBM is introducing the ARM architecture to their chips, so there may not be much interest in the s390-zOS port as we could just skip to aarch64-zOS directly.