On 20/04/16 18:04, Richard Henderson wrote: > On 04/20/2016 02:55 AM, Alex Bennée wrote: >>> +static void tcg_out_nopn(TCGContext *s, int n) >>> +{ >>> + static const uint8_t nop1[] = { 0x90 }; >>> + static const uint8_t nop2[] = { 0x66, 0x90 }; >>> + static const uint8_t nop3[] = { 0x8d, 0x76, 0x00 }; >>> + static const uint8_t *const nopn[] = { nop1, nop2, nop3 }; >>> + int i; >>> + assert(n <= ARRAY_SIZE(nopn)); >>> + for (i = 0; i < n; ++i) { >>> + tcg_out8(s, nopn[n - 1][i]); >>> + } >>> +} >> >> *shudder* I recall x86 instruction encoding is weird. Maybe a comment >> for the function to describe the 3 forms of NOP we have here? > > I think I'd prefer to drop the tables and do > > /* Emit 1 or 2 operand size prefixes for the standard one byte nop, > xchg %eax,%eax, forming xchg %ax,%ax. All cores accept the > duplicate prefix, and all of the interesting recent cores can > decode and discard the duplicates in a single cycle. */ > for (i = 1; i < n; ++i) { > tcg_out8(s, 0x66); > } > tcg_out8(s, 0x90);
It's fine if you are sure about that :) Kind regards, Sergey