From e2d5cb7c863a09be0e58f43a605d6edbde8c4b69 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Sat, 8 Aug 2026 17:54:21 -0400 Subject: [PATCH] Test the remaining JIT backends under QEMU We have hand-written code for every architecture SLJIT supports, but CI only exercises a few of them. The existing "ptarmigan" job covers s390x, ppc64le, armv7, aarch64 and riscv64, which leaves the 32-bit ARM, PowerPC, MIPS and LoongArch backends untested. The ARM one is easy to miss: Ubuntu's armhf compiler defaults to Thumb-2, so armv7 exercises sljitNativeARM_T2_32.c and never sljitNativeARM_32.c. Add a job which cross-compiles for each of them and runs the test suite under qemu-user. This is a different mechanism to ptarmigan, which boots a container of the target architecture: run-on-arch-action supports only armv6, armv7, aarch64, riscv64, s390x and ppc64le, so none of these targets can be added to it. Cross-compiling is also faster, since only the test programs are emulated rather than the compiler as well. RunTest already accepts a "-sim" prefix for exactly this purpose, so the test scripts need no changes. Shared libraries are disabled so that the test programs are real executables rather than libtool wrapper scripts, which qemu-user cannot run. Both MIPS release 6 and the earlier releases are covered, since SLJIT_MIPS_REV selects different code for each. --- .github/workflows/dev.yml | 101 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index ecd722550..d2a96714c 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -23,6 +23,7 @@ on: - chaffinch - fruitbat - ptarmigan + - coelacanth - zebrilus - bee push: @@ -626,6 +627,106 @@ jobs: ninja ctest -j3 --output-on-failure && (cat ./Testing/Temporary/LastTest.log || true) + coelacanth: + # Tests with: cross-compilation and qemu-user, for the JIT backends that no + # other job covers. A coelacanth is a fish that was thought to be extinct. + name: QEMU ${{ matrix.config.name }} + runs-on: ubuntu-latest + container: + image: ${{ matrix.config.container }} + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + config: + # "libc" is the Debian architecture name. It is needed because the + # cross compilers do not depend on the target's libc headers, and it + # cannot always be derived from the triple. + # + # Ubuntu armhf defaults to Thumb-2, so ARM mode needs asking for. + - { name: arm, triple: arm-linux-gnueabihf, qemu: arm, libc: armhf, container: "ubuntu:26.04", cflags: -marm } + - { name: arm-thumb2, triple: arm-linux-gnueabihf, qemu: arm, libc: armhf, container: "ubuntu:26.04", cflags: -mthumb } + - { name: loongarch64, triple: loongarch64-linux-gnu, qemu: loongarch64, libc: loong64, container: "ubuntu:26.04" } + # PowerPC big-endian; ptarmigan covers ppc64le, which is a different + # ABI to ppc64. + - { name: powerpc, triple: powerpc-linux-gnu, qemu: ppc, libc: powerpc, container: "ubuntu:26.04" } + - { name: powerpc64, triple: powerpc64-linux-gnu, qemu: ppc64, libc: ppc64, container: "ubuntu:26.04" } + # These cross compilers come from Debian, which currently has no + # maintainer for the MIPS cross toolchain packages, so they have not + # been rebuilt for the release that Ubuntu 26.04 is based on. Hence + # the older container. (Ubuntu itself never targeted MIPS.) + - { name: mips, triple: mips-linux-gnu, qemu: mips, libc: mips, container: "ubuntu:24.04" } + - { name: mipsel, triple: mipsel-linux-gnu, qemu: mipsel, libc: mipsel, container: "ubuntu:24.04" } + - { name: mips64, triple: mips64-linux-gnuabi64, qemu: mips64, libc: mips64, container: "ubuntu:24.04" } + - { name: mips64el, triple: mips64el-linux-gnuabi64, qemu: mips64el, libc: mips64el, container: "ubuntu:24.04" } + # MIPS release 6 is a different instruction set to the earlier + # releases, and SLJIT_MIPS_REV >= 6 selects different code. There is + # no separate qemu-user binary for it; the emulated CPU has to be + # named instead, because the defaults predate release 6. + - { name: mips32r6el, triple: mipsisa32r6el-linux-gnu, qemu: mipsel, libc: mipsr6el, container: "ubuntu:24.04", qemu_cpu: mips32r6-generic } + - { name: mips64r6el, triple: mipsisa64r6el-linux-gnuabi64, qemu: mips64el, libc: mips64r6el, container: "ubuntu:24.04", qemu_cpu: I6400 } + if: | + (github.event_name == 'workflow_dispatch' && (inputs.job_id == 'all' || inputs.job_id == 'coelacanth')) || + github.event_name == 'push' + env: + # Where qemu-user looks for the target's shared libraries. + QEMU_LD_PREFIX: /usr/${{ matrix.config.triple }} + steps: + - name: Setup + run: | + apt-get -qq update + apt-get -qq install -y git autoconf automake libtool make \ + gcc-${{ matrix.config.triple }} \ + libc6-dev-${{ matrix.config.libc }}-cross \ + qemu-user + + # Not set unconditionally: an empty QEMU_CPU makes qemu fail to find + # a CPU definition. + if [ -n "${{ matrix.config.qemu_cpu }}" ]; then + echo "QEMU_CPU=${{ matrix.config.qemu_cpu }}" >> "$GITHUB_ENV" + fi + env: + DEBIAN_FRONTEND: noninteractive + + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + submodules: true + + - name: Prepare + run: ./autogen.sh + + - name: Configure + # Shared libraries are disabled so that the test programs are real + # executables rather than libtool wrapper scripts, which qemu-user + # cannot run. + run: | + ./configure \ + --build=`./config.guess` \ + --host=${{ matrix.config.triple }} \ + CC=${{ matrix.config.triple }}-gcc \ + CFLAGS="${{ matrix.config.cflags }} $CFLAGS_GCC_STYLE" \ + --disable-shared \ + --enable-jit \ + --enable-pcre2-16 \ + --enable-pcre2-32 \ + --enable-debug \ + --enable-Werror + + - name: Build + run: make -j$(nproc) + + - name: Test (main test script) + run: ./RunTest -sim qemu-${{ matrix.config.qemu }} + + - name: Test (JIT test program) + run: qemu-${{ matrix.config.qemu }} ./pcre2_jit_test + + - name: Test (pcre2posix program) + run: qemu-${{ matrix.config.qemu }} ./pcre2posix_test -v + + # RunGrepTest is skipped as it does not have a "-sim" flag yet. + zebrilus: # Tests with: Zig compiler. A "zebrilus" is known as a "zigzag heron". name: Zig