summaryrefslogtreecommitdiff
path: root/opflags.h
blob: c2b72b03550808a5b3abea7d869df33690b2f67e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/* ----------------------------------------------------------------------- *
 *   
 *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
 *   See the file AUTHORS included with the NASM distribution for
 *   the specific copyright holders.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following
 *   conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *     
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ----------------------------------------------------------------------- */

/*
 * opflags.h - operand flags
 */

#ifndef NASM_OPFLAGS_H
#define NASM_OPFLAGS_H

#include "compiler.h"

/*
 * Here we define the operand types. These are implemented as bit
 * masks, since some are subsets of others; e.g. AX in a MOV
 * instruction is a special operand type, whereas AX in other
 * contexts is just another 16-bit register. (Also, consider CL in
 * shift instructions, DX in OUT, etc.)
 *
 * The basic concept here is that
 *    (class & ~operand) == 0
 *
 * if and only if "operand" belongs to class type "class".
 *
 * The bits are assigned as follows:
 *
 * Bits 0-7, 23, 29: sizes
 *  0:  8 bits (BYTE)
 *  1: 16 bits (WORD)
 *  2: 32 bits (DWORD)
 *  3: 64 bits (QWORD)
 *  4: 80 bits (TWORD)
 *  5: FAR
 *  6: NEAR
 *  7: SHORT
 * 23: 256 bits (YWORD)
 * 29: 128 bits (OWORD)
 *
 * Bits 8-10 modifiers
 *  8: TO
 *  9: COLON
 * 10: STRICT
 *
 * Bits 12-15: type of operand
 * 12: REGISTER
 * 13: IMMEDIATE
 * 14: MEMORY (always has REGMEM attribute as well)
 * 15: REGMEM (valid EA operand)
 *
 * Bits 11, 16-19, 28: subclasses
 * With REG_CDT:
 * 16: REG_CREG (CRx)
 * 17: REG_DREG (DRx)
 * 18: REG_TREG (TRx)

 * With REG_GPR:
 * 16: REG_ACCUM  (AL, AX, EAX, RAX)
 * 17: REG_COUNT  (CL, CX, ECX, RCX)
 * 18: REG_DATA   (DL, DX, EDX, RDX)
 * 19: REG_HIGH   (AH, CH, DH, BH)
 * 28: REG_NOTACC (not REG_ACCUM)
 *
 * With REG_SREG:
 * 16: REG_CS
 * 17: REG_DESS (DS, ES, SS)
 * 18: REG_FSGS
 * 19: REG_SEG67
 *
 * With FPUREG:
 * 16: FPU0
 *
 * With XMMREG:
 * 16: XMM0
 *
 * With YMMREG:
 * 16: YMM0
 *
 * With MEMORY:
 * 16: MEM_OFFS (this is a simple offset)
 * 17: IP_REL (IP-relative offset)
 *
 * With IMMEDIATE:
 * 16: UNITY (1)
 * 17: BYTENESS16 (-128..127)
 * 18: BYTENESS32 (-128..127)
 * 19: BYTENESS64 (-128..127)
 * 28: SDWORD64 (-2^31..2^31-1)
 * 11: UDWORD64 (0..2^32-1)
 *
 * Bits 20-22, 24-27: register classes
 * 20: REG_CDT (CRx, DRx, TRx)
 * 21: RM_GPR (REG_GPR) (integer register)
 * 22: REG_SREG
 * 24: FPUREG
 * 25: RM_MMX (MMXREG)
 * 26: RM_XMM (XMMREG)
 * 27: RM_YMM (YMMREG)
 *
 * 30: SAME_AS
 * Special flag only used in instruction patterns; means this operand
 * has to be identical to another operand.  Currently only supported
 * for registers.
 */

typedef uint32_t opflags_t;

/* Size, and other attributes, of the operand */
#define BITS8           0x00000001U
#define BITS16          0x00000002U
#define BITS32          0x00000004U
#define BITS64          0x00000008U   /* x64 and FPU only */
#define BITS80          0x00000010U   /* FPU only */
#define BITS128         0x20000000U
#define BITS256         0x00800000U
#define FAR             0x00000020U   /* grotty: this means 16:16 or */
                                       /* 16:32, like in CALL/JMP */
#define NEAR            0x00000040U
#define SHORT           0x00000080U   /* and this means what it says :) */

#define SIZE_MASK       0x208000FFU   /* all the size attributes */

/* Modifiers */
#define MODIFIER_MASK   0x00000700U
#define TO              0x00000100U   /* reverse effect in FADD, FSUB &c */
#define COLON           0x00000200U   /* operand is followed by a colon */
#define STRICT          0x00000400U   /* do not optimize this operand */

