Skip to content

alpha: Add JIT support#921

Open
mattst88 wants to merge 4 commits into
PCRE2Project:mainfrom
alphalinux-org:alpha-jit-support
Open

alpha: Add JIT support#921
mattst88 wants to merge 4 commits into
PCRE2Project:mainfrom
alphalinux-org:alpha-jit-support

Conversation

@mattst88

Copy link
Copy Markdown

Add JIT compiler support for DEC Alpha (AXP) 64-bit, in four commits:

Base

  • Document and package the backend: add sljit Alpha sources to EXTRA_DIST, update the JIT-supported-platforms list. The deps/sljit submodule bump is deferred until the sljit backend is merged upstream.

CMPBGE scanning:

  • Implement fast_forward_char_simd, fast_requested_char_simd, and fast_forward_char_pair_simd using the Alpha CMPBGE instruction for 8-byte-at-a-time character scanning, analogous to the SIMD paths on other architectures. The first-match step uses a base-ISA binary search (NEGQ+AND to isolate the lowest set bit, then three AND+SELECT pairs), identical to glibc's Alpha strchr.

memchr:

  • For exact single-character 8-bit scanning, call glibc's memchr() instead of the inline CMPBGE loop. glibc's Alpha memchr uses CMPBGE with 3-cache-line prefetching, alignment, and software pipelining that the JIT cannot easily replicate.

Prefetching:

  • Emit PREFETCH_L1 (LDL R31) 192 bytes ahead in all three CMPBGE scanning loops. Guarded against short haystacks. Unconditional prefetch caused a ~15% regression on inputs shorter than 192 bytes.

Validated on a real HP AlphaServer ES47 (1 GHz EV7): pcre2_jit_test passes all tests in 8/16/32-bit modes; RunTest passes with and without JIT.

The last two commits could be dropped from this PR and considered separately, if desired.

Requires zherczeg/sljit#364

mattst88 added 4 commits July 3, 2026 18:50
List the new sljit Alpha backend sources in EXTRA_DIST and add DEC Alpha
64-bit to the platforms supported by the JIT compiler in the documentation.

The corresponding deps/sljit submodule bump is deferred until the backend
is merged upstream; validated under qemu-alpha (pcre2_jit_test passes in
8/16/32-bit modes and RunTest passes with and without JIT).
Use the Alpha CMPBGE instruction for 8-byte-at-a-time character
scanning in the JIT compiler, similar to how other architectures use
SIMD instructions. CMPBGE compares 8 byte pairs and produces an 8-bit
mask, which combined with XOR gives us byte-equality matching across a
whole quadword at once.

Implement fast_forward_char_simd, fast_requested_char_simd, and
fast_forward_char_pair_simd. The first-match step uses a base-ISA
binary search (NEGQ+AND to isolate the lowest set bit, then three
AND+SELECT pairs), identical to glibc's Alpha strchr; no CIX required.

For 16/32-bit code units, a post-processing step compacts the per-byte
CMPBGE mask into a per-code-unit mask by ANDing adjacent bits.

The char-pair function handles Alpha's 8-byte alignment requirement for
LDQ by constructing the unaligned second data word from two aligned
loads using SRL/SHL/OR.
Emit PREFETCH_L1 (LDL R31) 192 bytes ahead of the current position
in all three fast-forward scanning loops: fast_forward_char_simd,
fast_requested_char_simd, and fast_forward_char_pair_simd.

The 192-byte (3 cache line) prefetch distance matches what glibc's
Alpha memchr uses. Without this, the JIT's CMPBGE loop loses to the
interpreter's memchr() call on full-scan no-match patterns because
memchr has prefetching and software pipelining.

The prefetch is guarded by a comparison against STR_END - 192 to
avoid reading past the end of the buffer on short haystacks, where
unconditional prefetching caused a ~15% regression.
For 8-bit mode with an exact single-character match, call glibc's
memchr() instead of the inline CMPBGE scanning loop. glibc's Alpha
memchr uses CMPBGE with 3-cache-line-ahead prefetching, cacheline
alignment, and software pipelining (overlapping the next load with
the current compare to hide L1 latency).

The CMPBGE loop is retained for case-insensitive (match1i) and
two-character (match2) scanning where memchr does not apply.

Both fast_forward_char_simd and fast_requested_char_simd gain the
memchr path; fast_forward_char_pair_simd is unchanged since it
searches for two characters at different offsets simultaneously.
@zherczeg

Copy link
Copy Markdown
Collaborator

Is this architecture is still supported by HP? Alpha EV7 is released in 2003.
I want to drop mips from the codebase, because the last MIPS cpu was released in 2015.

@mattst88

Copy link
Copy Markdown
Author

Is this architecture is still supported by HP? Alpha EV7 is released in 2003.

It is not supported by HP, no.

I want to drop mips from the codebase, because the last MIPS cpu was released in 2015.

Is it causing maintenance issues? I have a passing interest in MIPS and could have a look.

Dropping it based on release date doesn't seem like the right metric.

@zherczeg

Copy link
Copy Markdown
Collaborator

The reasoning is that the jit compiler is normally used in high performance environments. If you have old machines, they are likely not used in production environments. They simply used for "showing that they still works". Supporting them is not worth the maintenance efforts. MIPS is not the first arch which was dropped, sparc and TileGX was also supported at some point of time.

Anyway, if somebody is willing to maintaining these architectures, I have no problem supporting these outdated cpus. The problem is that if the maintainer disappears after a few years. I have no resources to maintain them.

@mattst88

Copy link
Copy Markdown
Author

Thanks. That makes complete sense to me and I fully agree.

I've been working to support old/weird architectures for 15+ years now, so I'm happy to contribute to sljit and pcre2 in that capacity. (Though I cannot promise I won't suddenly be hit by a bus)

I'll start by checking on the status of the test suite on mips tomorrow. I found an issue indicating it might be more than a little broken :)

@NWilson

NWilson commented Jul 16, 2026

Copy link
Copy Markdown
Member

I don't have any particular influence over sljit. I have been struggling with personal to keep up with PCRE2 recently - so anything that keeps maintenance down would be nice.

Dead architectures like MIPS or Alpha or Sparc seem totally reasonable to drop. Retrocomputing can focus on keep old software alive on old systems, but doesn't need to bring new software to such systems. Or at least, I don't the time or energy to contribute to that effort personally.

I feel like there are several bits of code in PCRE2 (including some z/OS support and VMS) which is clearly broken, and I'm quite confident doesn't compile anymore. It's always painful to "pull the trigger" and delete it.

I'm afraid that old sljit architectures would end in the same place: code contributed by one expert, used by one or two users, and then after a couple of years be dead, and with little way for us to know if it still works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants