/* Declarations for Intel 80386 opcode table
- Copyright 2007
+ Copyright 2007, 2008, 2009, 2010
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
02110-1301, USA. */
#include "opcode/i386.h"
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#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,
+ /* 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,
+ /* ABM New Instructions required */
+ CpuABM,
+ /* SSE4.1 support required */
+ CpuSSE4_1,
+ /* SSE4.2 support required */
+ CpuSSE4_2,
+ /* AVX support required */
+ CpuAVX,
+ /* AVX2 support required */
+ CpuAVX2,
+ /* Intel L1OM support required */
+ CpuL1OM,
+ /* 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,
+ /* 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,
+ /* LZCNT support required */
+ CpuLZCNT,
+ /* INVPCID Instructions required */
+ CpuINVPCID,
+ /* 64bit support available, used by -march= in assembler. */
+ CpuLM,
+ /* 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 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 cpuabm:1;
+ unsigned int cpusse4_1:1;
+ unsigned int cpusse4_2:1;
+ unsigned int cpuavx:1;
+ unsigned int cpuavx2:1;
+ unsigned int cpul1om: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 cpuept:1;
+ unsigned int cpurdtscp:1;
+ unsigned int cpufsgsbase:1;
+ unsigned int cpurdrnd:1;
+ unsigned int cpuf16c:1;
+ unsigned int cpubmi2:1;
+ unsigned int cpulzcnt:1;
+ unsigned int cpuinvpcid:1;
+ unsigned int cpulm: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 words or dwords encoded the canonical way */
+ W,
+ /* Skip the current insn and use the next insn in i386-opc.tbl to swap
+ operand in encoding. */
+ S,
+ /* insn has a modrm byte. */
+ Modrm,
+ /* register is in low 3 bits of opcode */
+ ShortForm,
+ /* special case for jump insns. */
+ Jump,
+ /* call and jump */
+ JumpDword,
+ /* loop and jecxz */
+ JumpByte,
+ /* special case for intersegment leaps/calls */
+ JumpInterSegment,
+ /* FP insn memory format bit, sized by 0x4 */
+ FloatMF,
+ /* src/dest swap for floats. */
+ FloatR,
+ /* has float insn direction bit. */
+ FloatD,
+ /* needs size prefix if in 32-bit mode */
+ Size16,
+ /* needs size prefix if in 16-bit mode */
+ Size32,
+ /* needs size prefix if in 64-bit mode */
+ Size64,
+ /* check register size. */
+ CheckRegSize,
+ /* instruction ignores operand size prefix and in Intel mode ignores
+ mnemonic size suffix check. */
+ IgnoreSize,
+ /* default insn size depends on mode */
+ DefaultSize,
+ /* 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,
+ /* quick test for string instructions */
+ IsString,
+ /* quick test for lockable instructions */
+ IsLockable,
+ /* fake an extra reg operand for clr, imul and special register
+ processing for some instructions. */
+ RegKludge,
+ /* The first operand must be xmm0 */
+ FirstXmm0,
+ /* An implicit xmm0 as the first operand */
+ Implicit1stXmm0,
+ /* Convert to DWORD */
+ ToDword,
+ /* Convert to QWORD */
+ ToQword,
+ /* Address prefix changes operand 0 */
+ AddrPrefixOp0,
+ /* opcode is a prefix */
+ IsPrefix,
+ /* instruction has extension in 8 bit imm */
+ ImmExt,
+ /* instruction don't need Rex64 prefix. */
+ NoRex64,
+ /* instruction require Rex64 prefix. */
+ Rex64,
+ /* deprecated fp insn, gets a warning */
+ Ugh,
+ /* insn has VEX prefix:
+ 1: 128bit VEX prefix.
+ 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.
+ */
+#define VEXW0 1
+#define VEXW1 2
+ 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 has VEX 8 bit imm */
+ VexImmExt,
+ /* Instruction with vector SIB byte:
+ 1: 128bit vector register.
+ 2: 256bit vector register.
+ */
+#define VecSIB128 1
+#define VecSIB256 2
+ VecSIB,
+ /* SSE to AVX support required */
+ SSE2AVX,
+ /* No AVX equivalent */
+ NoAVX,
+ /* Compatible with old (<= 2.8.1) versions of gcc */
+ OldGcc,
+ /* AT&T mnemonic. */
+ ATTMnemonic,
+ /* AT&T syntax. */
+ ATTSyntax,
+ /* Intel syntax. */
+ IntelSyntax,
+ /* The last bitfield in i386_opcode_modifier. */
+ Opcode_Modifier_Max
+};
+
+typedef struct i386_opcode_modifier
+{
+ unsigned int d:1;
+ unsigned int w:1;
+ unsigned int s:1;
+ unsigned int modrm:1;
+ unsigned int shortform:1;
+ unsigned int jump:1;
+ unsigned int jumpdword:1;
+ unsigned int jumpbyte:1;
+ unsigned int jumpintersegment:1;
+ unsigned int floatmf:1;
+ unsigned int floatr:1;
+ unsigned int floatd:1;
+ unsigned int size16:1;
+ unsigned int size32:1;
+ unsigned int size64:1;
+ unsigned int checkregsize:1;
+ unsigned int ignoresize:1;
+ unsigned int defaultsize: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:1;
+ unsigned int islockable:1;
+ unsigned int regkludge:1;
+ unsigned int firstxmm0:1;
+ unsigned int implicit1stxmm0:1;
+ unsigned int todword:1;
+ unsigned int toqword:1;
+ unsigned int addrprefixop0:1;
+ unsigned int isprefix:1;
+ unsigned int immext:1;
+ unsigned int norex64:1;
+ unsigned int rex64: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 veximmext:1;
+ unsigned int vecsib:2;
+ unsigned int sse2avx:1;
+ unsigned int noavx:1;
+ unsigned int oldgcc:1;
+ unsigned int attmnemonic:1;
+ unsigned int attsyntax:1;
+ unsigned int intelsyntax:1;
+} i386_opcode_modifier;
+
+/* Position of operand_type bits. */
+
+enum
+{
+ /* 8bit register */
+ Reg8 = 0,
+ /* 16bit register */
+ Reg16,
+ /* 32bit register */
+ Reg32,
+ /* 64bit register */
+ Reg64,
+ /* Floating pointer stack register */
+ FloatReg,
+ /* MMX register */
+ RegMMX,
+ /* SSE register */
+ RegXMM,
+ /* AVX registers */
+ RegYMM,
+ /* Control register */
+ Control,
+ /* Debug register */
+ Debug,
+ /* Test register */
+ Test,
+ /* 2 bit segment register */
+ SReg2,
+ /* 3 bit segment register */
+ SReg3,
+ /* 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,
+ /* Accumulator %al/%ax/%eax/%rax */
+ Acc,
+ /* Floating pointer top stack register %st(0) */
+ FloatAcc,
+ /* Register which can be used for base or index in memory operand. */
+ BaseIndex,
+ /* Register to hold in/out port addr = dx */
+ InOutPortReg,
+ /* Register to hold shift count = cl */
+ ShiftCount,
+ /* Absolute address for jump. */
+ JumpAbsolute,
+ /* String insn operand with fixed es segment */
+ EsSeg,
+ /* 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 the destination register operand to indicate that it should
+ be encoded in the regmem field. */
+ RegMem,
+ /* Memory. */
+ Mem,
+ /* BYTE memory. */
+ Byte,
+ /* WORD memory. 2 byte */
+ Word,
+ /* DWORD memory. 4 byte */
+ Dword,
+ /* FWORD memory. 6 byte */
+ Fword,
+ /* QWORD memory. 8 byte */
+ Qword,
+ /* TBYTE memory. 10 byte */
+ Tbyte,
+ /* XMMWORD memory. */
+ Xmmword,
+ /* YMMWORD memory. */
+ Ymmword,
+ /* Unspecified memory size. */
+ Unspecified,
+ /* Any memory size. */
+ Anysize,
+
+ /* Vector 4 bit immediate. */
+ Vec_Imm4,
+
+ /* The last bitfield in i386_operand_type. */
+ OTMax
+};
+
+#define OTNumOfUints \
+ (OTMax / 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 (OTMax + 1)
+
+typedef union i386_operand_type
+{
+ struct
+ {
+ unsigned int reg8:1;
+ unsigned int reg16:1;
+ unsigned int reg32:1;
+ unsigned int reg64:1;
+ unsigned int floatreg:1;
+ unsigned int regmmx:1;
+ unsigned int regxmm:1;
+ unsigned int regymm:1;
+ unsigned int control:1;
+ unsigned int debug:1;
+ unsigned int test:1;
+ unsigned int sreg2:1;
+ unsigned int sreg3:1;
+ 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 acc:1;
+ unsigned int floatacc:1;
+ unsigned int baseindex:1;
+ unsigned int inoutportreg:1;
+ unsigned int shiftcount:1;
+ unsigned int jumpabsolute:1;
+ unsigned int esseg:1;
+ unsigned int regmem:1;
+ unsigned int mem: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 unspecified:1;
+ unsigned int anysize:1;
+ unsigned int vec_imm4: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;
/* 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 */
+ If this template has no extension opcode (the usual case) use None
+ Instructions */
unsigned int extension_opcode;
#define None 0xffff /* If no extension_opcode is possible. */
+ /* Opcode length. */
+ unsigned char opcode_length;
+
/* 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 */
-#define CpuSSE4_1 0x400000 /* SSE4.1 Instructions required */
-#define CpuSSE4_2 0x800000 /* SSE4.2 Instructions required */
-
-/* SSE4.1/4.2 Instructions required */
-#define CpuSSE4 (CpuSSE4_1|CpuSSE4_2)
-
- /* 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|CpuSSE4_1 \
- |CpuSSE4_2|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
- and special register processing for
- some instructions. */
-#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 */
-
- /* 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 the destination register operand to indicate that it should
- be encoded in the regmem field. */
-#define RegMem 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) /* 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;
+ 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;
+ unsigned char reg_num;
+#define RegRip ((unsigned char ) ~0)
+#define RegEip (RegRip - 1)
+/* EIZ and RIZ are fake index registers. */
+#define RegEiz (RegEip - 1)
+#define RegRiz (RegEiz - 1)
+/* FLAT is a fake segment register (Intel mode). */
+#define RegFlat ((unsigned char) ~0)
+ signed char dw2_regnum[2];
+#define Dw2Inval (-1)
}
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
{