opflags: Introduce opflags generating macros
[nasm.git] / opflags.h
blob904a53a2396eb13675b34aa4faad43c251c5dcba
1 /* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2012 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * opflags.h - operand flags
38 #ifndef NASM_OPFLAGS_H
39 #define NASM_OPFLAGS_H
41 #include "compiler.h"
44 * Here we define the operand types. These are implemented as bit
45 * masks, since some are subsets of others; e.g. AX in a MOV
46 * instruction is a special operand type, whereas AX in other
47 * contexts is just another 16-bit register. (Also, consider CL in
48 * shift instructions, DX in OUT, etc.)
50 * The basic concept here is that
51 * (class & ~operand) == 0
53 * if and only if "operand" belongs to class type "class".
55 * The bits are assigned as follows:
57 * Bits 0-7, 23, 29: sizes
58 * 0: 8 bits (BYTE)
59 * 1: 16 bits (WORD)
60 * 2: 32 bits (DWORD)
61 * 3: 64 bits (QWORD)
62 * 4: 80 bits (TWORD)
63 * 5: FAR
64 * 6: NEAR
65 * 7: SHORT
66 * 23: 256 bits (YWORD)
67 * 29: 128 bits (OWORD)
69 * Bits 8-10 modifiers
70 * 8: TO
71 * 9: COLON
72 * 10: STRICT
74 * Bits 12-15: type of operand
75 * 12: REGISTER
76 * 13: IMMEDIATE
77 * 14: MEMORY (always has REGMEM attribute as well)
78 * 15: REGMEM (valid EA operand)
80 * Bits 11, 16-19, 28: subclasses
81 * With REG_CDT:
82 * 16: REG_CREG (CRx)
83 * 17: REG_DREG (DRx)
84 * 18: REG_TREG (TRx)
86 * With REG_GPR:
87 * 16: REG_ACCUM (AL, AX, EAX, RAX)
88 * 17: REG_COUNT (CL, CX, ECX, RCX)
89 * 18: REG_DATA (DL, DX, EDX, RDX)
90 * 19: REG_HIGH (AH, CH, DH, BH)
91 * 28: REG_NOTACC (not REG_ACCUM)
93 * With REG_SREG:
94 * 16: REG_CS
95 * 17: REG_DESS (DS, ES, SS)
96 * 18: REG_FSGS
97 * 19: REG_SEG67
99 * With FPUREG:
100 * 16: FPU0
102 * With XMMREG:
103 * 16: XMM0
105 * With YMMREG:
106 * 16: YMM0
108 * With MEMORY:
109 * 16: MEM_OFFS (this is a simple offset)
110 * 17: IP_REL (IP-relative offset)
112 * With IMMEDIATE:
113 * 16: UNITY (1)
114 * 17: BYTENESS16 (-128..127)
115 * 18: BYTENESS32 (-128..127)
116 * 19: BYTENESS64 (-128..127)
117 * 28: SDWORD64 (-2^31..2^31-1)
118 * 11: UDWORD64 (0..2^32-1)
120 * Bits 20-22, 24-27: register classes
121 * 20: REG_CDT (CRx, DRx, TRx)
122 * 21: RM_GPR (REG_GPR) (integer register)
123 * 22: REG_SREG
124 * 24: FPUREG
125 * 25: RM_MMX (MMXREG)
126 * 26: RM_XMM (XMMREG)
127 * 27: RM_YMM (YMMREG)
129 * 30: SAME_AS
130 * Special flag only used in instruction patterns; means this operand
131 * has to be identical to another operand. Currently only supported
132 * for registers.
135 typedef uint64_t opflags_t;
137 #define OP_GENMASK(bits, shift) (((UINT64_C(1) << (bits)) - 1) << (shift))
138 #define OP_GENBIT(bit, shift) (UINT64_C(1) << ((shift) + (bit)))
141 /* Size, and other attributes, of the operand */
142 #define BITS8 UINT64_C(0x00000001)
143 #define BITS16 UINT64_C(0x00000002)
144 #define BITS32 UINT64_C(0x00000004)
145 #define BITS64 UINT64_C(0x00000008) /* x64 and FPU only */
146 #define BITS80 UINT64_C(0x00000010) /* FPU only */
147 #define BITS128 UINT64_C(0x20000000)
148 #define BITS256 UINT64_C(0x00800000)
149 #define FAR UINT64_C(0x00000020) /* grotty: this means 16:16 or */
150 /* 16:32, like in CALL/JMP */
151 #define NEAR UINT64_C(0x00000040)
152 #define SHORT UINT64_C(0x00000080) /* and this means what it says :) */
154 #define SIZE_MASK UINT64_C(0x208000FF) /* all the size attributes */
156 /* Modifiers */
157 #define MODIFIER_MASK UINT64_C(0x00000700)
158 #define TO UINT64_C(0x00000100) /* reverse effect in FADD, FSUB &c */
159 #define COLON UINT64_C(0x00000200) /* operand is followed by a colon */
160 #define STRICT UINT64_C(0x00000400) /* do not optimize this operand */
162 /* Type of operand: memory reference, register, etc. */
163 #define OPTYPE_MASK UINT64_C(0x0000f000)
164 #define REGISTER UINT64_C(0x00001000) /* register number in 'basereg' */
165 #define IMMEDIATE UINT64_C(0x00002000)
166 #define MEMORY UINT64_C(0x0000c000)
167 #define REGMEM UINT64_C(0x00008000) /* for r/m, ie EA, operands */
169 #define is_class(class, op) (!((opflags_t)(class) & ~(opflags_t)(op)))
171 #define IS_SREG(op) is_class(REG_SREG, nasm_reg_flags[(op)])
172 #define IS_FSGS(op) is_class(REG_FSGS, nasm_reg_flags[(op)])
174 /* Register classes */
175 #define REG_EA UINT64_C(0x00009000) /* 'normal' reg, qualifies as EA */
176 #define RM_GPR UINT64_C(0x00208000) /* integer operand */
177 #define REG_GPR UINT64_C(0x00209000) /* integer register */
178 #define REG8 UINT64_C(0x00209001) /* 8-bit GPR */
179 #define REG16 UINT64_C(0x00209002) /* 16-bit GPR */
180 #define REG32 UINT64_C(0x00209004) /* 32-bit GPR */
181 #define REG64 UINT64_C(0x00209008) /* 64-bit GPR */
182 #define FPUREG UINT64_C(0x01001000) /* floating point stack registers */
183 #define FPU0 UINT64_C(0x01011000) /* FPU stack register zero */
184 #define RM_MMX UINT64_C(0x02008000) /* MMX operand */
185 #define MMXREG UINT64_C(0x02009000) /* MMX register */
186 #define RM_XMM UINT64_C(0x04008000) /* XMM (SSE) operand */
187 #define XMMREG UINT64_C(0x04009000) /* XMM (SSE) register */
188 #define XMM0 UINT64_C(0x04019000) /* XMM register zero */
189 #define RM_YMM UINT64_C(0x08008000) /* YMM (AVX) operand */
190 #define YMMREG UINT64_C(0x08009000) /* YMM (AVX) register */
191 #define YMM0 UINT64_C(0x08019000) /* YMM register zero */
192 #define REG_CDT UINT64_C(0x00101004) /* CRn, DRn and TRn */
193 #define REG_CREG UINT64_C(0x00111004) /* CRn */
194 #define REG_DREG UINT64_C(0x00121004) /* DRn */
195 #define REG_TREG UINT64_C(0x00141004) /* TRn */
196 #define REG_SREG UINT64_C(0x00401002) /* any segment register */
197 #define REG_CS UINT64_C(0x00411002) /* CS */
198 #define REG_DESS UINT64_C(0x00421002) /* DS, ES, SS */
199 #define REG_FSGS UINT64_C(0x00441002) /* FS, GS */
200 #define REG_SEG67 UINT64_C(0x00481002) /* Unimplemented segment registers */
202 /* Special GPRs */
203 #define REG_SMASK UINT64_C(0x100f0800) /* a mask for the following */
204 #define REG_ACCUM UINT64_C(0x00219000) /* accumulator: AL, AX, EAX, RAX */
205 #define REG_AL UINT64_C(0x00219001)
206 #define REG_AX UINT64_C(0x00219002)
207 #define REG_EAX UINT64_C(0x00219004)
208 #define REG_RAX UINT64_C(0x00219008)
209 #define REG_COUNT UINT64_C(0x10229000) /* counter: CL, CX, ECX, RCX */
210 #define REG_CL UINT64_C(0x10229001)
211 #define REG_CX UINT64_C(0x10229002)
212 #define REG_ECX UINT64_C(0x10229004)
213 #define REG_RCX UINT64_C(0x10229008)
214 #define REG_DL UINT64_C(0x10249001) /* data: DL, DX, EDX, RDX */
215 #define REG_DX UINT64_C(0x10249002)
216 #define REG_EDX UINT64_C(0x10249004)
217 #define REG_RDX UINT64_C(0x10249008)
218 #define REG_HIGH UINT64_C(0x10289001) /* high regs: AH, CH, DH, BH */
219 #define REG_NOTACC UINT64_C(0x10000000) /* non-accumulator register */
220 #define REG8NA UINT64_C(0x10209001) /* 8-bit non-acc GPR */
221 #define REG16NA UINT64_C(0x10209002) /* 16-bit non-acc GPR */
222 #define REG32NA UINT64_C(0x10209004) /* 32-bit non-acc GPR */
223 #define REG64NA UINT64_C(0x10209008) /* 64-bit non-acc GPR */
225 /* special types of EAs */
226 #define MEM_OFFS UINT64_C(0x0001c000) /* simple [address] offset - absolute! */
227 #define IP_REL UINT64_C(0x0002c000) /* IP-relative offset */
229 /* memory which matches any type of r/m operand */
230 #define MEMORY_ANY (MEMORY|RM_GPR|RM_MMX|RM_XMM|RM_YMM)
232 /* special type of immediate operand */
233 #define UNITY UINT64_C(0x00012000) /* for shift/rotate instructions */
234 #define SBYTE16 UINT64_C(0x00022000) /* for op r16,immediate instrs. */
235 #define SBYTE32 UINT64_C(0x00042000) /* for op r32,immediate instrs. */
236 #define SBYTE64 UINT64_C(0x00082000) /* for op r64,immediate instrs. */
237 #define BYTENESS UINT64_C(0x000e0000) /* for testing for byteness */
238 #define SDWORD64 UINT64_C(0x10002000) /* for op r64,simm32 instrs. */
239 #define UDWORD64 UINT64_C(0x00002800) /* for op r64,uimm32 instrs. */
241 /* special flags */
242 #define SAME_AS UINT64_C(0x40000000)
244 #endif /* NASM_OPFLAGS_H */