Skip to content

Commit 6de2898

Browse files
H. Peter Anvin (Intel)Copilot
andcommitted
testgen: document implicitly-sized memory operand coverage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5422294 commit 6de2898

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

tools/testgen/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,44 @@ instructions may have memory-operand restrictions this generator
300300
doesn't model (alignment, tuple-type quirks, etc.) and one bad
301301
candidate line shouldn't cost a mnemonic its pre-existing coverage.
302302

303+
## Implicitly-sized memory operand coverage
304+
305+
Operand-type tokens fall into two groups with respect to memory-operand
306+
sizing: tokens with no size baked into their own name (plain `mem`),
307+
and tokens whose name already encodes a fixed size (`mem8`/`16`/`32`/
308+
`64`/`128`/`256`/`512`, `rm8`/`16`/`32`/`64`, `xmmrm8`/`16`/`32`/`64`/
309+
`128`, `ymmrm256`, `zmmrm512`, `mmxrm`/`mmxrm64` — the same
310+
`%mem_sizebits` table used for disp-boundary coverage). For the first
311+
group, `mem_operand($rng, 0)` already omits a size keyword
312+
unconditionally, so a bare `[0x1234]`-style operand with no `dword`/
313+
`oword`/etc. prefix was already being generated and exercised before
314+
this feature existed (confirmed by inspecting already-committed
315+
`.asm` files for mnemonics like `PDISTIB`/`MOVNTI`, whose sole memory
316+
operand is untyped `mem`).
317+
318+
The second group is where the actual gap was: the generator always
319+
attached an explicit size keyword for these tokens, so NASM's
320+
`SM`-flag-driven implicit-size-inference path — where a memory
321+
operand's size is inferred from a paired, already-sized operand in the
322+
same instruction (a `SM0-N`-flagged template, per `x86/iflags.ph`),
323+
e.g. `ADD reg32,rm32` or `MOVBE reg32,mem32` never actually need a
324+
`dword` keyword — was never tested.
325+
326+
Rather than parsing and range-expanding the `SM`/`AR` flag families
327+
from `insns.xda` to determine precisely which operand positions
328+
support implicit sizing (effectively reimplementing NASM's own
329+
operand-size-disambiguation logic), `build_implicitsize_line()` takes
330+
the same probe-and-keep approach as the other coverage buckets: for
331+
the first operand whose base token has a nonzero `%mem_sizebits`
332+
entry, it emits a bare (unsized) memory operand instead of the usual
333+
explicitly-sized one, leaving every other operand as normally
334+
generated. The candidate line is routed through the shared cumulative
335+
staged probe (alongside hireg/apxreg/mask/maskz/broadcast/saeer/
336+
disp-boundary) and is only kept if it actually assembles for that
337+
specific instruction — so an instruction whose size truly can't be
338+
inferred (no `SM` flag, ambiguous encoding, etc.) simply doesn't gain
339+
the line, without risking the rest of its coverage.
340+
303341
## Bit-width (16/32/64) handling
304342

305343
Bit-mode support isn't derived from CPU/mode flags in `insns.xda` — the
@@ -385,6 +423,10 @@ the last full run:
385423
a deliberate approximation, not exhaustive boundary-value coverage.
386424
- Register-span (`rs2`/`rs4`) operands used by multi-register FMA
387425
instructions (e.g. `V4FMADDPS`) aren't targeted by dedicated coverage.
426+
- Implicit-size coverage only tries omitting the size keyword on the
427+
*first* size-carrying memory operand in a template; templates with
428+
multiple independently-sizable memory operands aren't exhaustively
429+
covered.
388430
- ~70+ distinct operand-type tokens have generator support (see the
389431
`%fixed`/`%gen` tables at the top of the script); any new/renamed
390432
token introduced by a future `insns.dat` change that isn't in those
@@ -425,3 +467,9 @@ change these counts (1987 mnemonics gained at least one `[eax+N]`
425467
boundary line, verified via the same per-mnemonic `.json` entry-count
426468
comparison, identical 6955/6955). `make -j32 travis` continues to pass
427469
in ~26s.
470+
471+
Adding implicitly-sized memory operand coverage likewise did not
472+
change these counts (1922 mnemonics gained at least one implicit-size
473+
line, verified via the same per-mnemonic `.json` entry-count
474+
comparison, identical 6955/6955). `make -j32 travis` continues to pass
475+
in ~26s.

0 commit comments

Comments
 (0)