/* Declarations for Intel 80386 opcode table
- Copyright (C) 2007-2021 Free Software Foundation, Inc.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU opcodes library.
02110-1301, USA. */
#include "opcode/i386.h"
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif
-
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
CpuLZCNT,
/* POPCNT support required */
CpuPOPCNT,
+ /* MONITOR support required */
+ CpuMONITOR,
/* SSE4.1 support required */
CpuSSE4_1,
/* SSE4.2 support required */
CpuAVX512DQ,
/* Intel AVX-512 BW Instructions support required. */
CpuAVX512BW,
- /* Intel L1OM support required */
- CpuL1OM,
- /* Intel K1OM support required */
- CpuK1OM,
/* Intel IAMCU support required */
CpuIAMCU,
/* Xsave/xrstor New Instructions support required */
CpuMovbe,
/* CMPXCHG16B instruction support required. */
CpuCX16,
+ /* LAHF/SAHF instruction support required (in 64-bit mode). */
+ CpuLAHF_SAHF,
/* EPT Instructions required */
CpuEPT,
/* RDTSCP Instruction support required */
CpuTDX,
/* Intel AVX VNNI Instructions support required. */
CpuAVX_VNNI,
+ /* Intel AVX-512 FP16 Instructions support required. */
+ CpuAVX512_FP16,
+ /* PREFETCHI instruction required */
+ CpuPREFETCHI,
+ /* Intel AVX IFMA Instructions support required. */
+ CpuAVX_IFMA,
+ /* Intel AVX VNNI-INT8 Instructions support required. */
+ CpuAVX_VNNI_INT8,
+ /* Intel CMPccXADD instructions support required. */
+ CpuCMPCCXADD,
+ /* Intel WRMSRNS Instructions support required */
+ CpuWRMSRNS,
+ /* Intel MSRLIST Instructions support required. */
+ CpuMSRLIST,
+ /* Intel AVX NE CONVERT Instructions support required. */
+ CpuAVX_NE_CONVERT,
+ /* Intel RAO INT Instructions support required. */
+ CpuRAO_INT,
+ /* fred instruction required */
+ CpuFRED,
+ /* lkgs instruction required */
+ CpuLKGS,
/* mwaitx instruction required */
CpuMWAITX,
/* Clzero instruction required */
CpuAMX_INT8,
/* AMX-BF16 instructions required */
CpuAMX_BF16,
+ /* AMX-FP16 instructions required */
+ CpuAMX_FP16,
+ /* AMX-COMPLEX instructions required. */
+ CpuAMX_COMPLEX,
/* AMX-TILE instructions required */
CpuAMX_TILE,
/* GFNI instructions required */
CpuTLBSYNC,
/* SNP instructions required */
CpuSNP,
+ /* RMPQUERY instruction required */
+ CpuRMPQUERY,
+
+ /* NOTE: These last three items need to remain last and in this order. */
+
/* 64bit support required */
Cpu64,
/* Not supported in the 64bit mode */
unsigned int cpusse4a:1;
unsigned int cpulzcnt:1;
unsigned int cpupopcnt:1;
+ unsigned int cpumonitor:1;
unsigned int cpusse4_1:1;
unsigned int cpusse4_2:1;
unsigned int cpuavx:1;
unsigned int cpuavx512vl:1;
unsigned int cpuavx512dq:1;
unsigned int cpuavx512bw:1;
- unsigned int cpul1om:1;
- unsigned int cpuk1om:1;
unsigned int cpuiamcu:1;
unsigned int cpuxsave:1;
unsigned int cpuxsaveopt:1;
unsigned int cputbm:1;
unsigned int cpumovbe:1;
unsigned int cpucx16:1;
+ unsigned int cpulahf_sahf:1;
unsigned int cpuept:1;
unsigned int cpurdtscp:1;
unsigned int cpufsgsbase:1;
unsigned int cpuavx512_vp2intersect:1;
unsigned int cputdx:1;
unsigned int cpuavx_vnni:1;
+ unsigned int cpuavx512_fp16:1;
+ unsigned int cpuprefetchi:1;
+ unsigned int cpuavx_ifma:1;
+ unsigned int cpuavx_vnni_int8:1;
+ unsigned int cpucmpccxadd:1;
+ unsigned int cpuwrmsrns:1;
+ unsigned int cpumsrlist:1;
+ unsigned int cpuavx_ne_convert:1;
+ unsigned int cpurao_int:1;
+ unsigned int cpufred:1;
+ unsigned int cpulkgs:1;
unsigned int cpumwaitx:1;
unsigned int cpuclzero:1;
unsigned int cpuospke:1;
unsigned int cpushstk:1;
unsigned int cpuamx_int8:1;
unsigned int cpuamx_bf16:1;
+ unsigned int cpuamx_fp16:1;
+ unsigned int cpuamx_complex:1;
unsigned int cpuamx_tile:1;
unsigned int cpugfni:1;
unsigned int cpuvaes:1;
unsigned int cpuinvlpgb:1;
unsigned int cputlbsync:1;
unsigned int cpusnp:1;
+ unsigned int cpurmpquery:1;
+ /* NOTE: These last three fields need to remain last and in this order. */
unsigned int cpu64:1;
unsigned int cpuno64:1;
#ifdef CpuUnused
Jump,
/* FP insn memory format bit, sized by 0x4 */
FloatMF,
- /* src/dest swap for floats. */
- FloatR,
/* needs size prefix if in 32-bit mode */
#define SIZE16 1
/* needs size prefix if in 16-bit mode */
/* needs size prefix if in 64-bit mode */
#define SIZE64 3
Size,
- /* check register size. */
- CheckRegSize,
+ /* Check that operand sizes match. */
+ CheckOperandSize,
+ /* any memory size */
+#define ANY_SIZE 1
+ /* fake an extra reg operand for clr, imul and special register
+ processing for some instructions. */
+#define REG_KLUDGE 2
+ /* deprecated fp insn, gets a warning */
+#define UGH 3
+ /* An implicit xmm0 as the first operand */
+#define IMPLICIT_1ST_XMM0 4
+ /* The second operand must be a vector register, {x,y,z}mmN, where N is a multiple of 4.
+ It implicitly denotes the register group of {x,y,z}mmN - {x,y,z}mm(N + 3).
+ */
+#define IMPLICIT_QUAD_GROUP 5
+ /* Two source operands are swapped. */
+#define SWAP_SOURCES 6
+ /* Default mask isn't allowed. */
+#define NO_DEFAULT_MASK 7
+ /* Address prefix changes register operand */
+#define ADDR_PREFIX_OP_REG 8
+ /* Instrucion requires that destination must be distinct from source
+ registers. */
+#define DISTINCT_DEST 9
+ OperandConstraint,
/* instruction ignores operand size prefix and in Intel mode ignores
mnemonic size suffix check. */
#define IGNORESIZE 1
/* default insn size depends on mode */
#define DEFAULTSIZE 2
MnemonicSize,
- /* any memory size */
- Anysize,
/* b suffix on instruction illegal */
No_bSuf,
/* w suffix on instruction illegal */
No_sSuf,
/* q suffix on instruction illegal */
No_qSuf,
- /* long double suffix on instruction illegal */
- No_ldSuf,
/* instruction needs FWAIT */
FWait,
/* IsString provides for a quick test for string instructions, and
RegMem,
/* quick test if branch instruction is MPX supported */
BNDPrefixOk,
- /* quick test if NOTRACK prefix is supported */
- NoTrackPrefixOk,
- /* quick test for lockable instructions */
- IsLockable,
- /* fake an extra reg operand for clr, imul and special register
- processing for some instructions. */
- RegKludge,
- /* An implicit xmm0 as the first operand */
- Implicit1stXmm0,
- /* The HLE prefix is OK:
- 1. With a LOCK prefix.
- 2. With or without a LOCK prefix.
- 3. With a RELEASE (0xf3) prefix.
- */
-#define HLEPrefixNone 0
-#define HLEPrefixLock 1
-#define HLEPrefixAny 2
-#define HLEPrefixRelease 3
- HLEPrefixOk,
- /* An instruction on which a "rep" prefix is acceptable. */
- RepPrefixOk,
- /* Convert to DWORD */
- ToDword,
- /* Convert to QWORD */
- ToQword,
- /* Address prefix changes register operand */
- AddrPrefixOpReg,
+#define PrefixNone 0
+#define PrefixRep 1
+#define PrefixHLERelease 2 /* Okay with an XRELEASE (0xf3) prefix. */
+#define PrefixNoTrack 3
+ /* Prefixes implying "LOCK okay" must come after Lock. All others have
+ to come before. */
+#define PrefixLock 4
+#define PrefixHLELock 5 /* Okay with a LOCK prefix. */
+#define PrefixHLEAny 6 /* Okay with or without a LOCK prefix. */
+ PrefixOk,
/* opcode is a prefix */
IsPrefix,
/* instruction has extension in 8 bit imm */
ImmExt,
/* instruction don't need Rex64 prefix. */
NoRex64,
- /* deprecated fp insn, gets a warning */
- Ugh,
- /* Intel AVX Instructions support via {vex} prefix */
- PseudoVexPrefix,
/* insn has VEX prefix:
1: 128bit VEX prefix (or operand dependent).
2: 256bit VEX prefix.
Vex,
/* How to encode VEX.vvvv:
0: VEX.vvvv must be 1111b.
- 1: VEX.NDS. Register-only source is encoded in VEX.vvvv where
- the content of source registers will be preserved.
- VEX.DDS. The second register operand is encoded in VEX.vvvv
- where the content of first source register will be overwritten
- by the result.
- VEX.NDD2. The second destination register operand is encoded in
- VEX.vvvv for instructions with 2 destination register operands.
- For assembler, there are no difference between VEX.NDS, VEX.DDS
- and VEX.NDD2.
- 2. VEX.NDD. Register destination is encoded in VEX.vvvv for
- instructions with 1 destination register operand.
- 3. VEX.LWP. Register destination is encoded in VEX.vvvv and one
- of the operands can access a memory location.
+ 1: VEX.vvvv encodes one of the register operands.
*/
-#define VEXXDS 1
-#define VEXNDD 2
-#define VEXLWP 3
VexVVVV,
/* How the VEX.W bit is used:
0: Set by the REX.W bit.
#define VEXW1 2
#define VEXWIG 3
VexW,
- /* Regular opcode prefix:
+ /* Opcode prefix (values chosen to be usable directly in
+ VEX/XOP/EVEX pp fields):
0: None
1: Add 0x66 opcode prefix.
- 2: Add 0xf2 opcode prefix.
- 3: Add 0xf3 opcode prefix.
+ 2: Add 0xf3 opcode prefix.
+ 3: Add 0xf2 opcode prefix.
*/
#define PREFIX_NONE 0
#define PREFIX_0X66 1
-#define PREFIX_0XF2 2
-#define PREFIX_0XF3 3
- /* VEX opcode prefix:
- 0: VEX 0x0F opcode prefix.
- 1: VEX 0x0F38 opcode prefix.
- 2: VEX 0x0F3A opcode prefix
- 3: XOP 0x08 opcode prefix.
- 4: XOP 0x09 opcode prefix
- 5: XOP 0x0A opcode prefix.
- */
-#define VEX0F 0
-#define VEX0F38 1
-#define VEX0F3A 2
-#define XOP08 3
-#define XOP09 4
-#define XOP0A 5
+#define PREFIX_0XF3 2
+#define PREFIX_0XF2 3
OpcodePrefix,
- /* number of VEX source operands:
- 0: <= 2 source operands.
- 1: 2 XOP source operands.
- 2: 3 source operands.
- */
-#define XOP2SOURCES 1
-#define VEX3SOURCES 2
- VexSources,
/* Instruction with a mandatory SIB byte:
1: 128bit vector register.
2: 256bit vector register.
/* SSE to AVX support required */
SSE2AVX,
- /* No AVX equivalent */
- NoAVX,
/* insn has EVEX prefix:
1: 512bit EVEX prefix.
3: 256bit EVEX prefix.
4: Length-ignored (LIG) EVEX prefix.
5: Length determined from actual operands.
+ 6: L'L = 3 (reserved, .insn only)
*/
#define EVEX512 1
#define EVEX128 2
#define EVEX256 3
#define EVEXLIG 4
#define EVEXDYN 5
+#define EVEX_L3 6
EVex,
- /* AVX512 masking support:
- 1: Zeroing or merging masking depending on operands.
- 2: Merging-masking.
- 3: Both zeroing and merging masking.
- */
-#define DYNAMIC_MASKING 1
-#define MERGING_MASKING 2
-#define BOTH_MASKING 3
+ /* AVX512 masking support */
Masking,
/* AVX512 broadcast support. The number of bytes to broadcast is
#define DISP8_SHIFT_VL 7
Disp8MemShift,
- /* Default mask isn't allowed. */
- NoDefMask,
-
- /* The second operand must be a vector register, {x,y,z}mmN, where N is a multiple of 4.
- It implicitly denotes the register group of {x,y,z}mmN - {x,y,z}mm(N + 3).
- */
- ImplicitQuadGroup,
-
- /* Two source operands are swapped. */
- SwapSources,
-
/* Support encoding optimization. */
Optimize,
unsigned int modrm:1;
unsigned int jump:3;
unsigned int floatmf:1;
- unsigned int floatr:1;
unsigned int size:2;
- unsigned int checkregsize:1;
+ unsigned int checkoperandsize:1;
+ unsigned int operandconstraint:4;
unsigned int mnemonicsize:2;
- unsigned int anysize:1;
unsigned int no_bsuf:1;
unsigned int no_wsuf:1;
unsigned int no_lsuf:1;
unsigned int no_ssuf:1;
unsigned int no_qsuf:1;
- unsigned int no_ldsuf:1;
unsigned int fwait:1;
unsigned int isstring:2;
unsigned int regmem:1;
unsigned int bndprefixok:1;
- unsigned int notrackprefixok:1;
- unsigned int islockable:1;
- unsigned int regkludge:1;
- unsigned int implicit1stxmm0:1;
- unsigned int hleprefixok:2;
- unsigned int repprefixok:1;
- unsigned int todword:1;
- unsigned int toqword:1;
- unsigned int addrprefixopreg:1;
+ unsigned int prefixok:3;
unsigned int isprefix:1;
unsigned int immext:1;
unsigned int norex64:1;
- unsigned int ugh:1;
- unsigned int pseudovexprefix:1;
unsigned int vex:2;
- unsigned int vexvvvv:2;
+ unsigned int vexvvvv:1;
unsigned int vexw:2;
- unsigned int opcodeprefix:3;
- unsigned int vexsources:2;
+ unsigned int opcodeprefix:2;
unsigned int sib:3;
unsigned int sse2avx:1;
- unsigned int noavx:1;
unsigned int evex:3;
- unsigned int masking:2;
+ unsigned int masking:1;
unsigned int broadcast:3;
unsigned int staticrounding:1;
unsigned int sae:1;
unsigned int disp8memshift:3;
- unsigned int nodefmask:1;
- unsigned int implicitquadgroup:1;
- unsigned int swapsources:1;
unsigned int optimize:1;
unsigned int attmnemonic:1;
unsigned int attsyntax:1;
Disp8,
/* 16 bit displacement */
Disp16,
- /* 32 bit displacement */
+ /* 32 bit displacement (64-bit: sign-extended) */
Disp32,
- /* 32 bit signed displacement */
- Disp32S,
/* 64 bit displacement */
Disp64,
/* Register which can be used for base or index in memory operand. */
unsigned int disp8:1;
unsigned int disp16:1;
unsigned int disp32:1;
- unsigned int disp32s:1;
unsigned int disp64:1;
unsigned int baseindex:1;
unsigned int byte:1;
typedef struct insn_template
{
/* instruction name sans width suffix ("mov" for movl insns) */
- char *name;
+ unsigned int mnem_off;
+
+ /* Bitfield arrangement is such that individual fields can be easily
+ extracted (in native builds at least) - either by at most a masking
+ operation (base_opcode, operands), or by just a (signed) right shift
+ (extension_opcode). Please try to maintain this property. */
/* base_opcode is the fundamental opcode byte without optional
prefix(es). */
- unsigned int base_opcode;
+ unsigned int base_opcode:16;
#define Opcode_D 0x2 /* Direction bit:
set if Reg --> Regmem;
unset if Regmem --> Reg. */
-#define Opcode_FloatR 0x8 /* Bit to swap src/dest for float insns. */
-#define Opcode_FloatD 0x400 /* Direction bit for float insns. */
-#define Opcode_SIMD_FloatD 0x1 /* Direction bit for SIMD fp insns. */
+#define Opcode_FloatR 0x8 /* ModR/M bit to swap src/dest for float insns. */
+#define Opcode_FloatD 0x4 /* Direction bit for float insns. */
+#define Opcode_ExtD 0x1 /* Direction bit for extended opcode space insns. */
#define Opcode_SIMD_IntD 0x10 /* Direction bit for SIMD int insns. */
+/* The next value is arbitrary, as long as it's non-zero and distinct
+ from all other values above. */
+#define Opcode_VexW 0xf /* Operand order controlled by VEX.W. */
+
+ /* how many operands */
+ unsigned int operands:3;
+
+ /* opcode space */
+ unsigned int opcode_space:4;
+ /* Opcode encoding space (values chosen to be usable directly in
+ VEX/XOP mmmmm and EVEX mm fields):
+ 0: Base opcode space.
+ 1: 0F opcode prefix / space.
+ 2: 0F38 opcode prefix / space.
+ 3: 0F3A opcode prefix / space.
+ 5: EVEXMAP5 opcode prefix / space.
+ 6: EVEXMAP6 opcode prefix / space.
+ 8: XOP 08 opcode space.
+ 9: XOP 09 opcode space.
+ A: XOP 0A opcode space.
+ */
+#define SPACE_BASE 0
+#define SPACE_0F 1
+#define SPACE_0F38 2
+#define SPACE_0F3A 3
+#define SPACE_EVEXMAP5 5
+#define SPACE_EVEXMAP6 6
+#define SPACE_XOP08 8
+#define SPACE_XOP09 9
+#define SPACE_XOP0A 0xA
+
+/* (Fake) base opcode value for pseudo prefixes. */
+#define PSEUDO_PREFIX 0
+
+ /* extension_opcode is the 3 bit extension for group <n> insns.
+ This field is also used to store the 8-bit opcode suffix for the
+ AMD 3DNow! instructions.
+ If this template has no extension opcode (the usual case) use None
+ Instructions */
+ signed int extension_opcode:9;
+#define None (-1) /* If no extension_opcode is possible. */
/* Pseudo prefixes. */
#define Prefix_Disp8 0 /* {disp8} */
#define Prefix_REX 8 /* {rex} */
#define Prefix_NoOptimize 9 /* {nooptimize} */
- /* extension_opcode is the 3 bit extension for group <n> insns.
- This field is also used to store the 8-bit opcode suffix for the
- AMD 3DNow! instructions.
- If this template has no extension opcode (the usual case) use None
- Instructions */
- unsigned short extension_opcode;
-#define None 0xffff /* If no extension_opcode is possible. */
-
- /* Opcode length. */
- unsigned char opcode_length;
-
- /* how many operands */
- unsigned char operands;
-
- /* cpu feature flags */
- i386_cpu_flags cpu_flags;
-
/* the bits in opcode_modifier are used to generate the final opcode from
the base_opcode. These bits also are used to detect alternate forms of
the same instruction */
i386_opcode_modifier opcode_modifier;
+ /* cpu feature flags */
+ i386_cpu_flags cpu_flags;
+
/* operand_types[i] describes the type of operand i. This is made
by OR'ing together all of the possible type masks. (e.g.
'operand_types[i] = Reg|Imm' specifies that operand i can be
}
insn_template;
-extern const insn_template i386_optab[];
-
/* these are for register name --> number & type hash lookup */
typedef struct
{
- const char *reg_name;
+ char reg_name[8];
i386_operand_type reg_type;
unsigned char reg_flags;
#define RegRex 0x1 /* Extended register. */
#define Dw2Inval (-1)
}
reg_entry;
-
-/* Entries in i386_regtab. */
-#define REGNAM_AL 1
-#define REGNAM_AX 25
-#define REGNAM_EAX 41
-
-extern const reg_entry i386_regtab[];
-extern const unsigned int i386_regtab_size;
-
-typedef struct
-{
- char *seg_name;
- unsigned int seg_prefix;
-}
-seg_entry;
-
-extern const seg_entry cs;
-extern const seg_entry ds;
-extern const seg_entry ss;
-extern const seg_entry es;
-extern const seg_entry fs;
-extern const seg_entry gs;