NetBoot/vasm-1/cpus/x86/cpu.h

270 lines
9.5 KiB
C

/* cpu.h x86 cpu-description header-file */
/* (c) in 2005-2006,2017 by Frank Wille */
#define LITTLEENDIAN 1
#define BIGENDIAN 0
#define VASM_CPU_X86 1
#define MNEMOHTABSIZE 0x8000
/* maximum number of operands in one mnemonic */
#define MAX_OPERANDS 3
/* maximum number of mnemonic-qualifiers per mnemonic */
#define MAX_QUALIFIERS 1
/* data type to represent a target-address */
typedef int64_t taddr;
typedef uint64_t utaddr;
/* minimum instruction alignment */
#define INST_ALIGN 1
/* default alignment for n-bit data */
#define DATA_ALIGN(n) 1
/* default alignment mode for .align directive */
#define CPU_DEF_ALIGN 1 /* alignment in bytes */
/* operand class for n-bit data definitions */
int x86_data_operand(int);
#define DATA_OPERAND(n) x86_data_operand(n)
/* make sure operand is cleared upon first entry into parse_operand() */
#define NEED_CLEARED_OPERANDS 1
/* register symbols */
#define HAVE_REGSYMS
#define REGSYMHTSIZE 64
/* reg_flags: */
#define RegRex 0x1 /* Extended register. */
#define RegRex64 0x2 /* Extended 8 bit register. */
/* type to store each operand */
typedef struct {
int type; /* real type of operand */
int parsed_type; /* type recognized by parser */
unsigned int flags;
expr *value; /* displacement or immediate value */
regsym *basereg; /* base-reg. for SIB or single register */
regsym *indexreg;
expr *scalefactor;
regsym *segoverride;
int log2_scale; /* 0-3 for scale factor 1,2,4,8 */
} operand;
/* register operand types */
#define Reg8 0x1
#define Reg16 0x2
#define Reg32 0x4
#define Reg64 0x8
/* immediate operand types*/
#define Imm8 0x10
#define Imm8S 0x20
#define Imm16 0x40
#define Imm32 0x80
#define Imm32S 0x100
#define Imm64 0x200
#define Imm1 0x400 /* for 1-bit shift-instructions */
/* memory operand types */
#define Disp8 0x800
#define Disp16 0x1000
#define Disp32 0x2000
#define Disp32S 0x4000
#define Disp64 0x8000
#define BaseIndex 0x10000 /* indirect base-register has optional index */
/* special operand types */
#define ShiftCntReg 0x20000 /* Shift-count register (%cl) */
#define IOPortReg 0x40000 /* I/O port register (%dx) */
#define CtrlReg 0x80000
#define DebugReg 0x100000
#define TestReg 0x200000
#define Acc 0x400000 /* Accumulator (%al or %ax or %eax) */
#define SegReg2 0x800000 /* Segment register with 2 bits */
#define SegReg3 0x1000000 /* Segment register with 3 bits */
#define MMXReg 0x2000000
#define XMMReg 0x4000000
#define FloatReg 0x8000000 /* Float register %st(n) */
#define FloatAcc 0x10000000 /* Float stack top %st(0), float-accumulator */
#define EsSeg 0x20000000 /* String instr. oper. with fixed ES seg. */
#define JmpAbs 0x40000000 /* Absolute jump/call instruction */
#define InvMem 0x80000000 /* modrm-byte doesn't support memory form */
/* data operands (@@@ define their own flags?) */
#define FloatData (FloatAcc)
#define Data8 (Disp8)
#define Data16 (Disp16)
#define Data32 (Disp32)
#define Data64 (Disp64)
#define Float32 (Disp32|FloatData)
#define Float64 (Disp64|FloatData)
/* operand type groups */
#define Reg (Reg8|Reg16|Reg32|Reg64)
#define WordReg (Reg16|Reg32|Reg64)
#define AnyReg (Reg|MMXReg|XMMReg|SegReg2|SegReg3|CtrlReg|DebugReg|TestReg)
#define ImpliedReg (IOPortReg|ShiftCntReg|Acc|FloatAcc)
#define Imm (Imm8|Imm8S|Imm16|Imm32S|Imm32|Imm64)
#define EncImm (Imm8|Imm16|Imm32|Imm32S)
#define Disp (Disp8|Disp16|Disp32|Disp32S|Disp64)
#define AnyMem (Disp8|Disp16|Disp32|Disp32S|BaseIndex|InvMem)
/* currently we do not differentiate between those memory types, */
/* but the opcode table is prepared for it */
#define LLongMem AnyMem
#define LongMem AnyMem
#define ShortMem AnyMem
#define WordMem AnyMem
#define ByteMem AnyMem
/* flags */
#define OPER_REG 1 /* operand is a direct register */
#define OPER_PCREL 2 /* PC-relative operand */
/* x86 opcode prefixes */
#define WAIT_PREFIX 0
#define LOCKREP_PREFIX 1
#define ADDR_PREFIX 2
#define DATA_PREFIX 3
#define SEG_PREFIX 4
#define REX_PREFIX 5 /* must be the last one */
#define MAX_PREFIXES 6 /* maximum number of prefixes */
/* x86 segment register numbers */
#define ESEG_REGNUM 0
#define CSEG_REGNUM 1
#define SSEG_REGNUM 2
#define DSEG_REGNUM 3
#define FSEG_REGNUM 4
#define GSEG_REGNUM 5
/* Mod-R/M byte, which follows the opcode */
typedef struct {
unsigned char mode; /* how to interpret regmem & reg */
unsigned char reg; /* register operand or extended opcode */
unsigned char regmem; /* register or memory operand (addr.mode) */
} modrm_byte;
/* SIB (scale, index, base) byte, which follows modrm_byte in some
i386 addressing modes */
typedef struct {
unsigned char scale; /* scale-factor (1, 2, 4 or 8) */
unsigned char index; /* index register */
unsigned char base; /* base register */
} sib_byte;
#define EBP_REGNUM 5
#define ESP_REGNUM 4
/* modrm_byte.regmem for 2-byte opcode escape */
#define TWO_BYTE_ESCAPE (ESP_REGNUM)
/* sib_byte.index for no index register */
#define NO_INDEXREG (ESP_REGNUM)
/* sib_byte.base for no base register */
#define NO_BASEREG (EBP_REGNUM)
#define NO_BASEREG16 6
/* instruction extension */
#define HAVE_INSTRUCTION_EXTENSION 1
typedef struct {
uint32_t base_opcode;
unsigned char flags;
unsigned char num_prefixes;
unsigned char prefix[MAX_PREFIXES];
modrm_byte rm;
sib_byte sib;
short last_size;
} instruction_ext;
/* flags: */
#define HAS_REG_OPER 0x1 /* inst. has direct-register operands */
#define SUFFIX_CHECKED 0x2 /* suffix assigned and checked */
#define MODRM_BYTE 0x4 /* needs mod/rm byte */
#define SIB_BYTE 0x8 /* needs sib byte */
#define NEGOPT 0x40 /* negatively optimized, bytes gained */
#define POSOPT 0x80 /* positively optimized, bytes gained */
#define OPTFAILED (POSOPT|NEGOPT) /* no longer try to optimize this */
/* max_opt_tries:
An instruction optimized more frequent than that is been considered
'oscillating' (e.g. by effects of alignment-directives) and should
no longer be optimized! */
#define MAX_OPT_TRIES 10
/* additional mnemonic data */
typedef struct {
uint32_t base_opcode;
uint32_t extension_opcode;
uint32_t opcode_modifier;
uint32_t available;
} mnemonic_extension;
/* extension_opcode */
#define NO_EXTOPCODE 0xffff
/* cpu available flags: */
#define CPU086 0x1
#define CPU186 0x2
#define CPU286 0x4
#define CPU386 0x8
#define CPU486 0x10
#define CPU586 0x20
#define CPU686 0x40
#define CPUP4 0x80
#define CPUK6 0x100
#define CPUAthlon 0x200
#define CPUSledgehammer 0x400
#define CPUMMX 0x800
#define CPUSSE 0x1000
#define CPUSSE2 0x2000
#define CPU3dnow 0x4000
#define CPUPNI 0x8000
#define CPUPadLock 0x10000
#define CPU64 0x4000000
#define CPUNo64 0x8000000
#define CPUAny (CPU086|CPU186|CPU286|CPU386|CPU486|CPU586|CPU686|CPUP4|CPUSledgehammer|CPUMMX|CPUSSE|CPUSSE2|CPUPNI|CPU3dnow|CPUK6|CPUAthlon|CPUPadLock)
/* opcode_modifier: */
#define W 0x1 /* operands can be words or dwords */
#define M 0x4 /* has Modrm byte */
#define FloatR 0x8 /* swapped src/dest for floats: MUST BE 0x8 */
#define ShortForm 0x10 /* reg. enc. in 3 low-order bits of opcode */
#define FloatMF 0x20 /* FP insn memory format bit, sized by 0x4 */
#define Jmp 0x40 /* relative conditional and uncond. branches */
#define JmpDword 0x80 /* relative 16/32 bit calls */
#define JmpByte 0x100 /* loop and jecxz */
#define JmpInterSeg 0x200 /* inter segment calls and branches */
#define FloatD 0x400 /* direction for FP insns: MUST BE 0x400 */
#define Seg2ShortForm 0x800 /* 2-bit segment reg. encoded in opcode */
#define Seg3ShortForm 0x1000 /* 3-bit segment reg. encoded in opcode */
#define Size16 0x2000 /* needs a size prefix in 32-bit mode */
#define Size32 0x4000 /* needs a size prefix in 16-bit mode */
#define Size64 0x8000 /* needs a size prefix in 16-bit mode */
#define IgnoreSize 0x10000 /* operand size prefix is ignored */
#define DefaultSize 0x20000 /* default instruction size depends on mode */
#define b_Illegal 0x40000 /* b suffix is illegal */
#define w_Illegal 0x80000 /* w suffix is illegal */
#define l_Illegal 0x100000 /* l suffix is illegal */
#define s_Illegal 0x200000 /* s suffix is illegal */
#define q_Illegal 0x400000 /* q suffix is illegal */
#define x_Illegal 0x800000 /* x suffix is illegal */
#define FWait 0x1000000 /* needs an FWAIT prefix */
#define StrInst 0x2000000 /* string instructions */
#define FakeLastReg 0x4000000 /* duplicate last reg. for clr and imul */
#define IsPrefix 0x8000000 /* opcode is a prefix */
#define ImmExt 0x10000000 /* has extension in 8 bit immediate */
#define NoRex64 0x20000000 /* doesn't require REX64 prefix */
#define Rex64 0x40000000 /* requires REX64 prefix */
#define Deprecated 0x80000000 /* deprecated FPU instruction */