Code:
/* First byte: Length. Following bytes: Opcode bytes. */
#define MAKE_INSTR(nm, ...) static const u8 OPCODE_##nm[] = { __VA_ARGS__ }
MAKE_INSTR(INVD, 2, 0x0f, 0x08);
MAKE_INSTR(WBINVD, 2, 0x0f, 0x09);
MAKE_INSTR(CPUID, 2, 0x0f, 0xa2);
MAKE_INSTR(RDMSR, 2, 0x0f, 0x32);
MAKE_INSTR(WRMSR, 2, 0x0f, 0x30);
MAKE_INSTR(VMCALL, 3, 0x0f, 0x01, 0xd9);
MAKE_INSTR(HLT, 1, 0xf4);
MAKE_INSTR(INT3, 1, 0xcc);
MAKE_INSTR(RDTSC, 2, 0x0f, 0x31);
static const u8 *opc_bytes[INSTR_MAX_COUNT] =
{
[INSTR_INVD] = OPCODE_INVD,
[INSTR_WBINVD] = OPCODE_WBINVD,
[INSTR_CPUID] = OPCODE_CPUID,
[INSTR_RDMSR] = OPCODE_RDMSR,
[INSTR_WRMSR] = OPCODE_WRMSR,
[INSTR_VMCALL] = OPCODE_VMCALL,
[INSTR_HLT] = OPCODE_HLT,
[INSTR_INT3] = OPCODE_INT3,
[INSTR_RDTSC] = OPCODE_RDTSC
};
Here's a snippet of xen/arch/x86/hvm/svm/emulate.c that I originally wrote, which uses variable length array to describe differnet instruction formats.
--
Mats