X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-opc.h;h=55726c1a7a712bc4d446d04e202373b76e57d70d;hb=e822f2cda9bc484adb5f8860050640a5c6f1ced9;hp=83211dda80519fecb451358e603cfd56638ec23f;hpb=c3fe08facbc8d8e8e0bdff27a01c0c77a03a5047;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index 83211dda80..55726c1a7a 100644 --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -1,18 +1,17 @@ /* Declarations for Intel 80386 opcode table - Copyright 2007 - Free Software Foundation, Inc. + Copyright (C) 2007-2020 Free Software Foundation, Inc. - This file is part of GAS, the GNU Assembler. + This file is part of the GNU opcodes library. - GAS is free software; you can redistribute it and/or modify + This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. - GAS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free @@ -20,15 +19,847 @@ 02110-1301, USA. */ #include "opcode/i386.h" +#ifdef HAVE_LIMITS_H +#include +#endif -typedef struct template +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* Position of cpu flags bitfiled. */ + +enum +{ + /* i186 or better required */ + Cpu186 = 0, + /* i286 or better required */ + Cpu286, + /* i386 or better required */ + Cpu386, + /* i486 or better required */ + Cpu486, + /* i585 or better required */ + Cpu586, + /* i686 or better required */ + Cpu686, + /* CMOV Instruction support required */ + CpuCMOV, + /* FXSR Instruction support required */ + CpuFXSR, + /* CLFLUSH Instruction support required */ + CpuClflush, + /* NOP Instruction support required */ + CpuNop, + /* SYSCALL Instructions support required */ + CpuSYSCALL, + /* Floating point support required */ + Cpu8087, + /* i287 support required */ + Cpu287, + /* i387 support required */ + Cpu387, + /* i686 and floating point support required */ + Cpu687, + /* SSE3 and floating point support required */ + CpuFISTTP, + /* MMX support required */ + CpuMMX, + /* SSE support required */ + CpuSSE, + /* SSE2 support required */ + CpuSSE2, + /* 3dnow! support required */ + Cpu3dnow, + /* 3dnow! Extensions support required */ + Cpu3dnowA, + /* SSE3 support required */ + CpuSSE3, + /* VIA PadLock required */ + CpuPadLock, + /* AMD Secure Virtual Machine Ext-s required */ + CpuSVME, + /* VMX Instructions required */ + CpuVMX, + /* SMX Instructions required */ + CpuSMX, + /* SSSE3 support required */ + CpuSSSE3, + /* SSE4a support required */ + CpuSSE4a, + /* LZCNT support required */ + CpuLZCNT, + /* POPCNT support required */ + CpuPOPCNT, + /* SSE4.1 support required */ + CpuSSE4_1, + /* SSE4.2 support required */ + CpuSSE4_2, + /* AVX support required */ + CpuAVX, + /* AVX2 support required */ + CpuAVX2, + /* Intel AVX-512 Foundation Instructions support required */ + CpuAVX512F, + /* Intel AVX-512 Conflict Detection Instructions support required */ + CpuAVX512CD, + /* Intel AVX-512 Exponential and Reciprocal Instructions support + required */ + CpuAVX512ER, + /* Intel AVX-512 Prefetch Instructions support required */ + CpuAVX512PF, + /* Intel AVX-512 VL Instructions support required. */ + CpuAVX512VL, + /* Intel AVX-512 DQ Instructions 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 */ + CpuXsave, + /* Xsaveopt New Instructions support required */ + CpuXsaveopt, + /* AES support required */ + CpuAES, + /* PCLMUL support required */ + CpuPCLMUL, + /* FMA support required */ + CpuFMA, + /* FMA4 support required */ + CpuFMA4, + /* XOP support required */ + CpuXOP, + /* LWP support required */ + CpuLWP, + /* BMI support required */ + CpuBMI, + /* TBM support required */ + CpuTBM, + /* MOVBE Instruction support required */ + CpuMovbe, + /* CMPXCHG16B instruction support required. */ + CpuCX16, + /* EPT Instructions required */ + CpuEPT, + /* RDTSCP Instruction support required */ + CpuRdtscp, + /* FSGSBASE Instructions required */ + CpuFSGSBase, + /* RDRND Instructions required */ + CpuRdRnd, + /* F16C Instructions required */ + CpuF16C, + /* Intel BMI2 support required */ + CpuBMI2, + /* HLE support required */ + CpuHLE, + /* RTM support required */ + CpuRTM, + /* INVPCID Instructions required */ + CpuINVPCID, + /* VMFUNC Instruction required */ + CpuVMFUNC, + /* Intel MPX Instructions required */ + CpuMPX, + /* 64bit support available, used by -march= in assembler. */ + CpuLM, + /* RDRSEED instruction required. */ + CpuRDSEED, + /* Multi-presisionn add-carry instructions are required. */ + CpuADX, + /* Supports prefetchw and prefetch instructions. */ + CpuPRFCHW, + /* SMAP instructions required. */ + CpuSMAP, + /* SHA instructions required. */ + CpuSHA, + /* CLFLUSHOPT instruction required */ + CpuClflushOpt, + /* XSAVES/XRSTORS instruction required */ + CpuXSAVES, + /* XSAVEC instruction required */ + CpuXSAVEC, + /* PREFETCHWT1 instruction required */ + CpuPREFETCHWT1, + /* SE1 instruction required */ + CpuSE1, + /* CLWB instruction required */ + CpuCLWB, + /* Intel AVX-512 IFMA Instructions support required. */ + CpuAVX512IFMA, + /* Intel AVX-512 VBMI Instructions support required. */ + CpuAVX512VBMI, + /* Intel AVX-512 4FMAPS Instructions support required. */ + CpuAVX512_4FMAPS, + /* Intel AVX-512 4VNNIW Instructions support required. */ + CpuAVX512_4VNNIW, + /* Intel AVX-512 VPOPCNTDQ Instructions support required. */ + CpuAVX512_VPOPCNTDQ, + /* Intel AVX-512 VBMI2 Instructions support required. */ + CpuAVX512_VBMI2, + /* Intel AVX-512 VNNI Instructions support required. */ + CpuAVX512_VNNI, + /* Intel AVX-512 BITALG Instructions support required. */ + CpuAVX512_BITALG, + /* Intel AVX-512 BF16 Instructions support required. */ + CpuAVX512_BF16, + /* Intel AVX-512 VP2INTERSECT Instructions support required. */ + CpuAVX512_VP2INTERSECT, + /* mwaitx instruction required */ + CpuMWAITX, + /* Clzero instruction required */ + CpuCLZERO, + /* OSPKE instruction required */ + CpuOSPKE, + /* RDPID instruction required */ + CpuRDPID, + /* PTWRITE instruction required */ + CpuPTWRITE, + /* CET instructions support required */ + CpuIBT, + CpuSHSTK, + /* GFNI instructions required */ + CpuGFNI, + /* VAES instructions required */ + CpuVAES, + /* VPCLMULQDQ instructions required */ + CpuVPCLMULQDQ, + /* WBNOINVD instructions required */ + CpuWBNOINVD, + /* PCONFIG instructions required */ + CpuPCONFIG, + /* WAITPKG instructions required */ + CpuWAITPKG, + /* CLDEMOTE instruction required */ + CpuCLDEMOTE, + /* MOVDIRI instruction support required */ + CpuMOVDIRI, + /* MOVDIRR64B instruction required */ + CpuMOVDIR64B, + /* ENQCMD instruction required */ + CpuENQCMD, + /* SERIALIZE instruction required */ + CpuSERIALIZE, + /* RDPRU instruction required */ + CpuRDPRU, + /* MCOMMIT instruction required */ + CpuMCOMMIT, + /* SEV-ES instruction(s) required */ + CpuSEV_ES, + /* TSXLDTRK instruction required */ + CpuTSXLDTRK, + /* 64bit support required */ + Cpu64, + /* Not supported in the 64bit mode */ + CpuNo64, + /* The last bitfield in i386_cpu_flags. */ + CpuMax = CpuNo64 +}; + +#define CpuNumOfUints \ + (CpuMax / sizeof (unsigned int) / CHAR_BIT + 1) +#define CpuNumOfBits \ + (CpuNumOfUints * sizeof (unsigned int) * CHAR_BIT) + +/* If you get a compiler error for zero width of the unused field, + comment it out. */ +#define CpuUnused (CpuMax + 1) + +/* We can check if an instruction is available with array instead + of bitfield. */ +typedef union i386_cpu_flags +{ + struct + { + unsigned int cpui186:1; + unsigned int cpui286:1; + unsigned int cpui386:1; + unsigned int cpui486:1; + unsigned int cpui586:1; + unsigned int cpui686:1; + unsigned int cpucmov:1; + unsigned int cpufxsr:1; + unsigned int cpuclflush:1; + unsigned int cpunop:1; + unsigned int cpusyscall:1; + unsigned int cpu8087:1; + unsigned int cpu287:1; + unsigned int cpu387:1; + unsigned int cpu687:1; + unsigned int cpufisttp:1; + unsigned int cpummx:1; + unsigned int cpusse:1; + unsigned int cpusse2:1; + unsigned int cpua3dnow:1; + unsigned int cpua3dnowa:1; + unsigned int cpusse3:1; + unsigned int cpupadlock:1; + unsigned int cpusvme:1; + unsigned int cpuvmx:1; + unsigned int cpusmx:1; + unsigned int cpussse3:1; + unsigned int cpusse4a:1; + unsigned int cpulzcnt:1; + unsigned int cpupopcnt:1; + unsigned int cpusse4_1:1; + unsigned int cpusse4_2:1; + unsigned int cpuavx:1; + unsigned int cpuavx2:1; + unsigned int cpuavx512f:1; + unsigned int cpuavx512cd:1; + unsigned int cpuavx512er:1; + unsigned int cpuavx512pf: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 cpuaes:1; + unsigned int cpupclmul:1; + unsigned int cpufma:1; + unsigned int cpufma4:1; + unsigned int cpuxop:1; + unsigned int cpulwp:1; + unsigned int cpubmi:1; + unsigned int cputbm:1; + unsigned int cpumovbe:1; + unsigned int cpucx16:1; + unsigned int cpuept:1; + unsigned int cpurdtscp:1; + unsigned int cpufsgsbase:1; + unsigned int cpurdrnd:1; + unsigned int cpuf16c:1; + unsigned int cpubmi2:1; + unsigned int cpuhle:1; + unsigned int cpurtm:1; + unsigned int cpuinvpcid:1; + unsigned int cpuvmfunc:1; + unsigned int cpumpx:1; + unsigned int cpulm:1; + unsigned int cpurdseed:1; + unsigned int cpuadx:1; + unsigned int cpuprfchw:1; + unsigned int cpusmap:1; + unsigned int cpusha:1; + unsigned int cpuclflushopt:1; + unsigned int cpuxsaves:1; + unsigned int cpuxsavec:1; + unsigned int cpuprefetchwt1:1; + unsigned int cpuse1:1; + unsigned int cpuclwb:1; + unsigned int cpuavx512ifma:1; + unsigned int cpuavx512vbmi:1; + unsigned int cpuavx512_4fmaps:1; + unsigned int cpuavx512_4vnniw:1; + unsigned int cpuavx512_vpopcntdq:1; + unsigned int cpuavx512_vbmi2:1; + unsigned int cpuavx512_vnni:1; + unsigned int cpuavx512_bitalg:1; + unsigned int cpuavx512_bf16:1; + unsigned int cpuavx512_vp2intersect:1; + unsigned int cpumwaitx:1; + unsigned int cpuclzero:1; + unsigned int cpuospke:1; + unsigned int cpurdpid:1; + unsigned int cpuptwrite:1; + unsigned int cpuibt:1; + unsigned int cpushstk:1; + unsigned int cpugfni:1; + unsigned int cpuvaes:1; + unsigned int cpuvpclmulqdq:1; + unsigned int cpuwbnoinvd:1; + unsigned int cpupconfig:1; + unsigned int cpuwaitpkg:1; + unsigned int cpucldemote:1; + unsigned int cpumovdiri:1; + unsigned int cpumovdir64b:1; + unsigned int cpuenqcmd:1; + unsigned int cpuserialize:1; + unsigned int cpurdpru:1; + unsigned int cpumcommit:1; + unsigned int cpusev_es:1; + unsigned int cputsxldtrk:1; + unsigned int cpu64:1; + unsigned int cpuno64:1; +#ifdef CpuUnused + unsigned int unused:(CpuNumOfBits - CpuUnused); +#endif + } bitfield; + unsigned int array[CpuNumOfUints]; +} i386_cpu_flags; + +/* Position of opcode_modifier bits. */ + +enum +{ + /* has direction bit. */ + D = 0, + /* set if operands can be both bytes and words/dwords/qwords, encoded the + canonical way; the base_opcode field should hold the encoding for byte + operands */ + W, + /* load form instruction. Must be placed before store form. */ + Load, + /* insn has a modrm byte. */ + Modrm, + /* special case for jump insns; value has to be 1 */ +#define JUMP 1 + /* call and jump */ +#define JUMP_DWORD 2 + /* loop and jecxz */ +#define JUMP_BYTE 3 + /* special case for intersegment leaps/calls */ +#define JUMP_INTERSEGMENT 4 + /* absolute address for jump */ +#define JUMP_ABSOLUTE 5 + 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 */ +#define SIZE32 2 + /* needs size prefix if in 64-bit mode */ +#define SIZE64 3 + Size, + /* check register size. */ + CheckRegSize, + /* 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_wSuf, + /* l suffix on instruction illegal */ + No_lSuf, + /* s 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 + its actual value also indicates which of the operands (if any) + requires use of the %es segment. */ +#define IS_STRING_ES_OP0 2 +#define IS_STRING_ES_OP1 3 + IsString, + /* RegMem is for instructions with a modrm byte where the register + destination operand should be encoded in the mod and regmem fields. + Normally, it will be encoded in the reg field. We add a RegMem + flag to indicate that it should be encoded in the regmem field. */ + 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, + /* 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, + /* insn has VEX prefix: + 1: 128bit VEX prefix (or operand dependent). + 2: 256bit VEX prefix. + 3: Scalar VEX prefix. + */ +#define VEX128 1 +#define VEX256 2 +#define VEXScalar 3 + 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. + */ +#define VEXXDS 1 +#define VEXNDD 2 +#define VEXLWP 3 + VexVVVV, + /* How the VEX.W bit is used: + 0: Set by the REX.W bit. + 1: VEX.W0. Should always be 0. + 2: VEX.W1. Should always be 1. + 3: VEX.WIG. The VEX.W bit is ignored. + */ +#define VEXW0 1 +#define VEXW1 2 +#define VEXWIG 3 + VexW, + /* 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 + VexOpcode, + /* 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 vector SIB byte: + 1: 128bit vector register. + 2: 256bit vector register. + 3: 512bit vector register. + */ +#define VecSIB128 1 +#define VecSIB256 2 +#define VecSIB512 3 + VecSIB, + /* SSE to AVX support required */ + SSE2AVX, + /* No AVX equivalent */ + NoAVX, + + /* insn has EVEX prefix: + 1: 512bit EVEX prefix. + 2: 128bit EVEX prefix. + 3: 256bit EVEX prefix. + 4: Length-ignored (LIG) EVEX prefix. + 5: Length determined from actual operands. + */ +#define EVEX512 1 +#define EVEX128 2 +#define EVEX256 3 +#define EVEXLIG 4 +#define EVEXDYN 5 + 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 + Masking, + + /* AVX512 broadcast support. The number of bytes to broadcast is + 1 << (Broadcast - 1): + 1: Byte broadcast. + 2: Word broadcast. + 3: Dword broadcast. + 4: Qword broadcast. + */ +#define BYTE_BROADCAST 1 +#define WORD_BROADCAST 2 +#define DWORD_BROADCAST 3 +#define QWORD_BROADCAST 4 + Broadcast, + + /* Static rounding control is supported. */ + StaticRounding, + + /* Supress All Exceptions is supported. */ + SAE, + + /* Compressed Disp8*N attribute. */ +#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, + + /* Support encoding optimization. */ + Optimize, + + /* AT&T mnemonic. */ + ATTMnemonic, + /* AT&T syntax. */ + ATTSyntax, + /* Intel syntax. */ + IntelSyntax, + /* ISA64: Don't change the order without other code adjustments. + 0: Common to AMD64 and Intel64. + 1: AMD64. + 2: Intel64. + 3: Only in Intel64. + */ +#define AMD64 1 +#define INTEL64 2 +#define INTEL64ONLY 3 + ISA64, + /* The last bitfield in i386_opcode_modifier. */ + Opcode_Modifier_Num +}; + +typedef struct i386_opcode_modifier +{ + unsigned int d:1; + unsigned int w:1; + unsigned int load:1; + 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 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 isprefix:1; + unsigned int immext:1; + unsigned int norex64:1; + unsigned int ugh:1; + unsigned int vex:2; + unsigned int vexvvvv:2; + unsigned int vexw:2; + unsigned int vexopcode:3; + unsigned int vexsources:2; + unsigned int vecsib:2; + unsigned int sse2avx:1; + unsigned int noavx:1; + unsigned int evex:3; + unsigned int masking:2; + 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 optimize:1; + unsigned int attmnemonic:1; + unsigned int attsyntax:1; + unsigned int intelsyntax:1; + unsigned int isa64:2; +} i386_opcode_modifier; + +/* Operand classes. */ + +#define CLASS_WIDTH 4 +enum operand_class +{ + ClassNone, + Reg, /* GPRs and FP regs, distinguished by operand size */ + SReg, /* Segment register */ + RegCR, /* Control register */ + RegDR, /* Debug register */ + RegTR, /* Test register */ + RegMMX, /* MMX register */ + RegSIMD, /* XMM/YMM/ZMM registers, distinguished by operand size */ + RegMask, /* Vector Mask register */ + RegBND, /* Bound register */ +}; + +/* Special operand instances. */ + +#define INSTANCE_WIDTH 3 +enum operand_instance +{ + InstanceNone, + Accum, /* Accumulator %al/%ax/%eax/%rax/%st(0)/%xmm0 */ + RegC, /* %cl / %cx / %ecx / %rcx, e.g. register to hold shift count */ + RegD, /* %dl / %dx / %edx / %rdx, e.g. register to hold I/O port addr */ + RegB, /* %bl / %bx / %ebx / %rbx */ +}; + +/* Position of operand_type bits. */ + +enum +{ + /* Class and Instance */ + ClassInstance = CLASS_WIDTH + INSTANCE_WIDTH - 1, + /* 1 bit immediate */ + Imm1, + /* 8 bit immediate */ + Imm8, + /* 8 bit immediate sign extended */ + Imm8S, + /* 16 bit immediate */ + Imm16, + /* 32 bit immediate */ + Imm32, + /* 32 bit immediate sign extended */ + Imm32S, + /* 64 bit immediate */ + Imm64, + /* 8bit/16bit/32bit displacements are used in different ways, + depending on the instruction. For jumps, they specify the + size of the PC relative displacement, for instructions with + memory operand, they specify the size of the offset relative + to the base register, and for instructions with memory offset + such as `mov 1234,%al' they specify the size of the offset + relative to the segment base. */ + /* 8 bit displacement */ + Disp8, + /* 16 bit displacement */ + Disp16, + /* 32 bit displacement */ + Disp32, + /* 32 bit signed displacement */ + Disp32S, + /* 64 bit displacement */ + Disp64, + /* Register which can be used for base or index in memory operand. */ + BaseIndex, + /* BYTE size. */ + Byte, + /* WORD size. 2 byte */ + Word, + /* DWORD size. 4 byte */ + Dword, + /* FWORD size. 6 byte */ + Fword, + /* QWORD size. 8 byte */ + Qword, + /* TBYTE size. 10 byte */ + Tbyte, + /* XMMWORD size. */ + Xmmword, + /* YMMWORD size. */ + Ymmword, + /* ZMMWORD size. */ + Zmmword, + /* Unspecified memory size. */ + Unspecified, + + /* The number of bits in i386_operand_type. */ + OTNum +}; + +#define OTNumOfUints \ + ((OTNum - 1) / sizeof (unsigned int) / CHAR_BIT + 1) +#define OTNumOfBits \ + (OTNumOfUints * sizeof (unsigned int) * CHAR_BIT) + +/* If you get a compiler error for zero width of the unused field, + comment it out. */ +#define OTUnused OTNum + +typedef union i386_operand_type +{ + struct + { + unsigned int class:CLASS_WIDTH; + unsigned int instance:INSTANCE_WIDTH; + unsigned int imm1:1; + unsigned int imm8:1; + unsigned int imm8s:1; + unsigned int imm16:1; + unsigned int imm32:1; + unsigned int imm32s:1; + unsigned int imm64:1; + 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; + unsigned int word:1; + unsigned int dword:1; + unsigned int fword:1; + unsigned int qword:1; + unsigned int tbyte:1; + unsigned int xmmword:1; + unsigned int ymmword:1; + unsigned int zmmword:1; + unsigned int unspecified:1; +#ifdef OTUnused + unsigned int unused:(OTNumOfBits - OTUnused); +#endif + } bitfield; + unsigned int array[OTNumOfUints]; +} i386_operand_type; + +typedef struct insn_template { /* instruction name sans width suffix ("mov" for movl insns) */ char *name; - /* how many operands */ - unsigned int operands; - /* base_opcode is the fundamental opcode byte without optional prefix(es). */ unsigned int base_opcode; @@ -37,174 +868,58 @@ typedef struct template 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_SIMD_IntD 0x10 /* Direction bit for SIMD int insns. */ /* extension_opcode is the 3 bit extension for group 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 */ - unsigned int extension_opcode; + 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 */ - unsigned int cpu_flags; -#define Cpu186 0x1 /* i186 or better required */ -#define Cpu286 0x2 /* i286 or better required */ -#define Cpu386 0x4 /* i386 or better required */ -#define Cpu486 0x8 /* i486 or better required */ -#define Cpu586 0x10 /* i585 or better required */ -#define Cpu686 0x20 /* i686 or better required */ -#define CpuP4 0x40 /* Pentium4 or better required */ -#define CpuK6 0x80 /* AMD K6 or better required*/ -#define CpuSledgehammer 0x100 /* Sledgehammer or better required */ -#define CpuMMX 0x200 /* MMX support required */ -#define CpuMMX2 0x400 /* extended MMX support (with SSE or 3DNow!Ext) required */ -#define CpuSSE 0x800 /* Streaming SIMD extensions required */ -#define CpuSSE2 0x1000 /* Streaming SIMD extensions 2 required */ -#define Cpu3dnow 0x2000 /* 3dnow! support required */ -#define Cpu3dnowA 0x4000 /* 3dnow!Extensions support required */ -#define CpuSSE3 0x8000 /* Streaming SIMD extensions 3 required */ -#define CpuPadLock 0x10000 /* VIA PadLock required */ -#define CpuSVME 0x20000 /* AMD Secure Virtual Machine Ext-s required */ -#define CpuVMX 0x40000 /* VMX Instructions required */ -#define CpuSSSE3 0x80000 /* Supplemental Streaming SIMD extensions 3 required */ -#define CpuSSE4a 0x100000 /* SSE4a New Instuctions required */ -#define CpuABM 0x200000 /* ABM New Instructions required */ - - /* These flags are set by gas depending on the flag_code. */ -#define Cpu64 0x4000000 /* 64bit support required */ -#define CpuNo64 0x8000000 /* Not supported in the 64bit mode */ - - /* The default value for unknown CPUs - enable all features to avoid problems. */ -#define CpuUnknownFlags (Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \ - |CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuVMX \ - |Cpu3dnow|Cpu3dnowA|CpuK6|CpuPadLock|CpuSVME|CpuSSSE3|CpuABM|CpuSSE4a) + 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 */ - unsigned int opcode_modifier; - - /* opcode_modifier bits: */ -#define D 0x1 /* has direction bit. */ -#define W 0x2 /* set if operands can be words or dwords - encoded the canonical way */ -#define Modrm 0x4 /* insn has a modrm byte. */ -#define ShortForm 0x10 /* register is in low 3 bits of opcode */ -#define Jump 0x40 /* special case for jump insns. */ -#define JumpDword 0x80 /* call and jump */ -#define JumpByte 0x100 /* loop and jecxz */ -#define JumpInterSegment 0x200 /* special case for intersegment leaps/calls */ -#define FloatMF 0x400 /* FP insn memory format bit, sized by 0x4 */ -#define FloatR 0x800 /* src/dest swap for floats. */ -#define FloatD 0x1000 /* has float insn direction bit. */ -#define Size16 0x2000 /* needs size prefix if in 32-bit mode */ -#define Size32 0x4000 /* needs size prefix if in 16-bit mode */ -#define Size64 0x8000 /* needs size prefix if in 64-bit mode */ -#define IgnoreSize 0x10000 /* instruction ignores operand size prefix */ -#define DefaultSize 0x20000 /* default insn size depends on mode */ -#define No_bSuf 0x40000 /* b suffix on instruction illegal */ -#define No_wSuf 0x80000 /* w suffix on instruction illegal */ -#define No_lSuf 0x100000 /* l suffix on instruction illegal */ -#define No_sSuf 0x200000 /* s suffix on instruction illegal */ -#define No_qSuf 0x400000 /* q suffix on instruction illegal */ -#define No_xSuf 0x800000 /* x suffix on instruction illegal */ -#define FWait 0x1000000 /* instruction needs FWAIT */ -#define IsString 0x2000000 /* quick test for string instructions */ -#define regKludge 0x4000000 /* fake an extra reg operand for clr, imul */ -#define IsPrefix 0x8000000 /* opcode is a prefix */ -#define ImmExt 0x10000000 /* instruction has extension in 8 bit imm */ -#define NoRex64 0x20000000 /* instruction don't need Rex64 prefix. */ -#define Rex64 0x40000000 /* instruction require Rex64 prefix. */ -#define Ugh 0x80000000 /* deprecated fp insn, gets a warning */ + i386_opcode_modifier opcode_modifier; /* 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 either a register or an immediate operand. */ - unsigned int operand_types[MAX_OPERANDS]; - - /* operand_types[i] bits */ - /* register */ -#define Reg8 0x1 /* 8 bit reg */ -#define Reg16 0x2 /* 16 bit reg */ -#define Reg32 0x4 /* 32 bit reg */ -#define Reg64 0x8 /* 64 bit reg */ - /* immediate */ -#define Imm8 0x10 /* 8 bit immediate */ -#define Imm8S 0x20 /* 8 bit immediate sign extended */ -#define Imm16 0x40 /* 16 bit immediate */ -#define Imm32 0x80 /* 32 bit immediate */ -#define Imm32S 0x100 /* 32 bit immediate sign extended */ -#define Imm64 0x200 /* 64 bit immediate */ -#define Imm1 0x400 /* 1 bit immediate */ - /* memory */ -#define BaseIndex 0x800 - /* Disp8,16,32 are used in different ways, depending on the - instruction. For jumps, they specify the size of the PC relative - displacement, for baseindex type instructions, they specify the - size of the offset relative to the base register, and for memory - offset instructions such as `mov 1234,%al' they specify the size of - the offset relative to the segment base. */ -#define Disp8 0x1000 /* 8 bit displacement */ -#define Disp16 0x2000 /* 16 bit displacement */ -#define Disp32 0x4000 /* 32 bit displacement */ -#define Disp32S 0x8000 /* 32 bit signed displacement */ -#define Disp64 0x10000 /* 64 bit displacement */ - /* specials */ -#define InOutPortReg 0x20000 /* register to hold in/out port addr = dx */ -#define ShiftCount 0x40000 /* register to hold shift count = cl */ -#define Control 0x80000 /* Control register */ -#define Debug 0x100000 /* Debug register */ -#define Test 0x200000 /* Test register */ -#define FloatReg 0x400000 /* Float register */ -#define FloatAcc 0x800000 /* Float stack top %st(0) */ -#define SReg2 0x1000000 /* 2 bit segment register */ -#define SReg3 0x2000000 /* 3 bit segment register */ -#define Acc 0x4000000 /* Accumulator %al or %ax or %eax */ -#define JumpAbsolute 0x8000000 -#define RegMMX 0x10000000 /* MMX register */ -#define RegXMM 0x20000000 /* XMM registers in PIII */ -#define EsSeg 0x40000000 /* String insn operand with fixed es segment */ - - /* InvMem is for instructions with a modrm byte that only allow a - general register encoding in the i.tm.mode and i.tm.regmem fields, - eg. control reg moves. They really ought to support a memory form, - but don't, so we add an InvMem flag to the register operand to - indicate that it should be encoded in the i.tm.regmem field. */ -#define InvMem 0x80000000 - -#define Reg (Reg8|Reg16|Reg32|Reg64) /* gen'l register */ -#define WordReg (Reg16|Reg32|Reg64) -#define ImplicitRegister (InOutPortReg|ShiftCount|Acc|FloatAcc) -#define Imm (Imm8|Imm8S|Imm16|Imm32S|Imm32|Imm64) /* gen'l immediate */ -#define EncImm (Imm8|Imm16|Imm32|Imm32S) /* Encodable gen'l immediate */ -#define Disp (Disp8|Disp16|Disp32|Disp32S|Disp64) /* General displacement */ -#define AnyMem (Disp8|Disp16|Disp32|Disp32S|BaseIndex|InvMem) /* General memory */ - /* The following aliases are defined because the opcode table - carefully specifies the allowed memory types for each instruction. - At the moment we can only tell a memory reference size by the - instruction suffix, so there's not much point in defining Mem8, - Mem16, Mem32 and Mem64 opcode modifiers - We might as well just use - the suffix directly to check memory operands. */ -#define LLongMem AnyMem /* 64 bits (or more) */ -#define LongMem AnyMem /* 32 bit memory ref */ -#define ShortMem AnyMem /* 16 bit memory ref */ -#define WordMem AnyMem /* 16, 32 or 64 bit memory ref */ -#define ByteMem AnyMem /* 8 bit memory ref */ + i386_operand_type operand_types[MAX_OPERANDS]; } -template; +insn_template; -extern const template i386_optab[]; +extern const insn_template i386_optab[]; /* these are for register name --> number & type hash lookup */ typedef struct { - char *reg_name; - unsigned int reg_type; - unsigned int reg_flags; + const char *reg_name; + i386_operand_type reg_type; + unsigned char reg_flags; #define RegRex 0x1 /* Extended register. */ #define RegRex64 0x2 /* Extended 8 bit register. */ - unsigned int reg_num; +#define RegVRex 0x4 /* Extended vector register. */ + unsigned char reg_num; +#define RegIP ((unsigned char ) ~0) +/* EIZ and RIZ are fake index registers. */ +#define RegIZ (RegIP - 1) +/* FLAT is a fake segment register (Intel mode). */ +#define RegFlat ((unsigned char) ~0) + signed char dw2_regnum[2]; +#define Dw2Inval (-1) } reg_entry; @@ -215,8 +930,6 @@ reg_entry; extern const reg_entry i386_regtab[]; extern const unsigned int i386_regtab_size; -extern const reg_entry i386_float_regtab[]; -extern const unsigned int i386_float_regtab_size; typedef struct {