Intel instruction set reference gives us addsd instruction:
VEX.NDS.LIG.F2.0F.WIG 58 /r
VADDSD xmm1, xmm2, xmm3/m64
As we can see L bit is ignored (can be either 0 or 1).
Machine code of addsd xmm0, xmm0, xmm0: 0xC4, 0xE1, 0x7B, 0x58, 0xC0
C4 - indicates 3-byte VEX prefix
E1 - R = 1; X = 1; B = 1; m-mmmm = 1 (implied 0F escape)
7B - W = 0; vvvv = 1111 (xmm0); L = 0; pp = 11 (implied F2 prefix)
58 - opcode byte
C0 - mod-rm byte
Let's test:
void exec(Byte* code, int size)
{
Byte* buf = (Byte*)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(buf, code, size);
buf[size] = 0xC3;
((void (*)())buf)();
VirtualFree(buf, 4096, MEM_DECOMMIT);
}
void f()
{
Byte code[] = { 0xC4, 0xE1, 0x7B, 0x58, 0xC0 };
exec(code, sizeof(code));
}
Fine, also visual studio disassembler recognizes the instruction.
However when I change L bit to 1 (0x7B is replaced by 0x7F) disassembler does not recognize the instruction and Invalid Instruction exception is generated. Does it mean that L bit must always be 0 despite Intel manual?