Apx add ndd - #13916
Draft
jlb6740 wants to merge 9 commits into
Draft
Conversation
Subscribe to Label ActionDetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "cranelift:meta", "isle"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
Capstone's `disasm_all` stops at the first instruction it can't decode and returns success with whatever it managed to decode. We never compared that against the block length, so that instruction and everything after it vanished from the listing. For `precise-output` filetests the truncated output gets blessed, and the test then passes without asserting anything about those bytes. This is reachable today: the bundled capstone can't decode AVX-VNNI, so a function containing `vpdpbusd` was silently dropping five instructions. It is also a precursor to the APX work, whose EVEX map 4 encodings hit the same path; those filetests were being blessed as truncated output and so verified nothing about the instructions they were added to cover. Print the leftover bytes as `.byte`, keeping the reloc and trap annotations. s390x expectations already look like this. Resyncing after the bad instruction isn't possible on x86 without knowing its length, and guessing yields plausible but wrong instructions. The updated expectations only gain lines; nothing already printed changed. Those blocks end in constant pool data that capstone was already rendering as nonsense. prtest:full
Add the runtime EVEX map-4 prefix builder (ND/NF/EGPR bits per APX spec rev 8, Fig. 3.3), wire it into the meta code generator, and enable the NDD `addq` instruction. Verified with a byte-exact encoding test (62 F4 F4 18 01 C2). Instruction selection (ISLE lowering) and EGPR register allocation are not part of this change; the `.clif` filetest cannot select these instructions yet.
jlb6740
force-pushed
the
apx-add-ndd
branch
2 times, most recently
from
August 21, 2026 23:34
4df6421 to
74c42a8
Compare
Add a `use_apx` ISLE predicate and lower 64-bit `iadd` to the NDD form of `addq` (EVEX map 4) when the `has_apx` target flag is enabled. Gate the instruction on the `apx` assembler feature and align the NDD destination with the EVEX `vvvv` operand so the result is written to a fresh register without clobbering either input. Add filetests exercising the new lowering and the `has_apx` flag parsing.
The assembler's generated `Display` impl derives AT&T operand order by reversing the DSL's Intel-style order. That works when the destination is the ModRM.reg operand, but APX "new data destination" (NDD) forms encode their destination in `vvvv`, which the DSL must list in the middle so that the positional slot assignment in `generate_vex_or_evex_prefix` maps operands to `reg`/`vvvv`/`rm` correctly. Reversing therefore left the destination in the middle: `addq` printed as `addq %rsi, %rax, %rdi` where both AT&T convention and XED expect the destination last. Identify these forms from the `ND` bit rather than from the operand shape. `[Reg, Reg, RegMem]` is also used by ordinary VEX instructions, and `[Reg, RegMem, Reg]` is used by the BMI2 `bzhi`/`sarx`/`shlx`/`shrx` family with the slots assigned the other way around, so the shape alone cannot identify NDD. When `ND = 1`, sources keep their DSL order and the destination is printed last. Any future NDD instruction then gets the correct order without a per-instruction `Display` customization. Only printing changes here; the emitted encodings are untouched.
The bundled capstone build cannot decode the APX extended-EVEX ("map 4")
encodings at all, returning zero instructions, which tripped the "not a
single instruction" assertion in the roundtrip oracle. Skip them the same
way AVX-VNNI instructions are already skipped.
APX stays in `ALL_FEATURES` so that the XED oracle, which does understand
map 4, keeps exercising these instructions rather than losing coverage.
EVEX normally stores an 8-bit displacement as a multiple of a tuple-derived factor N, so a 128-bit `Full` tuple divides the byte offset by 16. APX promotes legacy GPR instructions into extended-EVEX "map 4", and those keep legacy displacement semantics: disp8 is a plain byte offset. We were applying the vector scaling to them anyway, so `0x50(%rdi)` encoded as disp8 = 0x50 / 16 = 0x05 and the CPU would read it as `0x5(%rdi)`. Found by the XED fuzz oracle; capstone cannot decode map 4 at all, and the memory-operand form is not reachable from lowering yet, so nothing else would have caught it. Key the exemption off `ApxClass::LegacyGpr` rather than the map number. Promoted vector instructions and APX-extended AVX-512 instructions are still vector encodings and do use compressed displacements.
Adding the `two_op`/`three_op` parameters to `generate_vex_or_evex_prefix` pushed both call sites past the width limit, so rustfmt wants them broken across lines. No functional change.
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 APX NDD (new data destination) form of 64-bit
add, as an initialend-to-end slice through the stack: DSL entry, extended-EVEX (map 4) encoding,
an ISLE lowering rule gated on
has_apx, and a filetest.This is deliberately one instruction rather than a batch to make sure of the generic
mechanisms definining APX, not necessarily
addqitself:NDbit, since withND = 1thedestination lives in
vvvvand prints last in AT&T order. Keying off the bitrather than the operand shape means future NDD instructions get this for free.
disp8scaling is disabled forApxClass::LegacyGpr. Map-4 instructions arepromoted legacy instructions and keep plain byte displacements rather than
EVEX compressed displacement.
Two things:
has_apxautomatically, becauseis_x86_feature_detected!("apxf")is still unstable (Tracking Issue for APX target feature rust-lang/rust#139284).Detection can follow once that lands.
isn't selected yet. It's covered by an assembler unit test instead.
Still a draft: it's stacked on #14136, so that commit currently shows up in the
diff here. I'll rebase and mark this ready once #14136 merges.