Add fcontext support for DEC Alpha (SysV/ELF) - #342
Open
mattst88 wants to merge 2 commits into
Open
Conversation
Alpha had no fcontext assembly, so a build on that architecture found no matching asm_sources alternative. The Alpha calling standard returns a 16 byte struct such as transfer_t through a hidden pointer passed in $16, which shifts the declared arguments to $17 and $18. That pointer belongs to the frame that made the call, so it has to travel with the context: each context records the pointer its own suspending call was given, and whoever resumes that context stores the transfer_t through it. Among the existing ports only ppc32-sysv-linux returns a context through memory this way. transfer_t is also passed by value in a register pair, so $16 and $17 are loaded with it as well. A context entered for the first time by make_fcontext reads its argument that way; for an ordinary resumption those are argument registers the resumed call may clobber, so setting them unconditionally is harmless. The resumption PC is loaded into $27 so that it doubles as the procedure value a context-function entered for the first time computes its own gp from. The transfer at the end of jump_fcontext and ontop_fcontext uses the ret hint rather than jmp. Those functions are entered by a bsr, which pushes onto the return prediction stack, and the resumption PC is where that call appears to return, so a jmp hint would orphan an entry per switch; the ret hint pops it. Worth about 3% on a ping-pong switch benchmark on an EV68AL UP1500. jsr_coroutine does not fit despite the name: it pushes PC+4, and resume points live in the context-data.
The CMake build selects the fcontext assembly by interpolating BOOST_CONTEXT_ARCHITECTURE into the source name, and alpha was not among the recognized values, so a CMake build on Alpha fell through to the 64-bit default of x86_64. Listing alpha in _all_archs is enough: CMAKE_SYSTEM_PROCESSOR is "alpha" there, so the IN_LIST branch matches it, as it already does for riscv64, s390x and loongarch64. The remaining defaults are sysv, elf and gas.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the three fcontext assembly routines for Alpha on Linux (SysV ABI, ELF), plus the b2 and CMake wiring and a doc table entry.
src/asm/{make,jump,ontop}_alpha_sysv_elf_gas.Sbuild/Jamfile.v2:asm_sourcesalternative for<architecture>alpha <address-model>64 <abi>sysv <binary-format>elfCMakeLists.txt:alphaadded to_all_archs;CMAKE_SYSTEM_PROCESSORisalpha, so the existingIN_LISTbranch matches it the same way riscv64/s390x/loongarch64 are already handleddoc/architectures.qbk: table rowABI note
The Alpha calling standard returns a 16-byte struct such as
transfer_tthrough a hidden pointer in$16, which shifts the declared arguments to$17/$18. That pointer belongs to the frame that made the call, so it has to travel with the context: each context records the pointer its own suspending call was given, and whoever resumes it stores thetransfer_tthrough it. Among the existing ports only ppc32-sysv-linux returns a context through memory this way, so this is the main thing worth reviewing.transfer_tis also passed by value in$16/$17, which is how a context entered for the first time bymake_fcontextreads its argument.Branch prediction
The transfers end in
ret $31, ($27), 0rather thanjmp. The Alpha jump-format opcodes are architecturally identical and differ only in two hint bits driving the return prediction stack.jump_fcontextis entered by absr, which pushes, and the resumption PC is where that call appears to return — so ajmphint orphans one entry per switch, whileretpops it. Measured 131.8 -> 128.1 ns/switch (-2.9%) on an EV68AL UP1500, winning all 16 interleaved runs across call depths 0/4/8/16.(
jsr_coroutinedoes not fit despite the name: its push value is architecturallyPC+4, and fcontext resume points live in the saved context-data, never atPC+4.)Testing
Assembled, linked and run on real hardware (UP1500, EV68AL, gcc 16.2.0) and under
qemu-alpha:jump_fcontext:$9-$15and$f2-$f9, using values kept live across the call so the compiler allocates them naturally rather than relying on asm clobbersDepends on
Architecture detection lands elsewhere;
<architecture>alphadoes not exist without these, so this PR is not usable on its own:alphato the<architecture>featurealphato the architecture check listchecks/architecture/alpha.cpp