1 | /* ----------------------------------------------------------------------- * |
2 | * |
3 | * Copyright 1996-2018 The NASM Authors - All Rights Reserved |
4 | * See the file AUTHORS included with the NASM distribution for |
5 | * the specific copyright holders. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following |
9 | * conditions are met: |
10 | * |
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. |
17 | * |
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. |
31 | * |
32 | * ----------------------------------------------------------------------- */ |
33 | |
34 | /* |
35 | * opflags.h - operand flags |
36 | */ |
37 | |
38 | #ifndef NASM_OPFLAGS_H |
39 | #define NASM_OPFLAGS_H |
40 | |
41 | #include "compiler.h" |
42 | #include "tables.h" /* for opflags_t and nasm_reg_flags[] */ |
43 | #include "regs.h" |
44 | |
45 | /* |
46 | * Here we define the operand types. These are implemented as bit |
47 | * masks, since some are subsets of others; e.g. AX in a MOV |
48 | * instruction is a special operand type, whereas AX in other |
49 | * contexts is just another 16-bit register. (Also, consider CL in |
50 | * shift instructions, DX in OUT, etc.) |
51 | * |
52 | * The basic concept here is that |
53 | * (class & ~operand) == 0 |
54 | * |
55 | * if and only if "operand" belongs to class type "class". |
56 | */ |
57 | |
58 | #define OP_GENMASK(bits, shift) (((UINT64_C(1) << (bits)) - 1) << (shift)) |
59 | #define OP_GENBIT(bit, shift) (UINT64_C(1) << ((shift) + (bit))) |
60 | |
61 | /* |
62 | * Type of operand: memory reference, register, etc. |
63 | * |
64 | * Bits: 0 - 3 |
65 | */ |
66 | #define OPTYPE_SHIFT (0) |
67 | #define OPTYPE_BITS (4) |
68 | #define OPTYPE_MASK OP_GENMASK(OPTYPE_BITS, OPTYPE_SHIFT) |
69 | #define GEN_OPTYPE(bit) OP_GENBIT(bit, OPTYPE_SHIFT) |
70 | |
71 | /* |
72 | * Modifiers. |
73 | * |
74 | * Bits: 4 - 6 |
75 | */ |
76 | #define MODIFIER_SHIFT (4) |
77 | #define MODIFIER_BITS (3) |
78 | #define MODIFIER_MASK OP_GENMASK(MODIFIER_BITS, MODIFIER_SHIFT) |
79 | #define GEN_MODIFIER(bit) OP_GENBIT(bit, MODIFIER_SHIFT) |
80 | |
81 | /* |
82 | * Register classes. |
83 | * |
84 | * Bits: 7 - 16 |
85 | */ |
86 | #define REG_CLASS_SHIFT (7) |
87 | #define REG_CLASS_BITS (10) |
88 | #define REG_CLASS_MASK OP_GENMASK(REG_CLASS_BITS, REG_CLASS_SHIFT) |
89 | #define GEN_REG_CLASS(bit) OP_GENBIT(bit, REG_CLASS_SHIFT) |
90 | |
91 | /* |
92 | * Subclasses. Depends on type of operand. |
93 | * |
94 | * Bits: 17 - 24 |
95 | */ |
96 | #define SUBCLASS_SHIFT (17) |
97 | #define SUBCLASS_BITS (8) |
98 | #define SUBCLASS_MASK OP_GENMASK(SUBCLASS_BITS, SUBCLASS_SHIFT) |
99 | #define GEN_SUBCLASS(bit) OP_GENBIT(bit, SUBCLASS_SHIFT) |
100 | |
101 | /* |
102 | * Special flags. Context dependant. |
103 | * |
104 | * Bits: 25 - 31 |
105 | */ |
106 | #define SPECIAL_SHIFT (25) |
107 | #define SPECIAL_BITS (7) |
108 | #define SPECIAL_MASK OP_GENMASK(SPECIAL_BITS, SPECIAL_SHIFT) |
109 | #define GEN_SPECIAL(bit) OP_GENBIT(bit, SPECIAL_SHIFT) |
110 | |
111 | /* |
112 | * Sizes of the operands and attributes. |
113 | * |
114 | * Bits: 32 - 42 |
115 | */ |
116 | #define SIZE_SHIFT (32) |
117 | #define SIZE_BITS (11) |
118 | #define SIZE_MASK OP_GENMASK(SIZE_BITS, SIZE_SHIFT) |
119 | #define GEN_SIZE(bit) OP_GENBIT(bit, SIZE_SHIFT) |
120 | |
121 | /* |
122 | * Register set count |
123 | * |
124 | * Bits: 47 - 43 |
125 | */ |
126 | #define REGSET_SHIFT (43) |
127 | #define REGSET_BITS (5) |
128 | #define REGSET_MASK OP_GENMASK(REGSET_BITS, REGSET_SHIFT) |
129 | #define GEN_REGSET(bit) OP_GENBIT(bit, REGSET_SHIFT) |
130 | |
131 | /* |
132 | * Bits distribution (counted from 0) |
133 | * |
134 | * 6 5 4 3 2 1 |
135 | * 3210987654321098765432109876543210987654321098765432109876543210 |
136 | * | |
137 | * | dword bound |
138 | * |
139 | * ............................................................1111 optypes |
140 | * .........................................................111.... modifiers |
141 | * ...............................................1111111111....... register classes |
142 | * .......................................11111111................. subclasses |
143 | * ................................1111111......................... specials |
144 | * .....................11111111111................................ sizes |
145 | * ................11111........................................... regset count |
146 | */ |
147 | |
148 | #define REGISTER GEN_OPTYPE(0) /* register number in 'basereg' */ |
149 | #define IMMEDIATE GEN_OPTYPE(1) |
150 | #define REGMEM GEN_OPTYPE(2) /* for r/m, ie EA, operands */ |
151 | #define MEMORY (GEN_OPTYPE(3) | REGMEM) |
152 | |
153 | #define BITS8 GEN_SIZE(0) /* 8 bits (BYTE) */ |
154 | #define BITS16 GEN_SIZE(1) /* 16 bits (WORD) */ |
155 | #define BITS32 GEN_SIZE(2) /* 32 bits (DWORD) */ |
156 | #define BITS64 GEN_SIZE(3) /* 64 bits (QWORD), x64 and FPU only */ |
157 | #define BITS80 GEN_SIZE(4) /* 80 bits (TWORD), FPU only */ |
158 | #define BITS128 GEN_SIZE(5) /* 128 bits (OWORD) */ |
159 | #define BITS256 GEN_SIZE(6) /* 256 bits (YWORD) */ |
160 | #define BITS512 GEN_SIZE(7) /* 512 bits (ZWORD) */ |
161 | #define FAR GEN_SIZE(8) /* grotty: this means 16:16 or 16:32, like in CALL/JMP */ |
162 | #define NEAR GEN_SIZE(9) |
163 | #define SHORT GEN_SIZE(10) /* and this means what it says :) */ |
164 | |
165 | #define TO GEN_MODIFIER(0) /* reverse effect in FADD, FSUB &c */ |
166 | #define COLON GEN_MODIFIER(1) /* operand is followed by a colon */ |
167 | #define STRICT GEN_MODIFIER(2) /* do not optimize this operand */ |
168 | |
169 | #define REG_CLASS_CDT GEN_REG_CLASS(0) |
170 | #define REG_CLASS_GPR GEN_REG_CLASS(1) |
171 | #define REG_CLASS_SREG GEN_REG_CLASS(2) |
172 | #define REG_CLASS_FPUREG GEN_REG_CLASS(3) |
173 | #define REG_CLASS_RM_MMX GEN_REG_CLASS(4) |
174 | #define REG_CLASS_RM_XMM GEN_REG_CLASS(5) |
175 | #define REG_CLASS_RM_YMM GEN_REG_CLASS(6) |
176 | #define REG_CLASS_RM_ZMM GEN_REG_CLASS(7) |
177 | #define REG_CLASS_OPMASK GEN_REG_CLASS(8) |
178 | #define REG_CLASS_BND GEN_REG_CLASS(9) |
179 | |
180 | static inline bool is_class(opflags_t class, opflags_t op) |
181 | { |
182 | return !(class & ~op); |
183 | } |
184 | |
185 | static inline bool is_reg_class(opflags_t class, opflags_t reg) |
186 | { |
187 | if (reg >= EXPR_REG_START && reg <= EXPR_REG_END) |
188 | return is_class(class, nasm_reg_flags[reg]); |
189 | return false; |
190 | } |
191 | |
192 | #define IS_SREG(reg) is_reg_class(REG_SREG, (reg)) |
193 | #define IS_FSGS(reg) is_reg_class(REG_FSGS, (reg)) |
194 | |
195 | /* Register classes */ |
196 | #define REG_EA ( REGMEM | REGISTER) /* 'normal' reg, qualifies as EA */ |
197 | #define RM_GPR ( REG_CLASS_GPR | REGMEM) /* integer operand */ |
198 | #define REG_GPR ( REG_CLASS_GPR | REGMEM | REGISTER) /* integer register */ |
199 | #define REG8 ( REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* 8-bit GPR */ |
200 | #define REG16 ( REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) /* 16-bit GPR */ |
201 | #define REG32 ( REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) /* 32-bit GPR */ |
202 | #define REG64 ( REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) /* 64-bit GPR */ |
203 | #define FPUREG ( REG_CLASS_FPUREG | REGISTER) /* floating point stack registers */ |
204 | #define FPU0 (GEN_SUBCLASS(1) | REG_CLASS_FPUREG | REGISTER) /* FPU stack register zero */ |
205 | #define RM_MMX ( REG_CLASS_RM_MMX | REGMEM) /* MMX operand */ |
206 | #define MMXREG ( REG_CLASS_RM_MMX | REGMEM | REGISTER) /* MMX register */ |
207 | #define RM_XMM ( REG_CLASS_RM_XMM | REGMEM) /* XMM (SSE) operand */ |
208 | #define XMMREG ( REG_CLASS_RM_XMM | REGMEM | REGISTER) /* XMM (SSE) register */ |
209 | #define RM_YMM ( REG_CLASS_RM_YMM | REGMEM) /* YMM (AVX) operand */ |
210 | #define YMMREG ( REG_CLASS_RM_YMM | REGMEM | REGISTER) /* YMM (AVX) register */ |
211 | #define RM_ZMM ( REG_CLASS_RM_ZMM | REGMEM) /* ZMM (AVX512) operand */ |
212 | #define ZMMREG ( REG_CLASS_RM_ZMM | REGMEM | REGISTER) /* ZMM (AVX512) register */ |
213 | #define RM_OPMASK ( REG_CLASS_OPMASK | REGMEM) /* Opmask operand */ |
214 | #define OPMASKREG ( REG_CLASS_OPMASK | REGMEM | REGISTER) /* Opmask register */ |
215 | #define OPMASK0 (GEN_SUBCLASS(1) | REG_CLASS_OPMASK | REGMEM | REGISTER) /* Opmask register zero (k0) */ |
216 | #define RM_K RM_OPMASK |
217 | #define KREG OPMASKREG |
218 | #define RM_BND ( REG_CLASS_BND | REGMEM) /* Bounds operand */ |
219 | #define BNDREG ( REG_CLASS_BND | REGMEM | REGISTER) /* Bounds register */ |
220 | #define REG_CDT ( REG_CLASS_CDT | BITS32 | REGISTER) /* CRn, DRn and TRn */ |
221 | #define REG_CREG (GEN_SUBCLASS(1) | REG_CLASS_CDT | BITS32 | REGISTER) /* CRn */ |
222 | #define REG_DREG (GEN_SUBCLASS(2) | REG_CLASS_CDT | BITS32 | REGISTER) /* DRn */ |
223 | #define REG_TREG (GEN_SUBCLASS(3) | REG_CLASS_CDT | BITS32 | REGISTER) /* TRn */ |
224 | #define REG_SREG ( REG_CLASS_SREG | BITS16 | REGISTER) /* any segment register */ |
225 | |
226 | /* Segment registers */ |
227 | #define REG_ES (GEN_SUBCLASS(0) | GEN_SUBCLASS(2) | REG_CLASS_SREG | BITS16 | REGISTER) /* ES */ |
228 | #define REG_CS (GEN_SUBCLASS(1) | GEN_SUBCLASS(2) | REG_CLASS_SREG | BITS16 | REGISTER) /* CS */ |
229 | #define REG_SS (GEN_SUBCLASS(0) | GEN_SUBCLASS(3) | REG_CLASS_SREG | BITS16 | REGISTER) /* SS */ |
230 | #define REG_DS (GEN_SUBCLASS(1) | GEN_SUBCLASS(3) | REG_CLASS_SREG | BITS16 | REGISTER) /* DS */ |
231 | #define REG_FS (GEN_SUBCLASS(0) | GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* FS */ |
232 | #define REG_GS (GEN_SUBCLASS(1) | GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* GS */ |
233 | #define REG_FSGS ( GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* FS or GS */ |
234 | #define REG_SEG67 ( GEN_SUBCLASS(5) | REG_CLASS_SREG | BITS16 | REGISTER) /* Unimplemented segment registers */ |
235 | |
236 | /* Special GPRs */ |
237 | #define REG_SMASK SUBCLASS_MASK /* a mask for the following */ |
238 | #define REG_ACCUM (GEN_SUBCLASS(1) | REG_CLASS_GPR | REGMEM | REGISTER) /* accumulator: AL, AX, EAX, RAX */ |
239 | #define REG_AL (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) |
240 | #define REG_AX (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) |
241 | #define REG_EAX (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) |
242 | #define REG_RAX (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) |
243 | #define REG_COUNT (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | REGMEM | REGISTER) /* counter: CL, CX, ECX, RCX */ |
244 | #define REG_CL (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) |
245 | #define REG_CX (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) |
246 | #define REG_ECX (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) |
247 | #define REG_RCX (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) |
248 | #define REG_DL (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* data: DL, DX, EDX, RDX */ |
249 | #define REG_DX (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) |
250 | #define REG_EDX (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) |
251 | #define REG_RDX (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) |
252 | #define REG_HIGH (GEN_SUBCLASS(5) | GEN_SUBCLASS(4) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* high regs: AH, CH, DH, BH */ |
253 | #define REG_NOTACC GEN_SUBCLASS(5) /* non-accumulator register */ |
254 | #define REG8NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* 8-bit non-acc GPR */ |
255 | #define REG16NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) /* 16-bit non-acc GPR */ |
256 | #define REG32NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) /* 32-bit non-acc GPR */ |
257 | #define REG64NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) /* 64-bit non-acc GPR */ |
258 | |
259 | /* special types of EAs */ |
260 | #define MEM_OFFS (GEN_SUBCLASS(1) | MEMORY) /* simple [address] offset - absolute! */ |
261 | #define IP_REL (GEN_SUBCLASS(2) | MEMORY) /* IP-relative offset */ |
262 | #define XMEM (GEN_SUBCLASS(3) | MEMORY) /* 128-bit vector SIB */ |
263 | #define YMEM (GEN_SUBCLASS(4) | MEMORY) /* 256-bit vector SIB */ |
264 | #define ZMEM (GEN_SUBCLASS(5) | MEMORY) /* 512-bit vector SIB */ |
265 | |
266 | /* memory which matches any type of r/m operand */ |
267 | #define MEMORY_ANY (MEMORY | RM_GPR | RM_MMX | RM_XMM_L16 | RM_YMM_L16 | RM_ZMM_L16 | RM_OPMASK | RM_BND) |
268 | |
269 | /* special immediate values */ |
270 | #define UNITY (GEN_SUBCLASS(0) | IMMEDIATE) /* operand equals 1 */ |
271 | #define SBYTEWORD (GEN_SUBCLASS(1) | IMMEDIATE) /* operand is in the range -128..127 mod 2^16 */ |
272 | #define SBYTEDWORD (GEN_SUBCLASS(2) | IMMEDIATE) /* operand is in the range -128..127 mod 2^32 */ |
273 | #define SDWORD (GEN_SUBCLASS(3) | IMMEDIATE) /* operand is in the range -0x80000000..0x7FFFFFFF */ |
274 | #define UDWORD (GEN_SUBCLASS(4) | IMMEDIATE) /* operand is in the range 0..0xFFFFFFFF */ |
275 | |
276 | /* |
277 | * Subset of vector registers: register 0 only and registers 0-15. |
278 | * Avoid conflicts in subclass bitfield with any of special EA types! |
279 | */ |
280 | #define RM_XMM_L16 (GEN_SUBCLASS(6) | RM_XMM) /* XMM r/m operand 0 ~ 15 */ |
281 | #define XMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | XMMREG) /* XMM register zero */ |
282 | #define XMM_L16 ( GEN_SUBCLASS(6) | XMMREG) /* XMM register 0 ~ 15 */ |
283 | |
284 | #define RM_YMM_L16 (GEN_SUBCLASS(6) | RM_YMM) /* YMM r/m operand 0 ~ 15 */ |
285 | #define YMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | YMMREG) /* YMM register zero */ |
286 | #define YMM_L16 ( GEN_SUBCLASS(6) | YMMREG) /* YMM register 0 ~ 15 */ |
287 | |
288 | #define RM_ZMM_L16 (GEN_SUBCLASS(6) | RM_ZMM) /* ZMM r/m operand 0 ~ 15 */ |
289 | #define ZMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | ZMMREG) /* ZMM register zero */ |
290 | #define ZMM_L16 ( GEN_SUBCLASS(6) | ZMMREG) /* ZMM register 0 ~ 15 */ |
291 | |
292 | /* Register set sizes */ |
293 | #define RS2 GEN_REGSET(0) |
294 | #define RS4 GEN_REGSET(1) |
295 | #define RS8 GEN_REGSET(2) |
296 | #define RS16 GEN_REGSET(3) |
297 | #define RS32 GEN_REGSET(4) |
298 | |
299 | #endif /* NASM_OPFLAGS_H */ |
300 | |