An x86-64 EVEX (AVX-512) machine-code encoder. EvexAssembler emits raw
instruction bytes into a growable buffer so you can JIT-assemble 512-bit-wide
compute kernels at runtime, then map the bytes executable and call them through
an unmanaged function pointer.
There is one EVEX prefix path: the R/X/B/R'/V' extension bits are
computed from the register operands, so every encoder reaches the full zmm0–
zmm31 and r0–r15 range. Displacements are given in bytes; the encoder
selects the encoding the ISA forces — compressed disp8 (scaled by 64) when the
offset is a 64-byte multiple in range, disp32 otherwise, a SIB byte for
rsp/r12 bases, and a forced disp8=0 for rbp/r13.
Operating envelope: 512-bit operands, no write-masking, no broadcast. x86-64.
using Evex.Net;
EvexAssembler asm = new();
asm.MovImm32(Gpr.Rcx, blocks);
Label top = asm.DefineLabel();
asm.MarkLabel(top);
asm.VmovupsLoad(Zmm.Zmm0, Gpr.Rdi);
asm.VmovupsStore(Gpr.Rsi, Zmm.Zmm0);
asm.AddImm32(Gpr.Rdi, 64);
asm.AddImm32(Gpr.Rsi, 64);
asm.Dec(Gpr.Rcx);
asm.Jnz(top);
asm.Ret();
byte[] code = asm.ToArray();DefineLabel/MarkLabel name positions; Jmp/Jz/Jnz and VmovupsLoadRip
record rel32 references that ToArray resolves. A label referenced but never
marked throws on ToArray.
| Group | Methods |
|---|---|
| Load/store | VmovupsLoad, VmovupsStore, Vmovdqu64Load, Vmovdqu64Store, VmovupsLoadRip |
| Register move | Vmovdqa64 |
| Logical | Vpxord, Vpandd, Vpord, Vpxorq, Vpandq, Vporq |
| Arithmetic | Vpaddq, Vpsubq |
| Ternary / permute | Vpternlogq, Vpermq |
| Shift | Vpsllq, Vpsrlq |
| Mask | Vptestmq, Kortestw |
| GPR | MovImm32, AddImm32, SubImm32, Dec, MovReg |
| Control | DefineLabel, MarkLabel, Jmp, Jz, Jnz, Ret |
dotnet build Evex.Net.slnx
dotnet test Evex.Net.slnx
Encodings are pinned byte-for-byte against GNU as/objdump output in the test
suite.