Skip to content

Add fcontext support for DEC Alpha (SysV/ELF) - #342

Open
mattst88 wants to merge 2 commits into
boostorg:developfrom
alphalinux-org:alpha
Open

Add fcontext support for DEC Alpha (SysV/ELF)#342
mattst88 wants to merge 2 commits into
boostorg:developfrom
alphalinux-org:alpha

Conversation

@mattst88

Copy link
Copy Markdown

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.S
  • build/Jamfile.v2: asm_sources alternative for <architecture>alpha <address-model>64 <abi>sysv <binary-format>elf
  • CMakeLists.txt: alpha added to _all_archs; CMAKE_SYSTEM_PROCESSOR is alpha, so the existing IN_LIST branch matches it the same way riscv64/s390x/loongarch64 are already handled
  • doc/architectures.qbk: table row

ABI note

The Alpha calling standard returns a 16-byte struct such as transfer_t through 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 the transfer_t through 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_t is also passed by value in $16/$17, which is how a context entered for the first time by make_fcontext reads its argument.

Branch prediction

The transfers end in ret $31, ($27), 0 rather than jmp. The Alpha jump-format opcodes are architecturally identical and differ only in two hint bits driving the return prediction stack. jump_fcontext is entered by a bsr, which pushes, and the resumption PC is where that call appears to return — so a jmp hint orphans one entry per switch, while ret pops 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_coroutine does not fit despite the name: its push value is architecturally PC+4, and fcontext resume points live in the saved context-data, never at PC+4.)

Testing

Assembled, linked and run on real hardware (UP1500, EV68AL, gcc 16.2.0) and under qemu-alpha:

  • make/jump/ontop round-trip produces the expected switch sequence
  • callee-saved registers verified live across jump_fcontext: $9-$15 and $f2-$f9, using values kept live across the call so the compiler allocates them naturally rather than relying on asm clobbers

Depends on

Architecture detection lands elsewhere; <architecture>alpha does not exist without these, so this PR is not usable on its own:

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.
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.

1 participant