cosmopolitan/third_party/xed/x86.h

242 lines
10 KiB
C
Raw Normal View History

2020-06-15 14:18:57 +00:00
#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
2020-06-15 14:18:57 +00:00
#define xed_modrm_mod(M) (((M)&0xff) >> 6)
#define xed_modrm_reg(M) (((M)&0b00111000) >> 3)
2020-06-15 14:18:57 +00:00
#define xed_modrm_rm(M) ((M)&7)
#define xed_sib_base(M) ((M)&7)
#define xed_sib_index(M) (((M)&0b00111000) >> 3)
2020-06-15 14:18:57 +00:00
#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
2020-06-15 14:18:57 +00:00
struct XedOperands { /*
rep
log𝑏
mode
eamode
mod
sego
rex REGISTER
rexb DISPATCH
srm ENCODING
rex
rexb
rm
rexw
osz
rex
rexr
reg
32222
08642 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() */
2020-06-15 14:18:57 +00:00
uint8_t nrexes;
uint8_t nprefixes;
2020-06-15 14:18:57 +00:00
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 */
2020-06-15 14:18:57 +00:00
uint8_t pos_disp;
uint8_t pos_imm;
uint8_t pos_imm1;
uint8_t pos_modrm;
uint8_t pos_opcode;
2020-06-15 14:18:57 +00:00
uint8_t pos_sib;
};
struct XedDecodedInst {
unsigned char length;
uint8_t bytes[15];
struct XedOperands op;
};
2020-06-15 14:18:57 +00:00
forceinline void xed_operands_set_mode(struct XedOperands *p, int mmode) {
p->realmode = false;
2020-06-15 14:18:57 +00:00
switch (mmode) {
default:
2020-06-15 14:18:57 +00:00
case XED_MACHINE_MODE_LONG_64:
p->mode = XED_MODE_LONG;
2020-06-15 14:18:57 +00:00
return;
case XED_MACHINE_MODE_LEGACY_32:
case XED_MACHINE_MODE_LONG_COMPAT_32:
p->mode = XED_MODE_LEGACY;
2020-06-15 14:18:57 +00:00
break;
case XED_MACHINE_MODE_REAL:
p->realmode = true;
p->mode = XED_MODE_REAL;
2020-06-15 14:18:57 +00:00
break;
case XED_MACHINE_MODE_UNREAL:
p->realmode = true;
p->mode = XED_MODE_LEGACY;
2020-06-15 14:18:57 +00:00
break;
case XED_MACHINE_MODE_LEGACY_16:
case XED_MACHINE_MODE_LONG_COMPAT_16:
p->mode = XED_MODE_REAL;
2020-06-15 14:18:57 +00:00
break;
}
}
extern const char kXedErrorNames[];
2021-02-27 18:33:32 +00:00
extern const uint8_t kXedEamode[2][3];
2020-06-15 14:18:57 +00:00
struct XedDecodedInst *xed_decoded_inst_zero_set_mode(struct XedDecodedInst *,
int);
int xed_instruction_length_decode(struct XedDecodedInst *, const void *,
size_t);
2020-06-15 14:18:57 +00:00
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_XED_X86_H_ */