# Fun fact, Ada (GNAT) runs on IBM s/390

**URL:** https://forum.ada-lang.io/t/fun-fact-ada-gnat-runs-on-ibm-s-390/4817
**Category:** General
**Tags:** spark
**Created:** [October 11, 2026, 5:59pm UTC](https://forum.ada-lang.io/t/fun-fact-ada-gnat-runs-on-ibm-s-390/4817 "2026-10-11T17:59:59Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Irvise](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/i/7ba0ec/32.png) [@Irvise](https://forum.ada-lang.io/u/Irvise)
#### Post date: [October 11, 2026, 5:59pm UTC](https://forum.ada-lang.io/t/fun-fact-ada-gnat-runs-on-ibm-s-390/4817/1 "2026-10-11T17:59:59Z")

</div>

Hi all,

this week I was in a conference (well, actually two, for those interested [MODELS 2026 – Model Driven Engineering Languages and Systems](https://conf.researchr.org/home/models-2026) and [https://langdevcon.org/](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](https://www.ibm.com/products/z) and [IBM mainframe - Wikipedia](https://en.wikipedia.org/wiki/IBM_mainframe)) 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](https://github.com/jrmarino/draco)). 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](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

1. **`make check-acats` is broken for GCC ≥ 15 on every target.**  
`run_all.sh` hardcodes `gccflags="-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`, implicit `int` is 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"`.
2. **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 native `gnat` for 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 linked `qemu-s390x`** , snapshot-pinned for  
reproducibility; disk image via `mkfs.ext4 -d` (the container has no loop  
devices); booted with `qemu -kernel/-initrd`, static `10.0.2.15`, ssh on  
`:2222`.
- ACATS assembled from the ada-auth 4.2 tarball **plus** GCC’s  
`gcc/testsuite/ada/acats-4` driver (the tarball ships no driver scripts, and  
GCC’s `support/` 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/rts` symlinks), so the s390 and x86  
arms are directly comparable.
- Full per-test logs, `acats.sum` files 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](https://github.com/ambitus/gcc)) and IBM has preferential support for LLVM toolchains (which we also support via [GitHub - AdaCore/gnat-llvm: LLVM based GNAT compiler · GitHub](https://github.com/AdaCore/gnat-llvm)). 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)](https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcobol/gcobol.html)) 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.
