OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can be | |
4 * found in the LICENSE file. | |
5 */ | |
6 | |
7 /* | |
8 * x86_insts.h - Holds common utilties for decoding x86 instructions. | |
9 */ | |
10 | |
11 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_X86_INSTS_H__ | |
12 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_X86_INSTS_H__ | |
13 | |
14 #include "native_client/src/include/portability.h" | |
15 | |
16 /* Readability macros for bitset testing. */ | |
17 /* Set contains bit. */ | |
18 #define NaClHasBit(set, bit) ((set) & (bit)) | |
19 | |
20 /* Set contains (all) bits. */ | |
21 #define NaClHasBits(set, bits) ((bits) == ((set) & (bits))) | |
22 | |
23 /* Set contains bits other than given bit. */ | |
24 #define NaClExcludesBit(set, bit) (~(set) & bit) | |
25 | |
26 /* Readability macros for changing bitsets. */ | |
27 #define NaClAddBits(set, bits) (set |= (bits)) | |
28 #define NaClRemoveBits(set, bits) (set &= ~(bits)) | |
29 | |
30 EXTERN_C_BEGIN | |
31 | |
32 /* Defines the corresponding byte encodings for each of the prefixes. */ | |
33 #define kValueSEGCS 0x2e | |
34 #define kValueSEGSS 0x36 | |
35 #define kValueSEGFS 0x64 | |
36 #define kValueSEGGS 0x65 | |
37 #define kValueDATA16 0x66 | |
38 #define kValueADDR16 0x67 | |
39 #define kValueREPNE 0xf2 | |
40 #define kValueREP 0xf3 | |
41 #define kValueLOCK 0xf0 | |
42 #define kValueSEGES 0x26 | |
43 #define kValueSEGDS 0x3e | |
44 | |
45 /* Using a bit mask here. Hopefully nobody will be offended. | |
46 * Prefix usage: 0x2e and 0x3e are used as branch prediction hints | |
47 * 0x64 and 0x65 needed for TLS | |
48 * 0x26 and 0x36 shouldn't be needed | |
49 * These are #defines, not const ints, because they are used | |
50 * for array initialization | |
51 */ | |
52 #define kPrefixSEGCS 0x0001 /* 0x2e */ | |
53 #define kPrefixSEGSS 0x0002 /* 0x36 */ | |
54 #define kPrefixSEGFS 0x0004 /* 0x64 */ | |
55 #define kPrefixSEGGS 0x0008 /* 0x65 */ | |
56 #define kPrefixDATA16 0x0010 /* 0x66 - OKAY */ | |
57 #define kPrefixADDR16 0x0020 /* 0x67 - disallowed */ | |
58 #define kPrefixREPNE 0x0040 /* 0xf2 - OKAY */ | |
59 #define kPrefixREP 0x0080 /* 0xf3 - OKAY */ | |
60 #define kPrefixLOCK 0x0100 /* 0xf0 - OKAY */ | |
61 #define kPrefixSEGES 0x0200 /* 0x26 - disallowed */ | |
62 #define kPrefixSEGDS 0x0400 /* 0x3e - disallowed */ | |
63 #define kPrefixREX 0x1000 /* 0x40 - 0x4f Rex prefix */ | |
64 | |
65 /* a new enumerated type for instructions. | |
66 * Note: Each enumerate type is marked with one of the following symbols, | |
67 * defining the validator it us used for: | |
68 * 32 - The x86-32 validator. | |
69 * 64 - The x86-64 validator. | |
70 * Both - Both the x86-32 and the x86-64 validators. | |
71 * Note: The code for the x86-64 validator is being cleaned up, and there | |
72 * are still uses of the "32" tag for x86 instructions. | |
73 * TODO(karl) - Fix this comment when modeling for the x86-64 has been cleaned | |
74 * up. | |
75 */ | |
76 typedef enum { | |
77 NACLi_UNDEFINED = 0, /* uninitialized space; should never happen */ /* Both */ | |
78 NACLi_ILLEGAL, /* not allowed in NaCl */ /* Both */ | |
79 NACLi_INVALID, /* not valid on any known x86 */ /* Both */ | |
80 NACLi_SYSTEM, /* ring-0 instruction, not allowed in NaCl */ /* Both */ | |
81 NACLi_NOP, /* Predefined nop instruction sequence. */ /* 32 */ | |
82 NACLi_386, /* an allowed instruction on all i386 implementations */ | |
83 /* Both */ | |
84 /* subset of i386 that allows LOCK prefix. NOTE: | |
85 * This is only used for the 32 bit validator. The new | |
86 * 64 bit validator uses "InstFlag(OpcodeLockable)" | |
87 * to communicate this (which separates the CPU ID | |
88 * information from whether the instruction is lockable. | |
89 * Hopefully, in future releases, this enumerated type | |
90 * will be removed. | |
91 */ | |
92 NACLi_386L, /* 32 */ | |
93 NACLi_386R, /* subset of i386 that allow REP prefix */ /* 32 */ | |
94 NACLi_386RE, /* subset of i386 that allow REPE/REPZ prefixes */ | |
95 /* 32 */ | |
96 NACLi_JMP8, /* 32 */ | |
97 NACLi_JMPZ, /* 32 */ | |
98 NACLi_INDIRECT, /* 32 */ | |
99 NACLi_OPINMRM, /* 32 */ | |
100 NACLi_RETURN, /* 32 */ | |
101 /* Both */ | |
102 NACLi_LAHF, /* LAHF/SAHF: unconditionally allowed in 32-bit | |
103 conditionally allowed in 64-bit mode */ | |
104 NACLi_SFENCE_CLFLUSH, /* Both */ | |
105 NACLi_CMPXCHG8B, /* Both */ | |
106 NACLi_CMPXCHG16B, /* 64-bit mode only, illegal for NaCl */ /* Both */ | |
107 NACLi_CMOV, /* Both */ | |
108 NACLi_RDMSR, /* Both */ | |
109 NACLi_RDTSC, /* Both */ | |
110 NACLi_RDTSCP, /* AMD only */ /* Both */ | |
111 NACLi_SYSCALL, /* AMD only; equivalent to SYSENTER */ /* Both */ | |
112 NACLi_SYSENTER, /* Both */ | |
113 NACLi_X87, /* Both */ | |
114 NACLi_X87_FSINCOS, /* Both */ | |
115 NACLi_MMX, /* Both */ | |
116 NACLi_MMXSSE2, /* MMX with no prefix, SSE2 with 0x66 prefix */ /* Both */ | |
117 NACLi_3DNOW, /* AMD only */ /* Both */ | |
118 NACLi_EMMX, /* Cyrix only; not supported yet */ /* Both */ | |
119 NACLi_E3DNOW, /* AMD only */ /* Both */ | |
120 NACLi_SSE, /* Both */ | |
121 NACLi_SSE2, /* no prefix => MMX; prefix 66 => SSE; */ /* Both */ | |
122 /* f2, f3 not allowed unless used for opcode selection */ | |
123 NACLi_SSE2x, /* SSE2; prefix 66 required!!! */ /* 32 */ | |
124 NACLi_SSE3, /* Both */ | |
125 NACLi_SSE4A, /* AMD only */ /* Both */ | |
126 NACLi_SSE41, /* Both */ | |
127 NACLi_SSE42, /* Both */ | |
128 NACLi_MOVBE, /* Both */ | |
129 NACLi_POPCNT, /* Both */ | |
130 NACLi_LZCNT, /* Both */ | |
131 NACLi_LONGMODE,/* AMD only? */ /* 32 */ | |
132 NACLi_SVM, /* AMD only */ /* Both */ | |
133 NACLi_SSSE3, /* Both */ | |
134 NACLi_3BYTE, /* 32 */ | |
135 NACLi_FCMOV, /* 32 */ | |
136 NACLi_VMX, /* 64 */ | |
137 NACLi_FXSAVE /* SAVE/RESTORE xmm, mmx, and x87 state. */ /* 64 */ | |
138 /* NOTE: This enum must be kept consistent with kNaClInstTypeRange */ | |
139 /* (defined below). */ | |
140 /* Note: If you change this enumerated type, be sure to update */ | |
141 /* kNaClInstTypeString in x86_insts.c. */ | |
142 } NaClInstType; | |
143 | |
144 #define kNaClInstTypeRange 49 | |
145 | |
146 /* Returns the print name for the enumerated type.*/ | |
147 const char* NaClInstTypeString(NaClInstType typ); | |
148 | |
149 /* Define the maximum register value that can be encoded into the opcode | |
150 * byte. | |
151 */ | |
152 #define kMaxRegisterIndexInOpcode 7 | |
153 | |
154 extern const uint8_t kFirstX87Opcode; /* 0xd8 */ | |
155 extern const uint8_t kLastX87Opcode; /* 0xdf */ | |
156 | |
157 /* Defines the opcode for the WAIT instruction. | |
158 * Note: WAIT is an x87 instruction but not in the coproc opcode space. | |
159 */ | |
160 extern const uint8_t kWAITOp; /* 0x9b */ | |
161 | |
162 #define NCDTABLESIZE 256 | |
163 | |
164 extern const uint8_t kTwoByteOpcodeByte1; /* 0x0f */ | |
165 extern const uint8_t k3DNowOpcodeByte2; /* 0x0f */ | |
166 extern const int kMaxPrefixBytes; /* 4 */ | |
167 | |
168 /* Accessors for the ModRm byte. */ | |
169 extern uint8_t modrm_mod(uint8_t modrm); | |
170 extern uint8_t modrm_rm(uint8_t modrm); | |
171 extern uint8_t modrm_reg(uint8_t modrm); | |
172 extern uint8_t modrm_opcode(uint8_t modrm); | |
173 | |
174 /* Accessors for the Sib byte. */ | |
175 extern uint8_t sib_ss(uint8_t sib); | |
176 extern uint8_t sib_index(uint8_t sib); | |
177 extern uint8_t sib_base(uint8_t sib); | |
178 | |
179 /* Defines the range of rex prefix values. */ | |
180 extern const uint8_t NaClRexMin; /* 0x40 */ | |
181 extern const uint8_t NaClRexMax; /* 0x4F */ | |
182 | |
183 /* Accessors for each of the rex bits. */ | |
184 uint8_t NaClRexW(uint8_t prefix); | |
185 uint8_t NaClRexR(uint8_t prefix); | |
186 uint8_t NaClRexX(uint8_t prefix); | |
187 uint8_t NaClRexB(uint8_t prefix); | |
188 | |
189 EXTERN_C_END | |
190 | |
191 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_X86_INSTS_H__ */ | |
OLD | NEW |