cosmopolitan/third_party/xed/x86.h
2022-08-21 15:51:44 -07:00

250 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef COSMOPOLITAN_THIRD_PARTY_XED_X86_H_
#define COSMOPOLITAN_THIRD_PARTY_XED_X86_H_
/* ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▄▄▄▄
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▄▓▓▓▓▓▓▄ ▄▓▓▓▓▓▓▓▓ ▄▓▓▓▀
▓▓▓▓ ▓▓▓▓▓ ▓ ▓▓▓▓ ▓▓ ▓▓▓ ▄▓▓▓▓
▬▬▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓▓▓▓▓▓▓▓▓▓▬▬▬▬▬▬▬▬▬▬▬▓▓▓▬▬▬▓▓▓▬▬▬▬▬▬▬▬▓▓▬▬▬▬▓▓▓▓▓▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
│ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▄ ▓▓▓ ▓▓▓▓ │
▬▬▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓ ▓▓▓▓▓▬▬▬▬▬▬▬▬▓▓▓▓▓▓▓▬▬▬▀▓▓▓▓▄▄▄▓▓▓▬▬▓▓▓▓▓▓▓▓▓▓▓▓▓▬▬▬▬▬▬▬▬▬▬
│ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▄ ▄▄▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▄ │
▬▬▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓ ▓▓▓▓▓▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓▓▄▄▓▓▀ ▀▀▓▓▓▓▓▓▓▓▓▓▬▬▬▬▬▬▬▬▓▓▓▬▬▬▬▬▬▬▬
▬▬▬▬▬▬▬▬║▬▬▬▬▓▓▓▓ ▓▓▓▓▓▬▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓▓▓▓▬▬▬▬▬▬▬▬▬▓▓▓ ▓▓▓▬▬▬▬▬▬▬▬▓▓▓▬▬▬▬║▬▬▬
▬▬▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓ ▓▓▓▓▓▬▬▬▬▬▬▬▬▬▬▬▓▓▓▓▬▬▓▓▓▬▬▬▬▬▬▬▬▓▓▓▬▓▓▓▓▬▬▬▬▬▬▬▓▓▓▬▬▬▬▬▬▬▬
■■■■■■■■║■■■■▓▓▓▓ ▓▓▓▓▓■■■▓▓▓▄▄▄▓▓▓▓■■■■▬▓▓▓▓▄▄▄▄▓▓▓■■■■▬▓▓▓▓▄▄▄▓▓▓▓▀■■■■║■■■
■■■■■■■■■■■■■▓▓▓▓▓▓▓▓▓▓▓▓▓■■■■■▀▓▓▓■■■■■■■■■■■■■■▀▀■■■■■■■■■■■■▀▓▓▀■■■■■■■■■■■■■
║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓║
╔───────╨───────────────────────────────────────────────────────────────────╨──╗
│ cosmopolitan § virtual machine » byte code language │
╚─────────────────────────────────────────────────────────────────────────────*/
#define XED_MAX_INSTRUCTION_BYTES 15
#define XED_MODE_REAL 0
#define XED_MODE_LEGACY 1
#define XED_MODE_LONG 2
#define XED_HINT_NTAKEN 2
#define XED_HINT_TAKEN 4
#define XED_HINT_ALTER 6
#define XED_SEG_ES 1
#define XED_SEG_CS 2
#define XED_SEG_SS 3
#define XED_SEG_DS 4
#define XED_SEG_FS 5
#define XED_SEG_GS 6
#define xed_modrm_mod(M) (((M)&0xff) >> 6)
#define xed_modrm_reg(M) (((M)&0b00111000) >> 3)
#define xed_modrm_rm(M) ((M)&7)
#define xed_sib_base(M) ((M)&7)
#define xed_sib_index(M) (((M)&0b00111000) >> 3)
#define xed_sib_scale(M) (((M)&0xff) >> 6)
#define xed_get_modrm_reg_field(M) (((M)&0x38) >> 3)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define XED_MACHINE_MODE_REAL XED_MODE_REAL
#define XED_MACHINE_MODE_LEGACY_32 XED_MODE_LEGACY
#define XED_MACHINE_MODE_LONG_64 XED_MODE_LONG
#define XED_MACHINE_MODE_UNREAL (1 << 2 | XED_MODE_REAL)
#define XED_MACHINE_MODE_LEGACY_16 (2 << 2 | XED_MODE_REAL)
#define XED_MACHINE_MODE_LONG_COMPAT_16 (3 << 2 | XED_MODE_REAL)
#define XED_MACHINE_MODE_LONG_COMPAT_32 (4 << 2 | XED_MODE_LEGACY)
#define XED_MACHINE_MODE_LAST (XED_MACHINE_MODE_LONG_COMPAT_32 + 1)
#define XED_ERROR_NONE 0
#define XED_ERROR_BUFFER_TOO_SHORT 1
#define XED_ERROR_GENERAL_ERROR 2
#define XED_ERROR_INVALID_FOR_CHIP 3
#define XED_ERROR_BAD_REGISTER 4
#define XED_ERROR_BAD_LOCK_PREFIX 5
#define XED_ERROR_BAD_REP_PREFIX 6
#define XED_ERROR_BAD_LEGACY_PREFIX 7
#define XED_ERROR_BAD_REX_PREFIX 8
#define XED_ERROR_BAD_EVEX_UBIT 9
#define XED_ERROR_BAD_MAP 10
#define XED_ERROR_BAD_EVEX_V_PRIME 11
#define XED_ERROR_BAD_EVEX_Z_NO_MASKING 12
#define XED_ERROR_NO_OUTPUT_POINTER 13
#define XED_ERROR_NO_AGEN_CALL_BACK_REGISTERED 14
#define XED_ERROR_BAD_MEMOP_INDEX 15
#define XED_ERROR_CALLBACK_PROBLEM 16
#define XED_ERROR_GATHER_REGS 17
#define XED_ERROR_INSTR_TOO_LONG 18
#define XED_ERROR_INVALID_MODE 19
#define XED_ERROR_BAD_EVEX_LL 20
#define XED_ERROR_UNIMPLEMENTED 21
#define XED_ERROR_LAST 22
#define XED_ADDRESS_WIDTH_INVALID 0
#define XED_ADDRESS_WIDTH_16b 2
#define XED_ADDRESS_WIDTH_32b 4
#define XED_ADDRESS_WIDTH_64b 8
#define XED_ADDRESS_WIDTH_LAST 9
#define XED_ILD_MAP0 0 /* 8086+ ... */
#define XED_ILD_MAP1 1 /* 286+ 0x0F,... */
#define XED_ILD_MAP2 2 /* Core2+ 0x0F,0x38,... */
#define XED_ILD_MAP3 3 /* Core2+ 0x0F,0x3A,... */
#define XED_ILD_MAP4 4
#define XED_ILD_MAP5 5
#define XED_ILD_MAP6 6
#define XED_ILD_MAPAMD 7
#define XED_ILD_MAP_XOP8 8
#define XED_ILD_MAP_XOP9 9
#define XED_ILD_MAP_XOPA 10
#define XED_ILD_MAP_LAST 11
#define XED_ILD_MAP_INVALID 12
struct XedOperands { /*
┌rep
│ ┌log₂𝑏
│ │ ┌mode
│ │ │ ┌eamode
│ │ │ │ ┌mod
│ │ │ │ │
│ │ │ │ │ ┌sego
│ │ │ │ │ │
│ │ │ │ │ │ ┌rex REGISTER
│ │ │ │ │ │ │┌rexb DISPATCH
│ │ │ │ │ │ ││┌srm ENCODING
│ │ │ │ │ │ │││ ┌rex
│ │ │ │ │ │ │││ │┌rexb
│ │ │ │ │ │ │││ ││┌rm
│ │ │ │ │ │ │││ │││ ┌rexw
│ │ │ │ │ │ │││ │││ │┌osz
│ │ │ │ │ │ │││ │││ ││┌rex
│ │ │ │ │ │ │││ │││ │││┌rexr
│ │ │ │ │ │ │││ │││ ││││┌reg
│3│2│2│2│2 │ │││ │││ │││││
│0│8│6│4│2 │18 │││12│││ 7│││││ 0
├┐├┐├┐├┐├┐ ├─┐ ││├─┐││├─┐││││├─┐
00000000000000000000000000000000*/
uint32_t rde;
union {
struct {
union {
uint8_t opcode;
uint8_t srm : 3;
};
uint8_t map : 4;
};
uint16_t dispatch;
};
union {
uint8_t sib;
struct {
uint8_t base : 3;
uint8_t index : 3;
uint8_t scale : 2;
};
};
bool osz : 1; /* operand size override prefix */
bool rexw : 1; /* rex.w or rex.wb or etc. 64-bit override */
bool rexb : 1; /* rex.b or rex.wb or etc. see modrm table */
bool rexr : 1; /* rex.r or rex.wr or etc. see modrm table */
bool rex : 1; /* any rex prefix including rex */
bool rexx : 1; /* rex.x or rex.wx or etc. see sib table */
bool rexrr : 1; /* evex */
bool asz : 1; /* address size override */
int64_t disp; /* displacement(%xxx) mostly sign-extended */
uint64_t uimm0; /* $immediate mostly sign-extended */
bool out_of_bytes : 1;
bool is_intel_specific : 1;
bool ild_f2 : 1;
bool ild_f3 : 1;
bool has_sib : 1;
bool realmode : 1;
bool amd3dnow : 1;
bool lock : 1;
union {
uint8_t modrm; /* selects address register */
struct {
uint8_t rm : 3;
uint8_t reg : 3;
uint8_t mod : 2;
};
};
uint8_t max_bytes;
uint8_t rep : 2; /* 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe) */
uint8_t has_modrm : 2;
bool imm_signed : 1; /* internal */
bool disp_unsigned : 1; /* internal */
uint8_t seg_ovd : 3; /* XED_SEG_xx */
uint8_t error : 5; /* enum XedError */
uint8_t mode : 2; /* real,legacy,long */
uint8_t hint : 3; /* static branch prediction */
uint8_t uimm1; /* enter $x,$y */
uint8_t disp_width; /* in bits */
uint8_t imm_width; /* in bits */
uint8_t mode_first_prefix; /* see xed_set_chip_modes() */
uint8_t nrexes;
uint8_t nprefixes;
uint8_t nseg_prefixes;
uint8_t ubit; /* vex */
uint8_t vexvalid; /* vex */
uint8_t vexdest3; /* vex */
uint8_t vexdest4; /* vex */
uint8_t vexdest210; /* vex */
uint8_t vex_prefix; /* vex */
uint8_t zeroing; /* evex */
uint8_t bcrc; /* evex */
uint8_t llrc; /* evex */
uint8_t vl; /* evex */
uint8_t mask; /* evex */
uint8_t imm1_bytes; /* evex */
uint8_t pos_disp;
uint8_t pos_imm;
uint8_t pos_imm1;
uint8_t pos_modrm;
uint8_t pos_opcode;
uint8_t pos_sib;
};
struct XedDecodedInst {
unsigned char length;
uint8_t bytes[15];
struct XedOperands op;
};
#define xed_operands_set_mode(p, machine_mode) \
do { \
struct XedOperands *__p = p; \
__p->realmode = false; \
switch (machine_mode) { \
default: \
case XED_MACHINE_MODE_LONG_64: \
__p->mode = XED_MODE_LONG; \
break; \
case XED_MACHINE_MODE_LEGACY_32: \
case XED_MACHINE_MODE_LONG_COMPAT_32: \
__p->mode = XED_MODE_LEGACY; \
break; \
case XED_MACHINE_MODE_REAL: \
__p->realmode = true; \
__p->mode = XED_MODE_REAL; \
break; \
case XED_MACHINE_MODE_UNREAL: \
__p->realmode = true; \
__p->mode = XED_MODE_LEGACY; \
break; \
case XED_MACHINE_MODE_LEGACY_16: \
case XED_MACHINE_MODE_LONG_COMPAT_16: \
__p->mode = XED_MODE_REAL; \
break; \
} \
} while (0)
extern const char kXedErrorNames[];
extern const uint8_t kXedEamode[2][3];
struct XedDecodedInst *xed_decoded_inst_zero_set_mode(struct XedDecodedInst *,
int);
int xed_instruction_length_decode(struct XedDecodedInst *, const void *,
size_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_XED_X86_H_ */