/* Type of operand: memory reference, register, etc. */
#define OPTYPE_MASK     0x0000f000U
#define REGISTER        0x00001000U   /* register number in 'basereg' */
#define IMMEDIATE       0x00002000U
#define MEMORY          0x0000c000U
#define REGMEM          0x00008000U   /* for r/m, ie EA, operands */

#define is_class(class, op)     (!((opflags_t)(class) & ~(opflags_t)(op)))

/* Register classes */
#define REG_EA          0x00009000U   /* 'normal' reg, qualifies as EA */
#define RM_GPR          0x00208000U   /* integer operand */
#define REG_GPR         0x00209000U   /* integer register */
#define REG8            0x00209001U   /*  8-bit GPR  */
#define REG16           0x00209002U   /* 16-bit GPR */
#define REG32           0x00209004U   /* 32-bit GPR */
#define REG64           0x00209008U   /* 64-bit GPR */
#define FPUREG          0x01001000U   /* floating point stack registers */
#define FPU0            0x01011000U   /* FPU stack register zero */
#define RM_MMX          0x02008000U   /* MMX operand */
#define MMXREG          0x02009000U   /* MMX register */
#define RM_XMM          0x04008000U   /* XMM (SSE) operand */
#define XMMREG          0x04009000U   /* XMM (SSE) register */
#define XMM0            0x04019000U   /* XMM register zero */
#define RM_YMM          0x08008000U   /* YMM (AVX) operand */
#define YMMREG          0x08009000U   /* YMM (AVX) register */
#define YMM0            0x08019000U   /* YMM register zero */
#define REG_CDT         0x00101004U   /* CRn, DRn and TRn */
#define REG_CREG        0x00111004U   /* CRn */
#define REG_DREG        0x00121004U   /* DRn */
#define REG_TREG        0x00141004U   /* TRn */
#define REG_SREG        0x00401002U   /* any segment register */
#define REG_CS          0x00411002U   /* CS */
#define REG_DESS        0x00421002U   /* DS, ES, SS */
#define REG_FSGS        0x00441002U   /* FS, GS */
#define REG_SEG67       0x00481002U   /* Unimplemented segment registers */

#define REG_RIP         0x00801008U   /* RIP relative addressing */
#define REG_EIP         0x00801004U   /* EIP relative addressing */

/* Special GPRs */
#define REG_SMASK       0x100f0800U   /* a mask for the following */
#define REG_ACCUM       0x00219000U   /* accumulator: AL, AX, EAX, RAX */
#define REG_AL          0x00219001U
#define REG_AX          0x00219002U
#define REG_EAX         0x00219004U
#define REG_RAX         0x00219008U
#define REG_COUNT       0x10229000U   /* counter: CL, CX, ECX, RCX */
#define REG_CL          0x10229001U
#define REG_CX          0x10229002U
#define REG_ECX         0x10229004U
#define REG_RCX         0x10229008U
#define REG_DL          0x10249001U   /* data: DL, DX, EDX, RDX */
#define REG_DX          0x10249002U
#define REG_EDX         0x10249004U
#define REG_RDX         0x10249008U
#define REG_HIGH        0x10289001U   /* high regs: AH, CH, DH, BH */
#define REG_NOTACC      0x10000000U   /* non-accumulator register */
#define REG8NA          0x10209001U   /*  8-bit non-acc GPR  */
#define REG16NA         0x10209002U   /* 16-bit non-acc GPR */
#define REG32NA         0x10209004U   /* 32-bit non-acc GPR */
#define REG64NA         0x10209008U   /* 64-bit non-acc GPR */

/* special types of EAs */
#define MEM_OFFS        0x0001c000U   /* simple [address] offset - absolute! */
#define IP_REL          0x0002c000U   /* IP-relative offset */

/* memory which matches any type of r/m operand */
#define MEMORY_ANY      (MEMORY|RM_GPR|RM_MMX|RM_XMM|RM_YMM)

/* special type of immediate operand */
#define UNITY           0x00012000U   /* for shift/rotate instructions */
#define SBYTE16         0x00022000U   /* for op r16,immediate instrs. */
#define SBYTE32         0x00042000U   /* for op r32,immediate instrs. */
#define SBYTE64         0x00082000U   /* for op r64,immediate instrs. */
#define BYTENESS        0x000e0000U   /* for testing for byteness */
#define SDWORD64	0x10002000U   /* for op r64,simm32 instrs. */
#define UDWORD64	0x00002800U   /* for op r64,uimm32 instrs. */

/* special flags */
#define SAME_AS         0x40000000U

#endif /* NASM_OPFLAGS_H */