Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: src/trusted/validator/x86/decoder/generator/ncdecode_onebyte.c

Issue 625923004: Delete old x86 validator. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: rebase master Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 * Defines the one byte x86 opcodes. Based on opcodes given in table A-1 of
9 * appendix "A2 - Opcode Encodings", in AMD document 24594-Rev.3.14-September
10 * 2007, "AMD64 Architecture Programmer's manual Volume 3: General-Purpose
11 * and System Instructions".
12 *
13 * TODO(karl): This file is being updated to match Appendix A2.
14 * Not all instructions have yet been converted to the form used in
15 * in table A-1 cited above.
16 */
17
18 #ifndef NACL_TRUSTED_BUT_NOT_TCB
19 #error("This file is not meant for use in the TCB")
20 #endif
21
22 #include "native_client/src/include/nacl_macros.h"
23 #include "native_client/src/include/portability_io.h"
24 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_for ms.h"
25 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_st. h"
26 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tab legen.h"
27
28 /* Defines the buffer size to use to generate strings */
29 #define BUFFER_SIZE 256
30
31 /* Define a symbol table size that can hold a small number of
32 * symbols (i.e. limit to at most 5 definitions).
33 */
34 #define NACL_SMALL_ST (5)
35
36 /* Define the number of register values that can appear in an opcode. */
37
38 static const NaClMnemonic NaClGroup1OpcodeName[8] = {
39 InstAdd,
40 InstOr,
41 InstAdc,
42 InstSbb,
43 InstAnd,
44 InstSub,
45 InstXor,
46 InstCmp
47 };
48
49 static const NaClMnemonic NaClGroup1CompName[1] = {
50 InstCmp
51 };
52
53 /* Returns true if the given mnemonic name corresponds
54 * to Compare.
55 */
56 static Bool NaClIsGroup1CompName(NaClMnemonic name) {
57 int i;
58 for (i = 0; i < NACL_ARRAY_SIZE(NaClGroup1CompName); ++i) {
59 if (name == NaClGroup1CompName[i]) return TRUE;
60 }
61 return FALSE;
62 }
63
64 /* Returns the set/use categorization for a group 1 mnemonic name. */
65 static NaClInstCat NaClGroup1Cat(NaClMnemonic name) {
66 return NaClIsGroup1CompName(name) ? Compare : Binary;
67 }
68
69 /* Define binary operation XX+00 to XX+05, for the binary operators
70 * add, or, adc, sbb, and, sub, xor, and cmp. Base is the value XX.
71 * Name is the name of the operation. Extra flags are any additional
72 * flags that are true to a specific binary operator, rather than
73 * all binary operators.
74 */
75 static void NaClBuildBinaryOps_00_05(const uint8_t base,
76 const NaClInstType itype,
77 const NaClMnemonic name) {
78 NaClInstCat cat = NaClGroup1Cat(name);
79 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, NULL);
80 NaClSymbolTablePutText("name", NaClMnemonicName(name), st);
81 NaClSymbolTablePutByte("base", base, st);
82
83 NaClDefine("@base: @name $Eb, $Gb", itype, st, cat);
84
85 NaClSymbolTablePutByte("base", base+1, st);
86 NaClDefine("@base: @name $Ev, $Gv", itype, st, cat);
87
88 NaClSymbolTablePutByte("base", base+2, st);
89 NaClDefine("@base: @name $Gb, $Eb", itype, st, cat);
90
91 NaClSymbolTablePutByte("base", base+3, st);
92 NaClDefine("@base: @name $Gv, $Ev", itype, st, cat);
93
94 NaClSymbolTablePutByte("base", base+4, st);
95 NaClDefine("@base: @name %al, $Ib", itype, st, cat);
96
97 NaClSymbolTablePutByte("base", base+5, st);
98 NaClDefine("@base: @name $rAXv, $Iz", itype, st, cat);
99
100 NaClSymbolTableDestroy(st);
101 }
102
103 /* Define the Xchg operator where the register is embedded in the opcode */
104 static void NaClDefXchgRegister(void) {
105 /* Note: xchg is commutative, so order of operands is unimportant. */
106 int i;
107 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, NULL);
108 for (i = 0; i <= kMaxRegisterIndexInOpcode; ++i) {
109 NaClSymbolTablePutInt("i", i, st);
110 NaClDefine("90+@i: Xchg $r8v, $rAXv", NACLi_386, st , Exchange);
111 }
112 }
113
114 /* Define the increment and descrement operators XX+00 to XX+07. Base is
115 * the value XX. Name is the name of the increment/decrement operator.
116 */
117 static void NaClDefIncOrDec_00_07(const uint8_t base,
118 const NaClMnemonic name,
119 struct NaClSymbolTable* context_st) {
120 static char* reg[kMaxRegisterIndexInOpcode + 1] = {
121 "rAXv",
122 "rCXv",
123 "rDXv",
124 "rBXv",
125 "rSPv",
126 "rBPv",
127 "rSIv",
128 "rDIv"
129 };
130
131 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
132 int i;
133 NaClSymbolTablePutText("name", NaClMnemonicName(name), st);
134 for (i = 0; i <= kMaxRegisterIndexInOpcode; ++i) {
135 NaClSymbolTablePutByte("opcode", base + i, st);
136 NaClSymbolTablePutText("reg", reg[i], st);
137 /* Note: Since the following instructions are only defined in
138 * 32-bit mode, operand size 8 will not apply, and hence rXX
139 * is equivalent to eXX (as used in the ADM manual).
140 */
141 NaClDef_32("@opcode: @name $@reg", NACLi_386, st, UnaryUpdate);
142 }
143 NaClSymbolTableDestroy(st);
144 }
145
146 /* Define the push and pop operators XX+00 to XX+17. Base is
147 * the value of XX. Name is the name of the push/pop operator.
148 */
149 static void NaClDefPushOrPop_00_07(const uint8_t base,
150 const NaClMnemonic name,
151 struct NaClSymbolTable* context_st) {
152 int i;
153 NaClInstCat cat = (name == InstPush ? Push : Pop);
154 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
155 NaClSymbolTablePutByte("base", base, st);
156 NaClSymbolTablePutText("name", NaClMnemonicName(name), st);
157 for (i = 0; i <= kMaxRegisterIndexInOpcode; ++i) {
158 NaClSymbolTablePutInt("i", i, st);
159 NaClDefine("@base+@i: @name {%@sp}, $r8v", NACLi_386, st, cat);
160 }
161 NaClSymbolTableDestroy(st);
162 }
163
164 static void NaClDefGroup1OpcodesInModRm(struct NaClSymbolTable* context_st) {
165 int i;
166 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
167 for (i = 0; i < NACL_ARRAY_SIZE(NaClGroup1OpcodeName); ++i) {
168 NaClMnemonic name = NaClGroup1OpcodeName[i];
169 NaClInstCat cat = NaClGroup1Cat(name);
170 NaClSymbolTablePutInt("i", i, st);
171 NaClSymbolTablePutText("name", NaClMnemonicName(name), st);
172 NaClDefine("80/@i: @name $Eb, $Ib", NACLi_386, st, cat);
173 NaClDefine("81/@i: @name $Ev, $Iz", NACLi_386, st, cat);
174 /* The AMD manual shows 0x82 as a synonym for 0x80 in 32-bit mode only */
175 NaClDef_32("82/@i: @name $Eb, $Ib", NACLi_386, st, cat);
176 NaClDef_64("82/@i: Invalid", NACLi_INVALID, st, Other);
177 NaClDefine("83/@i: @name $Ev, $Ib", NACLi_386, st, cat);
178 }
179 NaClSymbolTableDestroy(st);
180 }
181
182 static void NaClDefJump8Opcode(uint8_t opcode, NaClMnemonic name,
183 struct NaClSymbolTable* context_st) {
184 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
185 NaClSymbolTablePutByte("opcode", opcode, st);
186 NaClSymbolTablePutText("name", NaClMnemonicName(name), st);
187 NaClDefine("@opcode: @name {%@ip}, $Jb", NACLi_386, st, Jump);
188 }
189
190 /* Defines a conditional jump instruction that is dependent on address size. */
191 typedef struct {
192 /* The platform(s) the instruction is defined on. */
193 const NaClTargetPlatform platform;
194 /* The register XX the instruction conditionalizes the jump on. */
195 const char* reg;
196 /* The address size held in register XX. */
197 const NaClIFlag addr_size;
198 /* Flags to add to register XX. */
199 const NaClOpFlags xx_flags;
200 /* The mnemonic name of the instruction. */
201 const char* name;
202 } CondJumpInst;
203
204 /* Generates conditiona jump instructions, based on the set of specified
205 * instructions.
206 *
207 * Parameters are:
208 * context_st - Symbol table defining other values if needed.
209 * opcode - The opcode value that defines the address jump instruction.
210 * address_insts - The address jump instructions to define.
211 */
212 static void NaClDefCondJump(struct NaClSymbolTable* context_st,
213 uint8_t opcode,
214 CondJumpInst address_insts[],
215 size_t address_insts_size) {
216 size_t i;
217 int num_32_insts = 0;
218 int num_64_insts = 0;
219 char buffer[BUFFER_SIZE];
220 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
221 SNPRINTF(buffer, BUFFER_SIZE, "%02x", opcode);
222
223 /* Count the number of forms for each type of instruction, and record. */
224 for (i = 0; i < address_insts_size; i++) {
225 switch (address_insts[i].platform) {
226 case T32:
227 num_32_insts++;
228 break;
229 case T64:
230 num_64_insts++;
231 break;
232 case Tall:
233 num_32_insts++;
234 num_64_insts++;
235 break;
236 }
237 }
238 NaClDefPrefixInstChoices_32_64(NoPrefix, opcode, num_32_insts, num_64_insts);
239
240 /* Generate each form of the instruction. */
241 for (i = 0; i < address_insts_size; ++i) {
242 NaClSymbolTablePutText("opcode", buffer, st);
243 NaClSymbolTablePutText("name", address_insts[i].name, st);
244 NaClSymbolTablePutText("reg", address_insts[i].reg, st);
245 NaClBegDefPlatform(address_insts[i].platform,
246 "@opcode: @name {%@ip}, {%@reg}, $Jb",
247 NACLi_386, st);
248 NaClAddIFlags(NACL_IFLAG(address_insts[i].addr_size));
249 NaClAddOpFlags(1, address_insts[i].xx_flags);
250 NaClEndDef(Jump);
251 }
252 }
253
254 /* Generates a jXXz instruction, based on the use of register XX
255 * (XX in cx, ecx, rcx).
256 */
257 static void NaClDefJumpRegZero(struct NaClSymbolTable* context_st) {
258 CondJumpInst inst[3] = {
259 { T32, "cx", AddressSize_w, NACL_EMPTY_OPFLAGS, "Jcxz" },
260 { Tall, "ecx", AddressSize_v, NACL_EMPTY_OPFLAGS, "Jecxz" },
261 { T64, "rcx", AddressSize_o, NACL_EMPTY_OPFLAGS, "Jrcxz" }
262 };
263 NaClDefCondJump(context_st, 0xe3, inst, NACL_ARRAY_SIZE(inst));
264 }
265
266 /* Generates the loop, loopne, and loope instructions. */
267 static void NaClDefLoop(struct NaClSymbolTable* context_st) {
268 /* The forms each loop instruction can have. */
269 CondJumpInst inst_forms[3] = {
270 { T32, "cx", AddressSize_w, NACL_OPFLAG(OpSet), "???" },
271 { Tall, "ecx", AddressSize_v, NACL_OPFLAG(OpSet), "???" },
272 { T64, "rcx", AddressSize_o, NACL_OPFLAG(OpSet), "???" }
273 };
274 /* The opcode/name of each loop instruction. */
275 struct {
276 uint8_t opcode;
277 const char* name;
278 } loop_inst[3] = {
279 {0xe0, "Loopne"},
280 {0xe1, "Loope"},
281 {0xe2, "Loop"},
282 };
283
284 /* Generate all combinations of the loop instruction. */
285 size_t i;
286 for (i = 0; i < NACL_ARRAY_SIZE(loop_inst); i++) {
287 size_t j;
288 for (j = 0; j < NACL_ARRAY_SIZE(inst_forms); j++) {
289 inst_forms[j].name = loop_inst[i].name;
290 }
291 NaClDefCondJump(context_st, loop_inst[i].opcode,
292 inst_forms, NACL_ARRAY_SIZE(inst_forms));
293 }
294 }
295
296 static const NaClMnemonic NaClGroup2OpcodeName[8] = {
297 InstRol,
298 InstRor,
299 InstRcl,
300 InstRcr,
301 InstShl, /* same as Sal */
302 InstShr,
303 InstShl, /* same as Sal; disallowed as an alias encoding */
304 InstSar
305 };
306
307 static void NaClDefGroup2OpcodesInModRm(struct NaClSymbolTable* context_st) {
308 int i;
309 struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
310 for (i = 0; i < NACL_ARRAY_SIZE(NaClGroup2OpcodeName); i++) {
311 /* The "/6" encodings of "Shl" are aliases of the "/4" encodings.
312 * "/4" is used by assemblers. We disallow "/6" on the grounds of
313 * minimalism.
314 */
315 NaClInstType insttype = i == 6 ? NACLi_ILLEGAL : NACLi_386;
316 NaClMnemonic name;
317 NaClSymbolTablePutInt("i", i, st);
318 name = NaClGroup2OpcodeName[i];
319 NaClSymbolTablePutText("name", NaClMnemonicName(name), st);
320 NaClDefine("c0/@i: @name $Eb, $Ib", insttype, st, Binary);
321 NaClDefine("c1/@i: @name $Ev, $Ib", insttype, st, Binary);
322 NaClDefine("d0/@i: @name $Eb, 1", insttype, st, Binary);
323 NaClDefine("d1/@i: @name $Ev, 1", insttype, st, Binary);
324 NaClDefine("d2/@i: @name $Eb, %cl", insttype, st, Binary);
325 NaClDefine("d3/@i: @name $Ev, %cl", insttype, st, Binary);
326 }
327 NaClSymbolTableDestroy(st);
328 }
329
330 void NaClDefOneByteInsts(struct NaClSymbolTable* st) {
331
332 NaClDefInstPrefix(NoPrefix);
333
334 NaClBuildBinaryOps_00_05(0x00, NACLi_386, InstAdd);
335 NaClDef_32("06: Push {%@sp}, %es", NACLi_386, st, Push);
336 NaClDef_64("06: Invalid", NACLi_INVALID, st, Other);
337 NaClDef_32("07: Pop {%@sp}, %es", NACLi_386, st, Pop);
338 NaClDef_64("07: Invalid", NACLi_INVALID, st, Other);
339 NaClBuildBinaryOps_00_05(0x08, NACLi_386, InstOr);
340 NaClDef_32("0e: Push {%@sp}, %cs", NACLi_386, st, Push);
341 NaClDef_64("0e: Invalid", NACLi_INVALID, st, Other);
342 /* 0x0F is a two-byte opcode prefix. */
343 NaClDefine("0f: Invalid", NACLi_INVALID, st, Other);
344 NaClBuildBinaryOps_00_05(0x10, NACLi_386, InstAdc);
345 NaClDef_32("16: Push {%@sp}, %ss", NACLi_386, st, Push);
346 NaClDef_64("16: Invalid", NACLi_INVALID, st, Other);
347 NaClDef_32("17: Pop {%@sp}, %ss", NACLi_386, st, Pop);
348 NaClDef_64("17: Invalid", NACLi_INVALID, st, Other);
349 NaClBuildBinaryOps_00_05(0x18, NACLi_386, InstSbb);
350 NaClDef_32("1e: Push {%@sp}, %ds", NACLi_386, st, Push);
351 NaClDef_64("1e: Invalid", NACLi_INVALID, st, Other);
352 NaClDef_32("1f: Pop {%@sp}, %ds", NACLi_386, st, Pop);
353 NaClDef_64("1f: Invalid", NACLi_INVALID, st, Other);
354 NaClBuildBinaryOps_00_05(0x20, NACLi_386, InstAnd);
355 /* 26: segment ES prefix */
356 NaClDefine("26: Invalid", NACLi_INVALID, st, Other);
357 NaClDef_32("27: Daa", NACLi_386, st, Other);
358 NaClDef_64("27: Invalid", NACLi_INVALID, st, Other);
359 NaClBuildBinaryOps_00_05(0x28, NACLi_386, InstSub);
360 /* 2e: segment CS prefix*/
361 NaClDefine("2e: Invalid", NACLi_INVALID, st, Other);
362 NaClDef_32("2f: Das", NACLi_386, st, Other);
363 NaClDef_64("2f: Invalid", NACLi_INVALID, st, Other);
364 NaClBuildBinaryOps_00_05(0x30, NACLi_386, InstXor);
365 /* 36: segment SS prefix */
366 NaClDefine("36: Invalid", NACLi_INVALID, st, Other);
367 NaClDef_32("37: Aaa {%al}", NACLi_386, st, UnaryUpdate);
368 NaClDef_64("37: Invalid", NACLi_INVALID, st, Other);
369 NaClBuildBinaryOps_00_05(0x38, NACLi_386, InstCmp);
370 /* Ox3e segment DS prefix */
371 NaClDefine("3e: Invalid", NACLi_INVALID, st, Other);
372 NaClDef_32("3f: Aas", NACLi_386, st, Other);
373 NaClDef_64("3f: Invalid", NACLi_INVALID, st, Other);
374 NaClDefIncOrDec_00_07(0x40, InstInc, st);
375 NaClDefIncOrDec_00_07(0x48, InstDec, st);
376 NaClDefPushOrPop_00_07(0x50, InstPush, st);
377 NaClDefPushOrPop_00_07(0x58, InstPop, st);
378 NaClDefPrefixInstChoices_32_64(NoPrefix, 0x60, 2, 1);
379 NaClBegD32("60: Pusha {%@sp}, {%gp7}", NACLi_386, st);
380 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
381 NaClEndDef(Push);
382 NaClBegD32("60: Pushad {%@sp}, {%gp7}", NACLi_386, st);
383 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
384 NaClEndDef(Push);
385 NaClDefPrefixInstChoices_32_64(NoPrefix, 0x61, 2, 1);
386 NaClDef_64("60: Invalid", NACLi_INVALID, st, Other);
387 NaClBegD32("61: Popa {%@sp}, {%gp7}", NACLi_386, st);
388 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
389 NaClEndDef(Pop);
390 NaClBegD32("61: Popad {%@sp}, {%gp7}", NACLi_386, st);
391 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
392 NaClEndDef(Pop);
393 NaClDef_64("61: Invalid", NACLi_INVALID, st, Other);
394 NaClDef_32("62: Bound $Gv, $Ma", NACLi_386, st, Uses);
395 NaClDef_64("62: Invalid", NACLi_INVALID, st, Other);
396 NaClDef_32("63: Arpl $Ew, $Gw", NACLi_SYSTEM, st, Binary);
397 NaClDef_64("63: Movsxd $Gv, $Ed", NACLi_386, st, Move);
398 /* 64: segment FS prefix */
399 NaClDefine("64: Invalid", NACLi_INVALID, st, Other);
400 /* 65: segment GS prefix */
401 NaClDefine("65: Invalid", NACLi_INVALID, st, Other);
402 /* 66: data size prefix */
403 NaClDefine("66: Invalid", NACLi_INVALID, st, Other);
404 /* 67: address size prefix */
405 NaClDefine("67: Invalid", NACLi_INVALID, st, Other);
406 NaClDefine("68: Push {%@sp} $Iz", NACLi_386, st, Push);
407 NaClDefine("69: Imul $Gv, $Ev, $Iz", NACLi_386, st, Binary);
408 NaClDefine("6a: Push {%@sp} $Ib", NACLi_386, st, Push);
409 NaClDefine("6b: Imul $Gv, $Ev, $Ib", NACLi_386, st, Binary);
410 NaClDefine("6c: Insb {$Yb}, {%dx}", NACLi_386, st, Move);
411 NaClDefPrefixInstChoices(NoPrefix, 0x6D, 2);
412 NaClDefine("6d: Insw {$Yzw}, {%dx}", NACLi_386, st, Move);
413 NaClDefine("6d: Insd {$Yzd}, {%dx}", NACLi_386, st, Move);
414 NaClDefine("6e: Outsb {%dx}, {$Xb}", NACLi_386, st, Uses);
415 NaClDefPrefixInstChoices(NoPrefix, 0x6F, 2);
416 NaClDefine("6f: Outsw {%dx}, {$Xzw}", NACLi_386, st, Uses);
417 NaClDefine("6f: Outsd {%dx}, {$Xzd}", NACLi_386, st, Uses);
418 NaClDefJump8Opcode(0x70, InstJo, st);
419 NaClDefJump8Opcode(0x71, InstJno, st);
420 NaClDefJump8Opcode(0x72, InstJb, st);
421 NaClDefJump8Opcode(0x73, InstJnb, st);
422 NaClDefJump8Opcode(0x74, InstJz, st);
423 NaClDefJump8Opcode(0x75, InstJnz, st);
424 NaClDefJump8Opcode(0x76, InstJbe, st);
425 NaClDefJump8Opcode(0x77, InstJnbe, st);
426 NaClDefJump8Opcode(0x78, InstJs, st);
427 NaClDefJump8Opcode(0x79, InstJns, st);
428 NaClDefJump8Opcode(0x7a, InstJp, st);
429 NaClDefJump8Opcode(0x7b, InstJnp, st);
430 NaClDefJump8Opcode(0x7c, InstJl, st);
431 NaClDefJump8Opcode(0x7d, InstJnl, st);
432 NaClDefJump8Opcode(0x7e, InstJle, st);
433 NaClDefJump8Opcode(0x7f, InstJnle, st);
434 /* Defines 80-83, using opcode in mod/rm */
435 NaClDefGroup1OpcodesInModRm(st);
436 NaClDefine("84: Test $Eb, $Gb", NACLi_386, st, Compare);
437 NaClDefine("85: Test $Ev, $Gv", NACLi_386, st, Compare);
438 NaClDefine("86: Xchg $Eb, $Gb", NACLi_386, st, Exchange);
439 NaClDefine("87: Xchg $Ev, $Gv", NACLi_386, st, Exchange);
440 NaClDefine("88: Mov $Eb, $Gb", NACLi_386, st, Move);
441 NaClDefine("89: Mov $Ev, $Gv", NACLi_386, st, Move);
442 NaClDefine("8a: Mov $Gb, $Eb", NACLi_386, st, Move);
443 NaClDefine("8b: Mov $Gv, $Ev", NACLi_386, st, Move);
444 NaClDefine("8c: Mov $Mw/Rv, $Sw", NACLi_386, st, Move);
445 NaClBegDef("8d: Lea $Gv, $M", NACLi_386, st);
446 NaClAddOpFlags(1, NACL_OPFLAG(OpAddress));
447 NaClEndDef(Lea);
448 NaClDefine("8e: Mov $Sw, $Ew", NACLi_386, st, Move);
449 NaClDefine("8f/0: Pop {%@sp}, $Ev", NACLi_386, st, Pop);
450 NaClDefine("8f/r: Invalid", NACLi_INVALID, st, Other);
451 /* 90-97: exchange register. */
452 NaClDefXchgRegister();
453 NaClDefPrefixInstChoices_32_64(NoPrefix, 0x98, 2, 3);
454 NaClBegDef("98: Cbw {%ax}, {%al}", NACLi_386, st);
455 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
456 NaClEndDef(Move);
457 NaClBegDef("98: Cwde {%eax}, {%ax}", NACLi_386, st);
458 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
459 NaClAddOpFlags(0, NACL_OPFLAG(OperandSignExtends_v));
460 NaClEndDef(Move);
461 NaClBegD64("98: Cdqe {%rax}, {%eax}", NACLi_386, st);
462 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
463 NaClEndDef(Move);
464 NaClDefPrefixInstChoices_32_64(NoPrefix, 0x99, 2, 3);
465 NaClBegDef("99: Cwd {%dx}, {%ax}", NACLi_386, st);
466 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
467 NaClEndDef(Move);
468 NaClBegDef("99: Cdq {%edx}, {%eax}", NACLi_386, st);
469 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
470 NaClEndDef(Move);
471 NaClBegD64("99: Cqo {%rdx}, {%rax}", NACLi_386, st);
472 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
473 NaClEndDef(Move);
474 NaClDef_32("9a: Call {%@ip}, {%@sp}, $Ap", NACLi_386, st, Call);
475 NaClDef_64("9a: Invalid", NACLi_INVALID, st, Other);
476 NaClDefine("9b: Fwait", NACLi_X87, st, Other);
477 NaClDefPrefixInstChoices(NoPrefix, 0x9c, 2);
478 NaClDefine("9c: Pushf {%@sp}, {$Fvw}", NACLi_386, st, Push);
479 NaClDef_32("9c: Pushfd {%@sp}, {$Fvd}", NACLi_386, st, Push);
480 NaClDef_64("9c: Pushfq {%@sp}, {$Fvq}", NACLi_386, st, Push);
481 NaClDefPrefixInstChoices(NoPrefix, 0x9d, 2);
482 NaClDefine("9d: Popf {%@sp}, {$Fvw}", NACLi_386, st, Pop);
483 NaClDef_32("9d: Popfd {%@sp}, {$Fvd}", NACLi_386, st, Pop);
484 NaClDef_64("9d: Popfq {%@sp}, {$Fvq}", NACLi_386, st, Pop);
485 NaClDefine("9e: Sahf {%ah}", NACLi_LAHF, st, Uses);
486 NaClDefine("9f: Lahf {%ah}", NACLi_LAHF, st, UnarySet);
487 NaClDefine("a0: Mov %al, $Ob", NACLi_386, st, Move);
488 NaClDefine("a1: Mov $rAXv, $Ov", NACLi_386, st, Move);
489 NaClDefine("a2: Mov $Ob, %al", NACLi_386, st, Move);
490 NaClDefine("a3: Mov $Ov, $rAXv", NACLi_386, st, Move);
491 NaClDefine("a4: Movsb $Yb, $Xb", NACLi_386, st, Move);
492 NaClDefPrefixInstChoices_32_64(NoPrefix, 0xa5, 2, 3);
493 NaClDefine("a5: Movsw $Yvw, $Xvw", NACLi_386, st, Move);
494 NaClDefine("a5: Movsd $Yvd, $Xvd", NACLi_386, st, Move);
495 NaClDef_64("a5: Movsq $Yvq, $Xvq", NACLi_386, st, Move);
496 NaClDefine("a6: Cmpsb $Yb, $Xb", NACLi_386, st, Compare);
497 NaClDefPrefixInstChoices_32_64(NoPrefix, 0xa7, 2, 3);
498 NaClDefine("a7: Cmpsw $Yvw, $Xvw", NACLi_386, st, Compare);
499 NaClDefine("a7: Cmpsd $Yvd, $Xvd", NACLi_386, st, Compare);
500 NaClDef_64("a7: Cmpsq $Yvq, $Xvq", NACLi_386, st, Compare);
501 NaClDefine("a8: Test %al, $Ib", NACLi_386, st, Compare);
502 NaClDefine("a9: Test $rAXv, $Iz", NACLi_386, st, Compare);
503 NaClDefine("aa: Stosb $Yb, {%al}", NACLi_386, st, Move);
504 NaClDefPrefixInstChoices_32_64(NoPrefix, 0xab, 2, 3);
505 NaClDefine("ab: Stosw $Yvw, {$rAXvw}", NACLi_386, st, Move);
506 NaClDefine("ab: Stosd $Yvd, {$rAXvd}", NACLi_386, st, Move);
507 NaClDef_64("ab: Stosq $Yvq, {$rAXvq}", NACLi_386, st, Move);
508 NaClDefine("ac: Lodsb {%al}, $Xb", NACLi_386, st, Move);
509 NaClDefPrefixInstChoices_32_64(NoPrefix, 0xad, 2, 3);
510 NaClDefine("ad: Lodsw {$rAXvw}, $Xvw", NACLi_386, st, Move);
511 NaClDefine("ad: Lodsd {$rAXvd}, $Xvd", NACLi_386, st, Move);
512 NaClDef_64("ad: Lodsq {$rAXvq}, $Xvq", NACLi_386, st, Move);
513 NaClDefine("ae: Scasb {%al}, $Yb", NACLi_386, st, Compare);
514 NaClDefPrefixInstChoices_32_64(NoPrefix, 0xaf, 2, 3);
515 NaClDefine("af: Scasw {$rAXvw}, $Yvw", NACLi_386, st, Compare);
516 NaClDefine("af: Scasd {$rAXvd}, $Yvd", NACLi_386, st, Compare);
517 NaClDef_64("af: Scasq {$rAXvq}, $Yvq", NACLi_386, st, Compare);
518 NaClDefReg("b0+@reg: Mov $r8b, $Ib", 0, 7, NACLi_386, st, Move);
519 NaClDefReg("b8+@reg: Mov $r8v, $Iv", 0, 7, NACLi_386, st, Move);
520 /* 0xC0 and 0xC1 defined by NaClDefGroup2OpcodesInModRm, called below. */
521 NaClDefine("c2: Ret {%@ip}, {%@sp}, $Iw", NACLi_386, st, Return);
522 NaClDefine("c3: Ret {%@ip}, {%@sp}", NACLi_386, st, Return);
523 NaClDef_32("c4: Les $SGz, $Mp", NACLi_386, st, Lea);
524 NaClDef_64("c4: Invalid", NACLi_INVALID, st, Other);
525 NaClDef_32("c5: Lds $SGz, $Mp", NACLi_386, st, Lea);
526 NaClDef_64("c5: Invalid", NACLi_INVALID, st, Other);
527 NaClDefine("c6/0: Mov $Eb, $Ib", NACLi_386, st, Move);
528 NaClDefine("c6/r: Invalid", NACLi_INVALID, st, Other);
529 NaClDefine("c7/0: Mov $Ev, $Iz", NACLi_386, st, Move);
530 NaClDefine("c7/r: Invalid", NACLi_INVALID, st, Other);
531 NaClDefine("c8: Enter {%@sp}, {%@bp}, $Iw, $I2b", NACLi_386, st, Call);
532 NaClDefine("c9: Leave {%@sp}, {%@bp}", NACLi_386, st, Return);
533 NaClDefine("ca: Ret {%@ip} {%@sp}, $Iw", NACLi_RETURN, st, Return);
534 NaClDefine("cb: Ret {%@ip} {%@sp}", NACLi_RETURN, st, Return);
535 NaClDefine("cc: Int3", NACLi_SYSTEM, st, Other);
536 NaClDefine("cd: Int $Ib", NACLi_386, st, Uses);
537 NaClDefine("ce: Into", NACLi_386, st, Other);
538 NaClDefPrefixInstChoices_32_64(NoPrefix, 0xcf, 2, 3);
539 NaClBegDef("cf: Iretd {%@ip} {%@sp}", NACLi_SYSTEM, st);
540 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
541 NaClEndDef(Return);
542 NaClBegD64("cf: Iretq {%@ip} {%@sp}", NACLi_SYSTEM, st);
543 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
544 NaClEndDef(Return);
545 NaClBegDef("cf: Iret {%@ip} {%@sp}", NACLi_SYSTEM, st);
546 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
547 NaClEndDef(Return);
548 /* Group 2 - 0xD0, 0XD1, 0xD2, 0xD3 */
549 NaClDefGroup2OpcodesInModRm(st);
550 NaClDef_32("d4: Aam {%ax} $Ib", NACLi_386, st, Binary);
551 NaClDef_64("d4: Invalid", NACLi_INVALID, st, Other);
552 NaClDef_32("d5: Aad {%ax}, $Ib", NACLi_386, st, Binary);
553 NaClDef_64("d5: Invalid", NACLi_INVALID, st, Other);
554 /* TODO(Karl): Intel manual (see comments above) has a blank entry
555 * for opcode 0xd6, which states that blank entries in the tables
556 * correspond to reserved (undefined) values Should we treat this
557 * accordingly? (currently illegal).
558 */
559 NaClDef_32("d6: Salc {%al}", NACLi_386, st, Other);
560 NaClDef_64("d6: Invalid", NACLi_INVALID, st, Other);
561 NaClDefine("d7: Xlat {%al}, {%DS_EBX}", NACLi_386, st, Binary);
562 /* Note: 0xd8 through 0xdf is defined in ncdecodeX87.c */
563 NaClDefLoop(st); /* opcodes e0, e1, and e2 */
564 /* 0xe3 - jXXz */
565 NaClDefJumpRegZero(st);
566 NaClDefine("e4: In %al, $Ib", NACLi_386, st, Move);
567 NaClDefine("e5: In $rAXv, $Ib", NACLi_386, st, Move);
568 NaClDefine("e6: Out $Ib, %al", NACLi_386, st, Move);
569 NaClDefine("e7: Out $Ib, $rAXv", NACLi_386, st, Move);
570 /* Note: We special case the 66 prefix on direct jumps and calls, by
571 * explicitly disallowing 16-bit direct branches. This is done partly because
572 * some versions (within x86-64) are not supported in such cases. However,
573 * NaCl also doesn't want to allow 16-bit direct branches.
574 */
575 NaClDefine("e8: Call {%@ip}, {%@sp}, $Jzd", NACLi_386, st, Call);
576 NaClDefine("e9: Jmp {%@ip}, $Jzd", NACLi_386, st, Jump);
577 NaClDef_32("ea: Jmp {%@ip}, $Ap", NACLi_386, st, Jump);
578 NaClDef_64("ea: Invalid", NACLi_INVALID, st, Other);
579 NaClDefine("eb: Jmp {%@ip}, $Jb", NACLi_386, st, Jump);
580 NaClDefine("ec: In %al, %dx", NACLi_386, st, Move);
581 NaClDefine("ed: In $rAXv, %dx", NACLi_386, st, Move);
582 NaClDefine("ee: Out %dx, %al", NACLi_386, st, Move);
583 NaClDefine("ef: Out %dx, $rAXv", NACLi_386, st, Move);
584 /* f0 : lock prefix. */
585 NaClDefine("f0: Invalid", NACLi_INVALID, st, Other);
586 NaClDefine("f1: Int1", NACLi_386, st, Other);
587 /* f2: Repne prefix. */
588 NaClDefine("f2: Invalid", NACLi_INVALID, st, Other);
589 /* f3: Rep prefix. */
590 NaClDefine("f3: Invalid", NACLi_INVALID, st, Other);
591 NaClDefine("f4: Hlt", NACLi_386, st, Other);
592 NaClDefine("f5: Cmc", NACLi_386, st, Other);
593 /* The "/1" encodings of "Test" are aliases of the "/0" encodings.
594 * "/0" is used by assemblers. We disallow "/1" on the grounds of
595 * minimalism.
596 */
597 NaClDefine("f6/0: Test $Eb, $Ib", NACLi_386, st, Compare);
598 NaClDefine("f6/1: Test $Eb, $Ib", NACLi_ILLEGAL, st, Compare);
599 NaClDefine("f6/2: Not $Eb", NACLi_386, st, UnaryUpdate);
600 NaClDefine("f6/3: Neg $Eb", NACLi_386, st, UnaryUpdate);
601 NaClDefine("f6/4: Mul {%ax}, {%al}, $Eb", NACLi_386, st, Binary);
602 NaClDefine("f6/5: Imul {%ax}, {%al}, $Eb", NACLi_386, st, Binary);
603 NaClDefine("f6/6: Div {%ax}, {%al}, $Eb", NACLi_386, st, Binary);
604 NaClDefine("f6/7: Idiv {%ax}, {%al},$Eb", NACLi_386, st, Binary);
605 NaClDefine("f7/0: Test $Ev, $Iz", NACLi_386, st, Compare);
606 NaClDefine("f7/1: Test $Ev, $Iz", NACLi_ILLEGAL, st, Compare);
607 NaClDefine("f7/2: Not $Ev", NACLi_386, st, UnaryUpdate);
608 NaClDefine("f7/3: Neg $Ev", NACLi_386, st, UnaryUpdate);
609 NaClDefine("f7/4: Mul {%redx}, {%reax}, $Ev", NACLi_386, st, O2Binary);
610 NaClDefine("f7/5: Imul {%redx}, {%reax}, $Ev", NACLi_386, st, O2Binary);
611 NaClDefine("f7/6: Div {%redx}, {%reax}, $Ev", NACLi_386, st, O2Binary);
612 NaClDefine("f7/7: Idiv {%redx}, {%reax}, $Ev", NACLi_386, st, O2Binary);
613 NaClDefine("f8: Clc", NACLi_386, st, Other);
614 NaClDefine("f9: Stc", NACLi_386, st, Other);
615 NaClDefine("fa: Cli", NACLi_SYSTEM, st, Other);
616 NaClDefine("fb: Sti", NACLi_SYSTEM, st, Other);
617 NaClDefine("fc: Cld", NACLi_386, st, Other);
618 NaClDefine("fd: Std", NACLi_386, st, Other);
619 NaClDefine("fe/0: Inc $Eb", NACLi_386, st, UnaryUpdate);
620 NaClDefine("fe/1: Dec $Eb", NACLi_386, st, UnaryUpdate);
621 NaClDefine("fe/2: Invalid", NACLi_INVALID, st, Other);
622 NaClDefine("fe/3: Invalid", NACLi_INVALID, st, Other);
623 NaClDefine("fe/4: Invalid", NACLi_INVALID, st, Other);
624 NaClDefine("fe/5: Invalid", NACLi_INVALID, st, Other);
625 NaClDefine("fe/6: Invalid", NACLi_INVALID, st, Other);
626 NaClDefine("fe/7: Invalid", NACLi_INVALID, st, Other);
627 NaClDefine("ff/0: Inc $Ev", NACLi_386, st, UnaryUpdate);
628 NaClDefine("ff/1: Dec $Ev", NACLi_386, st, UnaryUpdate);
629 NaClBegDef("ff/2: Call {%@ip}, {%@sp}, $Ev", NACLi_386, st);
630 NaClAddOpFlags(2, NACL_OPFLAG(OperandNear));
631 NaClEndDef(Call);
632 NaClDefine("ff/3: Call {%@ip}, {%@sp}, $Mp", NACLi_386, st, Call);
633 NaClBegDef("ff/4: Jmp {%@ip}, $Ev", NACLi_386, st);
634 NaClAddOpFlags(1, NACL_OPFLAG(OperandNear));
635 NaClEndDef(Jump);
636 NaClDefine("ff/5: Jmp {%@ip}, $Mp", NACLi_386, st, Jump);
637 NaClDefine("ff/6: Push {%@sp}, $Ev", NACLi_386, st, Push);
638 NaClDefine("ff/7: Invalid", NACLi_INVALID, st, Other);
639 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698