Testing future-ISA assembly with Intel SDE

Some assembly uses an instruction-set extension the machine running the tests does not have: Intel APX’s extended registers r16–r31, AVX10.2, AMX, or plain AVX-512 on an AVX2-only box. Those routines are normally untestable here — the DynamoRIO native tier executes on the real CPU (so an unsupported instruction faults), and the Unicorn emulator tier vendors a QEMU whose TCG predates AVX.

Intel’s Software Development Emulator (SDE) closes that gap. SDE emulates future and absent ISA extensions for the whole process, so running an unmodified suite binary under sde64 -future gives future-ISA routines the same full register / flag / memory / ABI assertion battery every other test gets — on any x86-64 host, including CI runners with no special silicon.

Backend

Records

Runs where

Intel SDE emulation under sde64 -future

full register / flag / memory / ABI assertions on emulated ISA

any x86-64 Linux


Running the lane

The pinned, digest-verified SDE kit and the APX-capable assemblers live in a container image, so the simplest way to run the lane is:

make docker-sde

That builds Dockerfile.sde (Intel SDE 10.8.0 + GNU binutils 2.46.1 for an APX-capable GAS + NASM 3.02 + libunicorn, each SHA-256-pinned) and runs the suite under sde64 -future.

To run on a host directly, fetch the pinned kit and point the lane at it:

make sde-test SDE_HOME=$(scripts/fetch-sde.sh)

scripts/fetch-sde.sh downloads SDE 10.8.0, refuses it unless its SHA-256 matches the pinned digest in scripts/third-party-digests.txt, and prints SDE_HOME. The lane self-skips with a printed reason on a non-x86-64 host (SDE is x86-only) and when SDE_HOME is unset (it points you at the fetch script).


What the lane proves

Transparency (the null test). SDE must not change the behaviour of correct baseline code. sde-test runs suites with no capability-dependent skips (test_arith, test_capture, test_mem) both natively and under sde64 -future and asserts the two TAP streams are byte-for-byte identical. Any difference is a transparency-violation report.

The APX example. examples/apx_basic.s uses the extended registers r16–r19 (via REX2 encodings) and the new-data-destination (NDD) 3-operand form. examples/test_apx_basic.c gates every case on a CPUID probe, so on real pre-APX silicon it reports # SKIP APX not available (it can never rot into a vacuous pass), while under sde64 -future — whose emulated CPUID reports APX_F — the gate opens and the routines actually execute and are asserted. This is the lane’s reason to exist: those routines run nowhere else in the test suite.

The AVX-512-on-AVX2 un-skip. The existing test_simd suite skips its AVX-512 case on a host without AVX-512F. Under sde64 -future that case runs as a real execution — the lane converts a documented capability self-skip into an assertion, regardless of the host’s true AVX support.

The instruction-mix report. make sde-mix histograms a suite’s dynamic instructions with SDE’s emulator-aware -mix tool and folds the process-wide total into the repo’s canonical asmtest_trace_t report shape, then prints the per-ISA-set breakdown that nothing else in the tree can produce.


The candid boundary

SDE is an emulator, so what the lane asserts holds up to emulation fidelity. Timing and the exact silicon-level ABI are not what SDE guarantees — it guarantees architectural results (registers, flags, memory, control flow). Two anchors keep that fidelity trustworthy:

  • Native TAP identity (the transparency null test above) proves SDE reproduces the real machine byte-for-byte on ISA the host does support.

  • The Unicorn cross-check (sde-crosscheck-test) runs the same baseline routines natively-under-SDE and through the independent Unicorn emulator tier and asserts they agree — an emulator-versus-emulator anchor on the ISA both model.

For the full design — the pinning discipline, the license posture (SDE is test-lane-only and never bundled), and the per-task validation — see the implementation note.