mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
fa20edc44d
- Remove most __ASSEMBLER__ __LINKER__ ifdefs - Rename libc/intrin/bits.h to libc/serialize.h - Block pthread cancelation in fchmodat() polyfill - Remove `clang-format off` statements in third_party
248 lines
11 KiB
C
248 lines
11 KiB
C
#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)
|
||
|
||
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 /* COSMOPOLITAN_THIRD_PARTY_XED_X86_H_ */
|