14.1 Portability and Performance

An important goal of the Gforth Project is availability across a wide range of personal machines, in particular different architectures and OSs. This was particularly important in the 1990s with it’s wide variety of RISC architectures (that are still supported by Gforth, but we currently cannot test all of them).

However, even in this century new architectures have appeared, and Gforth’s portability allows us to support them early on; it usually runs out of the box (but without engine optimizations) on hardware it does not know about; e.g., in 2017 we built it on a QEMU (virtual machine) implementation of RISC-V, before adding more specific support in 2022.

The more specific support ideally consists of just checking that the engine optimizations work, and enabling them in the configuration script. We also define BFD_ARCH and BFD_MACH for disasm2, the disassembler based on GNU binutils (the generic support uses disasm-gdb or dump instread). On some architectures we have to define a FLUSH_ICACHE and tune, e.g., the number of stack representations.

In any case, the specific support is so easy that we take an hour or so to add it once we have access to hardware. E.g., Gforth supported AMD64 (first hardware release 2003) in 2003, while SwiftForth and VFX took until the 2020s to do so. Gforth has supported ARM A64 (first hardware release 2013) in 2014, while SwiftForth and VFX have not yet (in 2026) released an ARM A64 version. Gforth has had specific support for RISC-V since 2022, while SwiftForth and VFX probably don’t see enough interest in RISC-V yet to support it.

Our tool for achieving this portability has been to use GNU C as a substrate, in particular the labels-as-values feature (see Labels as Values in GNU C Manual)) present since gcc-2.0 (released February 1992; we started to work on Gforth in July 1992). This extension is supported by gcc (recommended), clang (with slow compiles in clang) and others.

The labels-as-values feature has allowed us to implement threaded code, as well as native-code copying optimizations such as dynamic superinstructions (see Dynamic Superinstructions) and the optimizations based on them. The use of gcc has been a bumpy ride at times (especially in the 2000s), but we managed to work around some of the bumps and the rest were eventually fixed in gcc. Concerning portability, gcc is available for a wide range of architectures and platforms.

Writing in a portable language has the reputation of producing code that is slower than assembly language. However, already at the beginning Gforth ran faster than threaded-code Forth systems written in assembly language like Win32Forth. Over the course of its development we further improved the performance (see Optimizations), and now it is competetive in performance with native-code systems like SwiftForth.

For portability across OSs we used POSIX interfaces, and this works nicely for many OSs, including Linux, MacOS and Android. For Windows it also works, thanks to Cygwin, but building a Windows package is so much work that the we currently recommend using a Linux package of Gforth on WSL. There is no iOS port, however.