Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / validator / x86 / decoder / generator / ncdecode_forms.c
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  * Set of predefined instruction forms (via procedure calls), providing
9  * a more concise way of specifying opcodes.
10  */
11
12 #ifndef NACL_TRUSTED_BUT_NOT_TCB
13 #error("This file is not meant for use in the TCB")
14 #endif
15
16 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_forms.h"
17
18 #include <assert.h>
19 #include <ctype.h>
20
21 #include "native_client/src/include/nacl_macros.h"
22 #include "native_client/src/include/portability_io.h"
23 #include "native_client/src/include/portability_string.h"
24 #include "native_client/src/include/nacl_macros.h"
25 #include "native_client/src/shared/platform/nacl_log.h"
26 #include "native_client/src/trusted/validator/x86/decoder/generator/defsize64.h"
27 #include "native_client/src/trusted/validator/x86/decoder/generator/lock_insts.h"
28 #include "native_client/src/trusted/validator/x86/decoder/generator/long_mode.h"
29 #include "native_client/src/trusted/validator/x86/decoder/generator/nacl_illegal.h"
30 #include "native_client/src/trusted/validator/x86/decoder/generator/nc_def_jumps.h"
31 #include "native_client/src/trusted/validator/x86/decoder/generator/nc_rep_prefix.h"
32 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_st.h"
33 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tablegen.h"
34 #include "native_client/src/trusted/validator/x86/decoder/generator/zero_extends.h"
35
36 /* To turn on debugging of instruction decoding, change value of
37  * DEBUGGING to 1.
38  */
39 #define DEBUGGING 0
40
41 #include "native_client/src/shared/utils/debugging.h"
42
43 /* Returns the name for the given enumerated value. */
44 static const char* NaClInstCatName(NaClInstCat cat) {
45   int i;
46   static struct {
47     NaClInstCat cat;
48     const char* name;
49   } cat_desc[] = {
50     { UnarySet , "UnarySet" },
51     { UnaryUpdate , "UnaryUpdate" },
52     { Move , "Move" },
53     { O2Move, "O2Move" },
54     { Binary , "Binary" },
55     { O2Binary , "O2Binary" },
56     { Nary , "Nary" },
57     { O1Nary, "O1Nary"},
58     { O3Nary, "O3Nary"},
59     { Compare , "Compare"},
60     { Exchange, "Exchange" },
61     { Push, "Push" },
62     { Pop, "Pop" },
63     { Call, "Call"},
64     { SysCall, "SysCall"},
65     { SysJump, "SysJump"},
66     { Return, "Return"},
67     { SysRet, "SysRet"},
68     { Jump, "Jump" },
69     { Uses, "Uses" },
70     { Sets, "Sets" },
71     { Lea, "Lea" },
72     { Cpuid, "Cpuid" },
73     { Other, "Other" },
74   };
75   for (i = 0; i < NACL_ARRAY_SIZE(cat_desc); ++i) {
76     if (cat == cat_desc[i].cat) return cat_desc[i].name;
77   }
78   /* Shouldn't be reached!! */
79   NaClFatal("Unrecognized category");
80   /* NOT REACHED */
81   return "Unspecified";
82 }
83
84 /* Returns the OpSet and OpUse operand flags for the destination
85  * argument of the instruction, given the category of instruction. Argument
86  * num_ops is the number of operands the instruction has.
87  */
88 static NaClOpFlags NaClGetArg1Flags(NaClInstCat icat, int num_ops) {
89   DEBUG(NaClLog(LOG_INFO, "NaClGetArg1Flags(%s)\n", NaClInstCatName(icat)));
90   switch (icat) {
91     case Move:
92     case O2Move:
93     case O1Nary:
94     case O3Nary:
95     case Lea:
96     case UnarySet:
97     case Sets:
98     case O2Binary:
99     case Jump:
100     case Return:
101     case SysRet:
102     case SysJump:
103     case Cpuid:
104       return NACL_OPFLAG(OpSet);
105     case Nary:
106     case Exchange:
107     case Call:
108     case SysCall:
109     case UnaryUpdate:
110     case Push:
111     case Pop:
112       return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
113     case Binary:
114       if (3 == num_ops) {
115         return NACL_OPFLAG(OpSet);
116       } else {
117         return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
118       }
119     case Compare:
120     case Uses:
121       return NACL_OPFLAG(OpUse);
122     case Other:
123       return NACL_EMPTY_OPFLAGS;
124       break;
125     default:
126       NaClFatal("NaClGetArg1Flags: unrecognized category");
127       /* NOT REACHED */
128       return NACL_EMPTY_OPFLAGS;
129   }
130 }
131
132 /* Returns the OpSet, OpUse, and OpDest operand flags for the source argument(s)
133  * of an instruction, given the category of instruction.
134  *
135  * Argument visible_index is the (1-based) index of the operand for which flags
136  * are being defined. A value of zero implies the argument is not visible.
137  *
138  * Argument op_index is the actual index of the operand in the
139  * instruction being modeled.
140  */
141 static NaClOpFlags NaClGetArg2PlusFlags(NaClInstCat icat,
142                                         int visible_index,
143                                         int op_index) {
144   DEBUG(NaClLog(LOG_INFO, "NaClGetArgsPlusFlags(%s, %d)\n",
145                 NaClInstCatName(icat), visible_index));
146   switch (icat) {
147     case UnarySet:
148     case UnaryUpdate:
149       NaClLog(LOG_INFO, "icat = %s\n", NaClInstCatName(icat));
150       NaClFatal("Illegal to use unary categorization for binary operation");
151       /* NOT REACHED */
152       return NACL_EMPTY_OPFLAGS;
153     case Call:
154     case Return:
155     case O2Binary:
156       if (2 == op_index) {
157         return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
158       } else {
159         return NACL_OPFLAG(OpUse);
160       }
161     case O3Nary:
162       if (op_index <= 3) {
163         return NACL_OPFLAG(OpSet);
164       } else {
165         return NACL_OPFLAG(OpUse);
166       }
167     case Move:
168     case Binary:
169     case Push:
170     case Jump:
171     case Uses:
172     case SysRet:
173     case Compare:
174     case Nary:
175     case O1Nary:
176       return NACL_OPFLAG(OpUse);
177     case O2Move:
178       if ((2 == op_index)) {
179         return NACL_OPFLAG(OpSet);
180       } else {
181         return NACL_OPFLAG(OpUse);
182       }
183     case Exchange:
184       if (op_index == 2) {
185         /* The second argument is always both a set and a use. */
186         if (visible_index == 2) {
187           return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
188         } else {
189           return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
190         }
191       } else if (op_index == 3) {
192         /* If it has a 3rd argument, it is like a cmpxchg. */
193         if (visible_index == 1) {
194           return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
195         } else {
196           return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
197         }
198       } else {
199         return NACL_OPFLAG(OpUse);
200       }
201     case Pop:
202     case SysCall:
203     case Sets:
204       return NACL_OPFLAG(OpSet);
205     case SysJump:
206       if (op_index <= 4) {
207         return NACL_OPFLAG(OpSet);
208       } else {
209         return NACL_OPFLAG(OpUse);
210       }
211     case Lea:
212     case Other:
213       return NACL_EMPTY_OPFLAGS;
214     case Cpuid:
215       if (op_index <= 2) {
216         return NACL_OPFLAG(OpSet);
217       } else {
218         return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
219       }
220     default:
221       NaClFatal("NaClGetArg2PlusFlags: unrecognized category");
222       /* NOT REACHED */
223       return NACL_EMPTY_OPFLAGS;
224   }
225 }
226
227 /* Returns the OpSet and OpUse operand flags for the operand
228  * with the given operand_index (1-based) argument for the instruction,
229  *
230  * Argument icat is the instruction category of the instruction being
231  * modeled.
232  *
233  * Argument visible_index is the (1-based) index of the operand for which flags
234  * are being defined. A value of zero implies the argument is not visible.
235  *
236  * Argument op_index is the actual index of the operand in the
237  * instruction being modeled.
238  *
239  * Argument num_ops is the number of operands the instruction has (base 1).
240  */
241 static NaClOpFlags NaClGetIcatFlags(NaClInstCat icat,
242                                     int operand_index,
243                                     int visible_count,
244                                     int num_ops) {
245   NaClOpFlags flags = NACL_EMPTY_OPFLAGS;
246   DEBUG(NaClLog(LOG_INFO, "NaClGetIcatFlags(%s, %d, %d)\n",
247                 NaClInstCatName(icat), operand_index, visible_count));
248   if (operand_index == 1) {
249     flags = NaClGetArg1Flags(icat, num_ops);
250   } else {
251     flags = NaClGetArg2PlusFlags(icat, visible_count, operand_index);
252   }
253   return flags;
254 }
255
256 /* Add miscellaneous flags defined elsewhere. */
257 static void NaClAddMiscellaneousFlags(void) {
258   DEBUG(NaClLog(LOG_INFO, "-> Adding Miscellaneous Flags\n"));
259   NaClAddZeroExtend32FlagIfApplicable();
260   NaClLockableFlagIfApplicable();
261   NaClAddSizeDefaultIs64();
262   NaClAddLongModeIfApplicable();
263   NaClAddNaClIllegalIfApplicable();
264   NaClAddRepPrefixFlagsIfApplicable();
265   NaClAddJumpFlagsIfApplicable();
266   DEBUG(NaClLog(LOG_INFO, "<- Adding Miscellaneous Flags\n"));
267 }
268
269 /* Adds OpSet/OpUse flags to operands to the current instruction,
270  * based on the given instruction categorization.
271  */
272 static void NaClSetInstCat(NaClInstCat icat) {
273   int operand_index = 0;  /* note: this is one-based. */
274   int visible_count = 0;
275   int i;
276   int num_ops;
277   NaClModeledInst* inst = NaClGetDefInst();
278   num_ops = inst->num_operands;
279   for (i = 0; i < num_ops; ++i) {
280     Bool is_visible = FALSE;
281     ++operand_index;
282     if (NACL_EMPTY_OPFLAGS ==
283         (inst->operands[i].flags & NACL_OPFLAG(OpImplicit))) {
284       is_visible = TRUE;
285       ++visible_count;
286     }
287     NaClAddOpFlags(i, NaClGetIcatFlags(
288         icat, operand_index, (is_visible ? visible_count : 0), num_ops));
289   }
290   /* Do special fixup for binary case with 3 arguments. In such
291    * cases, the first argument is only a set, rather than a set/use.
292    */
293   if ((Binary == icat) && (3 == num_ops)) {
294     NaClRemoveOpFlags(0, NACL_OPFLAG(OpUse));
295   }
296   NaClAddMiscellaneousFlags();
297 }
298
299 /* Returns true if opcode sequence value is a SL (slash)
300  * value.
301  */
302 static Bool IsSLValue(int16_t val) {
303   return val < 0;
304 }
305
306 /* Returns the opcode denoted by a SL (slash) value. */
307 static uint8_t SLOpcode(int16_t val) {
308   return (uint8_t) ((0 - val) - 1);
309 }
310
311 /* Returns true if any prefix byte values, which need
312  * to be considered part of the opcode sequence, is defined
313  * by the given instruction. If prefix byte(s) are matched,
314  * prefix_count is incremented by the number of bytes matched.
315  *
316  * Parameters are:
317  *   prefix_count - Variable to update on number of matched prefix
318  *      bytes.
319  *   inst - The instruction we are matching the opcode sequence against.
320  *   name_and_opcode_seq - The opcode sequence descriptor we are trying
321  *      to match.
322  */
323 static Bool NaClNameOpcodeSeqMatchesPrefixByte(
324     int* prefix_count,
325     NaClModeledInst* inst,
326     const NaClNameOpcodeSeq* name_and_opcode_seq,
327     int index) {
328   int16_t prefix;
329   switch (inst->prefix) {
330     case PrefixF20F:
331     case PrefixF20F38:
332       prefix = PR(0xF2);
333       break;
334     case PrefixF30F:
335       prefix = PR(0xF3);
336       break;
337     case Prefix660F:
338     case Prefix660F38:
339     case Prefix660F3A:
340       prefix = PR(0x66);
341       break;
342     default:
343       return TRUE;
344   }
345   if (prefix == name_and_opcode_seq[index].opcode_seq[0]) {
346     ++(*prefix_count);
347     return TRUE;
348   } else {
349     return FALSE;
350   }
351 }
352
353 Bool NaClInInstructionSet(const NaClMnemonic* names,
354                           size_t names_size,
355                           const NaClNameOpcodeSeq* name_and_opcode_seq,
356                           size_t name_and_opcode_seq_size) {
357   size_t i;
358   NaClModeledInst* inst = NaClGetDefInst();
359
360   /* First handle cases where all instances of an instruction
361    * mnemonic is in the set.
362    */
363   for (i = 0; i < names_size; ++i) {
364     if (inst->name == names[i]) {
365       return TRUE;
366     }
367   }
368
369   /* How handle cases where only a specific opcode sequence of
370    * an instruction mnemonic applies.
371    */
372   for (i = 0; i < name_and_opcode_seq_size; ++i) {
373     if (inst->name == name_and_opcode_seq[i].name) {
374       int j;
375       int prefix_count = 0;
376       Bool is_good = TRUE;
377       Bool matched_slash = FALSE;
378       /* First compare opcode bytes. */
379       if (NaClNameOpcodeSeqMatchesPrefixByte(
380               &prefix_count, inst, name_and_opcode_seq, (int) i)) {
381         for (j = 0; j < inst->num_opcode_bytes; ++j) {
382           if (inst->opcode[j] !=
383               name_and_opcode_seq[i].opcode_seq[prefix_count + j]) {
384             is_good = FALSE;
385             break;
386           }
387         }
388       } else {
389         is_good = FALSE;
390       }
391       if (is_good) {
392         /* Now compare any values that must by in modrm. */
393         for (j = prefix_count + inst->num_opcode_bytes;
394              j < NACL_OPCODE_SEQ_SIZE; ++j) {
395           int16_t val = name_and_opcode_seq[i].opcode_seq[j];
396           if (END_OPCODE_SEQ == val) {
397             /* At end of descriptor. See if instruction defines an opcode
398              * in the ModRm byte. If so, make sure that we matched the slash.
399              */
400             if (inst->flags & NACL_IFLAG(OpcodeInModRm)) {
401               return matched_slash;
402             } else {
403               /* At end of descriptor, matched! */
404               return TRUE;
405             }
406           }
407           if (IsSLValue(val)) {
408             if ((inst->flags & NACL_IFLAG(OpcodeInModRm)) &&
409                 (SLOpcode(val) == NaClGetOpcodeInModRm(inst->opcode_ext))) {
410               /* good, continue search. */
411               matched_slash = TRUE;
412             } else {
413               is_good = FALSE;
414               break;
415             }
416           }
417         }
418         if (is_good) {
419           return TRUE;
420         }
421       }
422     }
423   }
424   /* If reached, couldn't match, so not in instruction set. */
425   return FALSE;
426 }
427
428 static void NaClOperandForm_Ap(void) {
429   NaClDefOp(A_Operand, NACL_OPFLAG(OperandFar) | NACL_OPFLAG(OperandRelative));
430   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OpcodeHasImmed_p));
431 }
432
433 static void NaClOperandForm_CdSlq(void) {
434   /* Note: For Cd/q, we don't worry about the size of the
435    * control registers for NaCl. Hence, for now, we ignore the
436    * size constraint
437    */
438   NaClDefOp(C_Operand, NACL_EMPTY_OPFLAGS);
439 }
440
441 static void NaClOperandForm_DdSlq(void) {
442   /* Note: For Dd/q, we don't worry about the size of the
443    * debug register for NaCl. Hence, for now, we ignore the
444    * size constraint.
445    */
446   NaClDefOp(D_Operand, NACL_EMPTY_OPFLAGS);
447 }
448
449 static void NaClOperandForm_Eb(void) {
450   /* For Eb, we must worry about earlier arguments, which in some cases,
451    * have already specified valid effective operand sizes. If so, we must make
452    * the size of the this operand be byte specific. If size hasn't been
453    * specified yet, we go ahead and assume the effective operand size of the
454    * instructruction as being a byte.
455    */
456   NaClModeledInst* inst = NaClGetDefInst();
457   if (inst->flags & (NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
458                      NACL_IFLAG(OperandSize_o))) {
459     NaClDefOp(Eb_Operand, NACL_EMPTY_OPFLAGS);
460   } else {
461     NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
462     NaClAddIFlags(NACL_IFLAG(OperandSize_b));
463   }
464 }
465
466 static void NaClOperandForm_Ed(void) {
467   NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
468 }
469
470 static void NaClOperandForm_EdSlq(void) {
471   /* Note: For Ed/q we assume that only sizes d (32) and q (64) are possible.
472    * Hence, we don't allow a data 66 prefix effect the size.
473    */
474   NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
475   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
476                 NACL_IFLAG(SizeIgnoresData16));
477 }
478
479 static void NaClOperandForm_EdSlqSld(void) {
480   /* Ed/q/d is used for Ed/q when operand size is 32 bits (vs 64 bits).
481    * Note: For Ed/q we assume that only sizes d (32) and q (64) are possible.
482    * Hence, we don't allow a data 66 prefix effect the size.
483    */
484   NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
485   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(SizeIgnoresData16));
486 }
487
488 static void NaClOperandForm_EdSlqSlq(void) {
489   /* Ed/q/q is used for Ed/q when operand size is 64 bits (vs 32 bits).
490    * Note: For Ed/q we assume that only sizes d (32) and q (64) are possible.
491    * Hence, we don't allow a data 66 prefix effect the size.
492    */
493   NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
494   NaClAddIFlags(NACL_IFLAG(OperandSize_o) | NACL_IFLAG(SizeIgnoresData16));
495 }
496
497 static void NaClOperandForm_Ev(void) {
498   NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
499   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
500                 NACL_IFLAG(OperandSize_o));
501 }
502
503 static void NaClOperandForm_Ew(void) {
504   NaClDefOp(Ew_Operand, NACL_EMPTY_OPFLAGS);
505 }
506
507 static void NaClOperandForm_Fvw(void) {
508   NaClDefOp(RegRFLAGS, NACL_EMPTY_OPFLAGS);
509   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
510 }
511
512 static void NaClOperandForm_Fvd(void) {
513   NaClDefOp(RegRFLAGS, NACL_EMPTY_OPFLAGS);
514   NaClAddIFlags(NACL_IFLAG(OperandSize_v));
515 }
516
517 static void NaClOperandForm_Fvq(void) {
518   NaClDefOp(RegRFLAGS, NACL_EMPTY_OPFLAGS);
519   NaClAddIFlags(NACL_IFLAG(OperandSize_o));
520 }
521
522 static void NaClOperandForm_Gb(void) {
523   NaClDefOp(G_Operand, NACL_EMPTY_OPFLAGS);
524   NaClAddIFlags(NACL_IFLAG(OperandSize_b));
525 }
526
527 static void NaClOperandForm_Gd(void) {
528   NaClDefOp(Gv_Operand, NACL_EMPTY_OPFLAGS);
529 }
530
531 static void NaClOperandForm_GdQ(void) {
532   /* Note: For Gd/q we assume that only sizes d (32) and q (64) are possible.
533    * Hence, we don't allow a data 66 prefix effect the size.
534    */
535   NaClDefOp(G_Operand, NACL_EMPTY_OPFLAGS);
536   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
537                 NACL_IFLAG(SizeIgnoresData16));
538 }
539
540 static void NaClOperandForm_Gq(void) {
541   NaClDefOp(Go_Operand, NACL_EMPTY_OPFLAGS);
542 }
543
544 static void NaClOperandForm_Gv(void) {
545   NaClDefOp(G_Operand, NACL_EMPTY_OPFLAGS);
546   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
547                 NACL_IFLAG(OperandSize_o));
548 }
549
550 static void NaClOperandForm_Gw(void) {
551   NaClDefOp(Gw_Operand, NACL_EMPTY_OPFLAGS);
552 }
553
554 static void NaClOperandForm_Ib(void) {
555   int i;
556   NaClModeledInst* inst = NaClGetDefInst();
557   /* First look to see if 1st or 2nd instance of an immediate value,
558    * since different opcode flags that must be used are different.
559    */
560   for (i = 0; i < inst->num_operands; ++i) {
561     if (I_Operand == inst->operands[i].kind) {
562       /* Second instance!. */
563       NaClDefOp(I2_Operand, NACL_EMPTY_OPFLAGS);
564       NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed2_b));
565       return;
566     }
567   }
568   /* First instance of Ib. */
569   NaClDefOp(I_Operand, NACL_EMPTY_OPFLAGS);
570   if (inst->flags & NACL_IFLAG(OperandSize_b)) {
571     NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed));
572   } else {
573     NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_b));
574   }
575 }
576
577 static void NaClOperandForm_I2b(void) {
578   NaClDefOp(I2_Operand, NACL_EMPTY_OPFLAGS);
579   NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed2_b));
580 }
581
582 static void NaClOperandForm_Iv(void) {
583   NaClDefOp(I_Operand, NACL_EMPTY_OPFLAGS);
584   NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed) | NACL_IFLAG(OperandSize_w) |
585                 NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
586 }
587
588 static void NaClOperandForm_Iw(void) {
589   NaClDefOp(I_Operand, NACL_EMPTY_OPFLAGS);
590   NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_w));
591 }
592
593 static void NaClOperandForm_Iz(void) {
594   NaClDefOp(I_Operand, NACL_EMPTY_OPFLAGS);
595   NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_z));
596 }
597
598 static void NaClOperandForm_Jb(void) {
599   NaClDefOp(J_Operand,
600             NACL_OPFLAG(OperandRelative) | NACL_OPFLAG(OperandNear));
601   NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed) | NACL_IFLAG(OperandSize_b));
602 }
603
604 /* Installs Jz, except for size constraints. Assumes immediate value
605  * follows z (size) conventions, unless the argument implies to define
606  * immediate sizes based on v.
607  */
608 static void DefOperandJzBaseUseImmedV(Bool use_immed_v) {
609   NaClDefOp(J_Operand,
610             NACL_OPFLAG(OperandRelative) | NACL_OPFLAG(OperandNear));
611   if (use_immed_v) {
612     NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_v));
613   } else {
614     NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_z));
615   }
616 }
617
618 /* Installs Jz where immediate value is based on z size. */
619 static void DefOperandJzBase(void) {
620   /* Note: when in 32-bit mode, the relative offset can be a 16 or 32 bit
621    * immediate offset, depending on the operand size. When in 64-bit mode,
622    * the relative offset is ALWAYS a 32-bit immediate value (see page
623    * 76 for CALL of AMD manual (document 24594-Rev.3.14-September 2007,
624    * "AMD64 Architecture Programmer's manual Volume 3: General-Purpose
625    * and System Instructions").
626    */
627   DefOperandJzBaseUseImmedV(X86_64 == NACL_FLAGS_run_mode);
628 }
629
630 static void NaClOperandForm_Jz(void) {
631   DefOperandJzBase();
632   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
633                 NACL_IFLAG(OperandSize_o));
634 }
635
636 static void NaClOperandForm_Jzd(void) {
637   DefOperandJzBaseUseImmedV(TRUE);
638   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
639 }
640
641 static void NaClOperandForm_Jzw(void) {
642   DefOperandJzBase();
643   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
644   /* Note: Special case 64-bit with 66 prefix, which is not supported on
645    * some Intel Chips (See Call/Jcc instructions in Intel document
646    * 253666-030US - March 2009, "Intel 654 and IA-32 Architectures
647    * Software Developer's Manual, Volume2A").
648    */
649   if (X86_64 == NACL_FLAGS_run_mode) {
650     NaClAddIFlags(NACL_IFLAG(NaClIllegal));
651   }
652 }
653
654 static void NaClOperandForm_M(void) {
655   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
656   NaClAddIFlags(NACL_IFLAG(OpcodeAllowsData16));
657 }
658
659 static void NaClOperandForm_Ma(void) {
660   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
661   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
662   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v));
663 }
664
665 static void NaClOperandForm_Mb(void) {
666   NaClDefOp(Mb_Operand, NACL_EMPTY_OPFLAGS);
667 }
668
669 static void NaClOperandForm_Md(void) {
670   NaClDefOp(Mv_Operand, NACL_EMPTY_OPFLAGS);
671 }
672
673 static void NaClOperandForm_Mdq(void) {
674   NaClDefOp(Mdq_Operand, NACL_EMPTY_OPFLAGS);
675 }
676
677 static void NaClOperandForm_Mf(void) {
678   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
679 }
680
681 static void NaClOperandForm_MdSlq(void) {
682   /* Note: For Ed/q we assume that only sizes d (32) and q (64) are possible.
683    * Hence, we don't allow a data 66 prefix effect the size.
684    */
685   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
686   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
687                 NACL_IFLAG(SizeIgnoresData16));
688 }
689
690 static void NaClOperandForm_Mp(void) {
691   /* TODO(karl) fix measurement size. */
692   NaClDefOp(M_Operand, NACL_OPFLAG(OperandFar));
693 }
694
695 static void NaClOperandForm_Ms(void) {
696   /* TODO(karl): fix size of data accessed in memory. */
697   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
698 }
699
700 static void NaClOperandForm_Mq(void) {
701   NaClDefOp(Mo_Operand, NACL_EMPTY_OPFLAGS);
702 }
703
704 static void NaClOperandForm_Mv(void) {
705   NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
706   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
707                 NACL_IFLAG(OperandSize_o));
708 }
709
710 static void NaClOperandForm_Mw(void) {
711   NaClDefOp(Mw_Operand, NACL_EMPTY_OPFLAGS);
712 }
713
714 static void NaClOperandForm_MwSlRv(void) {
715   /* TODO(karl) Verify that Mw/Rv as same as Ev? */
716   NaClOperandForm_Ev();
717 }
718
719 static void NaClOperandForm_Ob(void) {
720   NaClDefOp(O_Operand, NACL_EMPTY_OPFLAGS);
721   NaClAddIFlags(NACL_IFLAG(OperandSize_b) | NACL_IFLAG(OpcodeHasImmed_Addr));
722 }
723
724 static void NaClOperandForm_Ov(void) {
725   NaClDefOp(O_Operand, NACL_EMPTY_OPFLAGS);
726   NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_Addr) | NACL_IFLAG(OperandSize_w) |
727                 NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
728 }
729
730
731 static void NaClOperandForm_One(void) {
732   NaClDefOp(Const_1, NACL_EMPTY_OPFLAGS);
733 }
734
735 static void NaClOperandForm_PdSlq(void) {
736   /* Note: For Pd/q we assume that only sizes d (32) and q (64) are possible.
737    * Hence, we don't allow a data 66 prefix effect the size.
738    */
739   NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
740   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
741                 NACL_IFLAG(SizeIgnoresData16));
742 }
743
744 static void NaClOperandForm_PdSlqSld(void) {
745   /* Pd/q/d is used for Pd/q when operand size is 32 bits (vs 64 bits).
746    * Note: For Pd/q we assume that only sizes d (32) and q (64) are possible.
747    * Hence, we don't allow a data 66 prefix effect the size.
748    */
749   NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
750   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(SizeIgnoresData16));
751 }
752
753 static void NaClOperandForm_PdSlqSlq(void) {
754   /* Pd/q/q is used for Pd/q when operand size is 64 bits (vs 32 bits).
755    * Note: For Pd/q we assume that only sizes d (32) and q (64) are possible.
756    * Hence, we don't allow a data 66 prefix effect the size.
757    */
758   NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
759   NaClAddIFlags(NACL_IFLAG(OperandSize_o) | NACL_IFLAG(SizeIgnoresData16));
760 }
761
762 static void NaClOperandForm_Pq(void) {
763   /* TODO(karl) Add q size restriction. */
764   NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
765 }
766
767 static void NaClOperandForm_PRq(void) {
768   /* Note: We ignore sizes for Mmx operands, since they
769    * aren't used to compute memory addresses in NaCl.
770    */
771   NaClDefOp(Mmx_N_Operand, NACL_EMPTY_OPFLAGS);
772 }
773
774 static void NaClOperandForm_Qd(void) {
775   /* TODO(karl) add d size restriction. */
776   NaClDefOp(Mmx_E_Operand, NACL_EMPTY_OPFLAGS);
777 }
778
779 static void NaClOperandForm_Qq(void) {
780   /* TODO(karl) add q size restriction. */
781   NaClDefOp(Mmx_E_Operand, NACL_EMPTY_OPFLAGS);
782 }
783
784 static void NaClOperandForm_Rd(void) {
785   NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
786   NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
787 }
788
789 static void NaClOperandForm_Rq(void) {
790   NaClDefOp(Eo_Operand, NACL_EMPTY_OPFLAGS);
791   NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
792 }
793
794 static void NaClOperandForm_RdSlMb(void) {
795   /* Note: For Rd/Mb, we ignore the size on memory,
796    * since we don't need to specify sizes on memory.
797    */
798   NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
799 }
800
801 static void NaClOperandForm_RdSlMw(void) {
802   /* Note: For Rd/Mw, we ignore the size on memory,
803    * since we don't need to specify sizes on memory for NaCl.
804    */
805   NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
806 }
807
808 static void NaClOperandForm_RdSlq(void) {
809   /* Note: It appears that Rd/q opcodes are connected to
810    * the architecture size, and only have one choice based
811    * on that size.
812    */
813   if (X86_32 == NACL_FLAGS_run_mode) {
814     NaClOperandForm_Rd();
815   } else {
816     NaClOperandForm_Rq();
817   }
818 }
819
820 static void NaClOperandForm_RdSlqSlMb(void) {
821   /* Note: For Rd/q/Mb, we ignore the size on memory,
822    * since we don't need to specify sizes on memory for NaCl.
823    */
824   NaClOperandForm_EdSlq();
825 }
826
827 static void NaClOperandForm_RdSlqSlMw(void) {
828   /* Note: For Rd/q/Mw, we ignore the size on memory,
829    * since we don't need to specify sizes on memory for NaCl.
830    */
831   NaClOperandForm_EdSlq();
832 }
833
834 static void NaClOperandForm_rAXv(void) {
835   NaClDefOp(RegREAX, NACL_EMPTY_OPFLAGS);
836   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
837                 NACL_IFLAG(OperandSize_o));
838 }
839
840 static void NaClOperandForm_rAXva(void) {
841   NaClDefOp(RegREAXa, NACL_EMPTY_OPFLAGS);
842 }
843
844 static void NaClOperandForm_rAXvd(void) {
845   NaClDefOp(RegEAX, NACL_EMPTY_OPFLAGS);
846   NaClAddIFlags(NACL_IFLAG(OperandSize_v));
847 }
848
849 static void NaClOperandForm_rAXvq(void) {
850   NaClDefOp(RegRAX, NACL_EMPTY_OPFLAGS);
851   NaClAddIFlags(NACL_IFLAG(OperandSize_o));
852 }
853
854 static void NaClOperandForm_rAXvw(void) {
855   NaClDefOp(RegAX, NACL_EMPTY_OPFLAGS);
856   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
857 }
858
859 static void NaClOperandForm_rBXv(void) {
860   NaClDefOp(RegREBX, NACL_EMPTY_OPFLAGS);
861   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
862                 NACL_IFLAG(OperandSize_o));
863 }
864
865 static void NaClOperandForm_rCXv(void) {
866   NaClDefOp(RegRECX, NACL_EMPTY_OPFLAGS);
867   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
868                 NACL_IFLAG(OperandSize_o));
869 }
870
871 static void NaClOperandForm_rDXv(void) {
872   NaClDefOp(RegREDX, NACL_EMPTY_OPFLAGS);
873   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
874                 NACL_IFLAG(OperandSize_o));
875 }
876
877 static void NaClOperandForm_rSPv(void) {
878   NaClDefOp(RegRESP, NACL_EMPTY_OPFLAGS);
879   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
880                 NACL_IFLAG(OperandSize_o));
881 }
882
883 static void NaClOperandForm_rBPv(void) {
884   NaClDefOp(RegREBP, NACL_EMPTY_OPFLAGS);
885   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
886                 NACL_IFLAG(OperandSize_o));
887 }
888
889 static void NaClOperandForm_rSIv(void) {
890   NaClDefOp(RegRESI, NACL_EMPTY_OPFLAGS);
891   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
892                 NACL_IFLAG(OperandSize_o));
893 }
894
895 static void NaClOperandForm_rDIv(void) {
896   NaClDefOp(RegREDI, NACL_EMPTY_OPFLAGS);
897   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
898                 NACL_IFLAG(OperandSize_o));
899 }
900
901 /* Note: The interpretation for r8b is documented in ncdecode_forms.h. That is,
902  *   r8 - The 8 registers AL, CL, DL, BL, AH, CH, DH, and BH if no REX prefix.
903  *        with A REX prefix, use the registers AL, CL, DL, BL, SPL, BPL, SIL,
904  *        DIL, and the optional registers r8-r15 if REX.b is set. Register
905  *        choice is based on the register value embedded in the opcode.
906  */
907 static void NaClOperandForm_r8b(void) {
908   NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
909   NaClAddIFlags(NACL_IFLAG(OperandSize_b));
910 }
911
912 /* Note: The interpretation for r8v is documented in ncdecode_forms.h. That is,
913  *   r8 - The 8 registers rAX, rCX, rDX, rBX, rSP, rBP, rSI, rDI, and the
914  *        optional registers r8-r15 if REX.b is set, based on the register value
915  *        embedded in the opcode.
916  */
917 static void NaClOperandForm_r8v(void) {
918   NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
919   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
920                 NACL_IFLAG(OperandSize_o));
921 }
922
923 /* Note: The interpretation for r8vd is documented in ncdecode_forms.h. That is,
924  *   r8 - The 8 registers rAX, rCX, rDX, rBX, rSP, rBP, rSI, rDI, and the
925  *        optional registers r8-r15 if REX.b is set, based on the register value
926  *        embedded in the opcode
927  *   vd - A doubleword only when the effective operand size matches.
928  */
929 static void NaClOperandForm_r8vd(void) {
930   NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
931   NaClAddIFlags(NACL_IFLAG(OperandSize_v));
932 }
933
934 /* Note: The interpretation for r8vq is documented in ncdecode_forms.h. That is,
935  *   r8 - The 8 registers rAX, rCX, rDX, rBX, rSP, rBP, rSI, rDI, and the
936  *        optional registers r8-r15 if REX.b is set, based on the register value
937  *        embedded in the opcode.
938  *   vq - A quadword only when the effective operand size matches.
939  */
940 static void NaClOperandForm_r8vq(void) {
941   NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
942   NaClAddIFlags(NACL_IFLAG(OperandSize_o));
943 }
944
945 static void NaClOperandForm_SGz(void) {
946   NaClDefOp(Seg_G_Operand, NACL_EMPTY_OPFLAGS);
947   NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
948                 NACL_IFLAG(OperandSize_o));
949 }
950
951 static void NaClOperandForm_Sw(void) {
952   NaClDefOp(S_Operand, NACL_EMPTY_OPFLAGS);
953   NaClAddIFlags(NACL_IFLAG(ModRmRegSOperand));
954 }
955
956 static void NaClOperandForm_Udq(void) {
957   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
958 }
959
960 static void NaClOperandForm_UdqMd(void) {
961   /* TODO: how to define size, based on register (Udq) or
962    * memory (Md).
963    */
964   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
965 }
966
967 static void NaClOperandForm_UdqMq(void) {
968   /* TODO: how to define size, based on register (Udq) or
969    * memory (Mq).
970    */
971   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
972 }
973
974 static void NaClOperandForm_UdqMw(void) {
975   /* TODO: how to define size, based on register (Udq) or
976    * memory (Mw).
977    */
978   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
979 }
980
981 static void NaClOperandForm_Vdq(void) {
982   /* TODO(karl) Add dq size restriction. */
983   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
984 }
985
986 static void NaClOperandForm_VdSlq(void) {
987   /* Note: For Vd/q we assume that only sizes d (32) and q (64) are possible.
988    * Hence, we don't allow a data 66 prefix effect the size.
989    */
990   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
991   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
992                 NACL_IFLAG(SizeIgnoresData16));
993 }
994
995 static void NaClOperandForm_VdSlqSld(void) {
996   /* Vd/q/d is used for Vd/q when operand size is 32 bits (vs 64 bits).
997    * Note: For Vd/q we assume that only sizes d (32) and q (64) are possible.
998    * Hence, we don't allow a data 66 prefix effect the size.
999    */
1000   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1001   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(SizeIgnoresData16));
1002 }
1003
1004 static void NaClOperandForm_VdSlqSlq(void) {
1005   /* Vd/q/q is used for Vd/q when operand size is 64 bits (vs 32 bits).
1006    * Note: For Vd/q we assume that only sizes d (32) and q (64) are possible.
1007    * Hence, we don't allow a data 66 prefix effect the size.
1008    */
1009   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1010   NaClAddIFlags(NACL_IFLAG(OperandSize_o) | NACL_IFLAG(SizeIgnoresData16));
1011 }
1012
1013 static void NaClOperandForm_Vpd(void) {
1014   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1015 }
1016
1017 static void NaClOperandForm_Vps(void) {
1018   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1019 }
1020
1021 static void NaClOperandForm_Vq(void) {
1022   NaClDefOp(Xmm_Go_Operand, NACL_EMPTY_OPFLAGS);
1023 }
1024
1025 static void NaClOperandForm_Vsd(void) {
1026   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1027 }
1028
1029 static void NaClOperandForm_Vss(void) {
1030   NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1031 }
1032
1033 static void NaClOperandForm_VRdq(void) {
1034   /* Note: We ignore sizes for Mmx operands, since they
1035    * aren't used to compute memory addresses in NaCl.
1036    */
1037   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1038   NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
1039 }
1040
1041 static void NaClOperandForm_VRps(void) {
1042   /* Note: We ignore sizes for Xmm operands, since they
1043    * aren't used to compute memory addresses in NaCl.
1044    */
1045   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1046   NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
1047 }
1048
1049 static void NaClOperandForm_VRq(void) {
1050   /* Note: We ignore sizes for Xmm operands, since they
1051    * aren't used to compute memory addresses in NaCl.
1052    */
1053   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1054   NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
1055 }
1056
1057 static void NaClOperandForm_VRpd(void) {
1058   /* Note: We ignore sizes for Xmm operands, since they
1059    * aren't used to compute memory addresses in NaCl.
1060    */
1061   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1062   NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
1063 }
1064
1065 static void NaClOperandForm_Wdq(void) {
1066   /* TODO(karl) Add dq size restriction. */
1067   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1068 }
1069
1070 static void NaClOperandForm_Wpd(void) {
1071   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1072 }
1073
1074 static void NaClOperandForm_Wps(void) {
1075   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1076 }
1077
1078 static void NaClOperandForm_Wq(void) {
1079   /* TODO(karl) Add q size restriction. */
1080   NaClDefOp(Xmm_Eo_Operand, NACL_EMPTY_OPFLAGS);
1081 }
1082
1083 static void NaClOperandForm_Wsd(void) {
1084   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1085 }
1086
1087 static void NaClOperandForm_Wss(void) {
1088   NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1089 }
1090
1091 static void NaClOperandForm_Xb(void) {
1092   NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1093   NaClAddIFlags(NACL_IFLAG(OperandSize_b));
1094 }
1095
1096 static void NaClOperandForm_Xvw(void) {
1097   NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1098   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1099 }
1100
1101 static void NaClOperandForm_Xvd(void) {
1102   NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1103   NaClAddIFlags(NACL_IFLAG(OperandSize_v));
1104 }
1105
1106 static void NaClOperandForm_Xvq(void) {
1107   NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1108   NaClAddIFlags(NACL_IFLAG(OperandSize_o));
1109 }
1110
1111 static void NaClOperandForm_Xzd(void) {
1112   NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1113   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
1114 }
1115
1116 static void NaClOperandForm_Xzw(void) {
1117   NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1118   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1119 }
1120
1121 static void NaClOperandForm_Yb(void) {
1122   NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1123   NaClAddIFlags(NACL_IFLAG(OperandSize_b));
1124 }
1125
1126 static void NaClOperandForm_Yvd(void) {
1127   NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1128   NaClAddIFlags(NACL_IFLAG(OperandSize_v));
1129 }
1130
1131 static void NaClOperandForm_Yvq(void) {
1132   NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1133   NaClAddIFlags(NACL_IFLAG(OperandSize_o));
1134 }
1135
1136 static void NaClOperandForm_Yvw(void) {
1137   NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1138   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1139 }
1140
1141 static void NaClOperandForm_Yzw(void) {
1142   NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1143   NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1144 }
1145
1146 static void NaClOperandForm_Yzd(void) {
1147   NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1148   NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
1149 }
1150
1151 static void NaClOperandForm_Zvd(void) {
1152   NaClDefOp(RegDS_EDI, NACL_EMPTY_OPFLAGS);
1153   NaClAddIFlags(NACL_IFLAG(OperandSize_v));
1154 }
1155
1156 /**************************************************************************
1157  * The following code is code that takes a opcode description string, and *
1158  * generates the corresponding instruction                                *
1159  *                                                                        *
1160  * TODO(karl) Remove macro implementations once we have moved to this new *
1161  * implementation.                                                        *
1162  *************************************************************************/
1163
1164 /* Define the (maximum) size that working buffers, for the translation code. */
1165 #define BUFSIZE 256
1166
1167 /* Define the maximum number of operands that can appear in an opcode
1168  * description string.
1169  */
1170 #define MAX_OPERANDS 10
1171
1172 #define MAX_DEFOPS 1000
1173
1174 #define BUF_SIZE 1024
1175
1176 /* The maximum number of symbol substitutions that can be applied to an
1177  * opcode description string. Used mainly to make sure that if a
1178  * substitution occurs, the code will not looop infinitely.
1179  */
1180 #define MAX_ST_SUBSTITUTIONS 100
1181
1182 /* The current opcode string description being translated. Mainly used
1183  * to generate useful error messages.
1184  */
1185 static char* kCachedDesc = "???";
1186
1187 /* The set of possible characters that can follow a symbol when doing
1188  * symbol substitution.
1189  */
1190 static const char* kSymbolTerminators = " :+/{},@";
1191
1192 /* Generates a fatal error message for the given opcode description string. */
1193 static void NaClDefDescFatal(const char* desc, const char* message) {
1194   NaClLog(LOG_FATAL, "NaClDefine '%s': %s\n", desc, message);
1195 }
1196
1197 /* Generates a fatal error message for the cached opcode description string. */
1198 static void NaClDefFatal(const char* message) {
1199   NaClDefDescFatal(kCachedDesc, message);
1200 }
1201
1202 /* replace all occurrences of "@NAME" with the corresponding
1203  * value in the given symbol table.
1204  *
1205  * NOTE: only MAX_ST_SUBSTITUTIONS are allowed, to make sure
1206  * that we don't infinite loop.
1207  */
1208 static void NaClStExpand(char* desc, struct NaClSymbolTable* st) {
1209   const char* marker;
1210   int attempts_left = MAX_ST_SUBSTITUTIONS;
1211   if (NULL == st) return;
1212   for (marker = strchr(desc, '@');
1213        (NULL != marker) && attempts_left;
1214        marker = strchr(desc, '@')) {
1215     char name[BUFSIZE];
1216     size_t name_len = 0;
1217     /* Extract name */
1218     const char *ch_ptr = marker+1;
1219     while (*ch_ptr && (NULL == strchr(kSymbolTerminators, *ch_ptr))) {
1220       name[name_len++] = *(ch_ptr++);
1221     }
1222     name[name_len] = '\0';
1223     if (name_len) {
1224       /* Get corresponding symbol table value. */
1225       NaClStValue* val = NaClSymbolTableGet(name, st);
1226       if (NULL != val) {
1227         /* Substitute and update desc. */
1228         char buffer[BUFSIZE];
1229         char* buffer_ptr = buffer;
1230         const char* desc_ptr = desc;
1231         char v_buffer[BUFSIZE];
1232         const char* v_buffer_ptr = v_buffer;
1233         /* Copy text before @name. */
1234         while (desc_ptr != marker) {
1235           *(buffer_ptr++) = *(desc_ptr++);
1236         }
1237         /* Do substitution of symbol value. */
1238         switch (val->kind) {
1239           case nacl_byte:
1240             SNPRINTF(v_buffer, BUFSIZE, "%02"NACL_PRIx8, val->value.byte_value);
1241             break;
1242           case nacl_text:
1243             v_buffer_ptr = val->value.text_value;
1244             break;
1245           case nacl_int:
1246             SNPRINTF(v_buffer, BUFSIZE, "%d", val->value.int_value);
1247             break;
1248           default:
1249             NaClDefDescFatal(desc, "Unable to expand @ variable");
1250             break;
1251         }
1252         while (*v_buffer_ptr) {
1253           *(buffer_ptr++) = *(v_buffer_ptr++);
1254         }
1255         /* copy text after @name. */
1256         desc_ptr = ch_ptr;
1257         while (*desc_ptr) {
1258           *(buffer_ptr++) = *(desc_ptr++);
1259         }
1260         *buffer_ptr = '\0';
1261         strcpy(desc, buffer);
1262         --attempts_left;
1263         continue;
1264       }
1265     }
1266     /* If reached, unable to do substitution, stop. */
1267     break;
1268   }
1269 }
1270
1271 /* Verify argument is a string describing a sequence of byte,
1272  * i.e. pairs of hex values (with no space inbetween), describing
1273  * the opcode base of an instruction.
1274  */
1275 static void NaClVerifyByteBaseAssumptions(const char* byte) {
1276   size_t len = strlen(byte);
1277   if ((len < 2) || (len % 2)) {
1278     NaClDefFatal("opcode (hex) base length must be divisible by 2");
1279   }
1280   if (len != strspn(byte, "0123456789aAbBcCdDeEfF")) {
1281     NaClDefFatal("opcode base not hex value");
1282   }
1283 }
1284
1285 /* Given a pointer to a string describing a byte using hexidecimal values,
1286  * extract the corresponding byte value.
1287  *
1288  * Note: Assumes that the length of base is 2.
1289  */
1290 static uint8_t NaClExtractByte(const char* base) {
1291   return (uint8_t) STRTOULL(base + strlen(base) - 2, NULL, 16);
1292 }
1293
1294 /* Given a string of bytes describing a prefix, return the
1295  * corresponding enumerated prefix value.
1296  */
1297 static NaClInstPrefix NaClExtractPrefixValue(const char* prefix_name,
1298                                              size_t prefix_size) {
1299   if (prefix_size == 0) {
1300     return NoPrefix;
1301   } else {
1302     size_t i;
1303     NaClInstPrefix prefix;
1304     char prefix_text[BUFSIZE];
1305     char* text_ptr;
1306     strcpy(prefix_text, "Prefix");
1307     text_ptr = prefix_text + strlen("Prefix");
1308     for (i = 0; i < prefix_size; ++i) {
1309       text_ptr[i] = toupper(prefix_name[i]);
1310     }
1311     text_ptr[prefix_size] = '\0';
1312     for (prefix = 0; prefix < NaClInstPrefixEnumSize; ++prefix) {
1313       if (0 == strcmp(NaClInstPrefixName(prefix), prefix_text)) {
1314         return prefix;
1315       }
1316     }
1317   }
1318   NaClDefFatal("Opcode prefix not understood");
1319   /* NOT REACHED */
1320   return NaClInstPrefixEnumSize;
1321 }
1322
1323 /* Given a string of byte values, describing the opcode base
1324  * of an instruction, extract out the corresponding opcode
1325  * prefix (i.e. the prefix defined by all but the last byte in
1326  * the opcode base.
1327  *
1328  * Note: Assumes that NaClVerifyByteBaseAssumptions was called
1329  * on the given parameter.
1330  */
1331 static NaClInstPrefix NaClExtractPrefix(const char* base) {
1332   size_t len = strlen(base);
1333   if (len >= 2) {
1334     return NaClExtractPrefixValue(base, len - 2);
1335   }
1336   NaClDefFatal("Opcode prefix not understood");
1337   /* NOT REACHED */
1338   return NaClInstPrefixEnumSize;
1339 }
1340
1341 static void NaClVerifyOctalDigit(const char* str, const char* message) {
1342   if ((1 != strlen(str)) || (1 != strspn(str, "01234567"))) {
1343     NaClDefFatal(message);
1344   }
1345 }
1346
1347 /*
1348  * Given a string describing an opcode, the type of the
1349  * instruction, and the mnemonic associated with the instruction,
1350  * parse the opcode string and define the corresponding instruction.
1351  *
1352  * Note: See ??? for descriptions of legal opcode strings.
1353  */
1354 static void NaClParseOpcode(const char* opcode,
1355                             NaClInstType insttype,
1356                             NaClMnemonic name,
1357                             struct NaClSymbolTable* st) {
1358   char buf[BUFSIZE];
1359   char* marker;
1360   char* buffer = buf;
1361   char* base;
1362   char* reg_offset = NULL;
1363   char* opcode_ext = NULL;
1364   char* opcode_3d_ext = NULL;
1365   char* opcode_rm_ext = NULL;
1366   NaClInstPrefix prefix;
1367   uint8_t opcode_value;
1368   Bool is_inst_defined = FALSE;
1369   strcpy(buf, opcode);
1370
1371   /* Remove leading whitespace. */
1372   while(' ' == *buffer) ++buffer;
1373   base = buffer;
1374
1375   /* Start by finding any valid suffix (i.e. +X or /X), and remove.
1376    * Put the corresponding suffix into reg_offset(+), or opcode_ext(/).
1377    */
1378   /* Try to recognize an opcode extension. */
1379   marker = strchr(buffer, '/');
1380   if (NULL != marker) {
1381     *marker = '\0';
1382     opcode_ext = buffer + strlen(base) + 1;
1383     marker = strchr(opcode_ext, '/');
1384     if (NULL != marker) {
1385       *marker = '\0';
1386       opcode_rm_ext = opcode_ext + strlen(opcode_ext) + 1;
1387       if (strlen(opcode_rm_ext) != 1) {
1388         NaClDefFatal("modrm r/m opcode extension can only be "
1389                      "a single digit");
1390       }
1391     }
1392     if (strlen(opcode_ext) != 1) {
1393       NaClDefFatal("modrm opcode extension can only be a single digit");
1394     }
1395   } else {
1396     /* Try to recognize a 3dnow extension. */
1397     marker = strchr(buffer, '.');
1398     if ((NULL != marker) && (0 == strncmp(marker, "..", 2))) {
1399       *marker = '\0';
1400       opcode_3d_ext = marker + 2;
1401     }
1402   }
1403
1404   marker = strchr(buffer, '+');
1405   if (NULL != marker) {
1406     *marker = '\0';
1407     reg_offset = buffer + strlen(base) + 1;
1408   }
1409
1410   /* Now verify the opcode string, less the suffix, is valid. If so,
1411    * Pull out the instruction prefix and opcode byte.
1412    */
1413   NaClVerifyByteBaseAssumptions(base);
1414   if (NULL == opcode_3d_ext) {
1415     prefix = NaClExtractPrefix(base);
1416   } else {
1417     prefix = NaClExtractPrefixValue(base, strlen(base));
1418   }
1419   NaClDefInstPrefix(prefix);
1420   opcode_value = NaClExtractByte(base + strlen(base) - 2);
1421
1422   if (reg_offset != NULL) {
1423     int reg = (int) STRTOULL(reg_offset, NULL, 10);
1424     if (reg < 0) {
1425       NaClDefFatal("can't add negative values to opcode");
1426     } else if ((reg + opcode_value) >= NCDTABLESIZE) {
1427       NaClDefFatal("opcode addition too large");
1428     }
1429     if (NULL == NaClSymbolTableGet("add_reg?", st)) {
1430       NaClVerifyOctalDigit(reg_offset, "invalid opcode register offset");
1431       NaClDefInst(opcode_value + reg, insttype, NACL_IFLAG(OpcodePlusR), name);
1432       NaClDefOpcodeRegisterValue(reg);
1433     }
1434     else {
1435       NaClDefInst(opcode_value + reg, insttype, NACL_EMPTY_IFLAGS, name);
1436     }
1437     is_inst_defined = TRUE;
1438   }
1439   if (opcode_ext != NULL) {
1440     if (0 == strcmp("r", opcode_ext)) {
1441       if (! is_inst_defined) {
1442         NaClDefInst(opcode_value, insttype, NACL_EMPTY_IFLAGS, name);
1443       }
1444       NaClAddIFlags(NACL_IFLAG(OpcodeUsesModRm));
1445     } else {
1446       int ext;
1447       NaClVerifyOctalDigit(opcode_ext, "invalid modrm opcode extension");
1448       ext = (int) STRTOULL(opcode_ext, NULL, 10);
1449       if (! is_inst_defined) {
1450         NaClDefInst(opcode_value, insttype, NACL_EMPTY_IFLAGS, name);
1451       }
1452       NaClAddIFlags(NACL_IFLAG(OpcodeInModRm));
1453       NaClDefOpcodeExtension(ext);
1454     }
1455     is_inst_defined = TRUE;
1456     if (opcode_rm_ext != NULL) {
1457       NaClVerifyOctalDigit(opcode_rm_ext, "invalid modrm r/m opcode extension");
1458       NaClDefineOpcodeModRmRmExtension((int) STRTOULL(opcode_rm_ext, NULL, 10));
1459     }
1460   }
1461   if (!is_inst_defined) {
1462     NaClIFlags flags = NACL_EMPTY_IFLAGS;
1463     if (opcode_3d_ext != NULL) {
1464       opcode_value = NaClExtractByte(opcode_3d_ext);
1465     }
1466     NaClDefInst(opcode_value, insttype, flags, name);
1467   }
1468 }
1469
1470 /* Given the text of a mnemonic, return the corresponding mnemonic. */
1471 static NaClMnemonic NaClAssemName(const char* name) {
1472   NaClMnemonic i;
1473   for (i = (NaClMnemonic) 0; i < NaClMnemonicEnumSize; ++i) {
1474     if (0 == strcmp(NaClMnemonicName(i), name)) {
1475       return i;
1476     }
1477   }
1478   NaClDefFatal("Can't find name for mnemonic");
1479  /* NOT REACHED */
1480   return NaClMnemonicEnumSize;
1481 }
1482
1483 /* Given the name of a register, define the corresponding operand on
1484  * the instruction being defined.
1485  */
1486 static void NaClExtractRegister(const char* reg_name) {
1487   char buffer[BUFSIZE];
1488   char* buf_ptr = buffer;
1489   char* reg_ptr = (char*) reg_name;
1490   NaClOpKind kind;
1491   strcpy(buf_ptr, "Reg");
1492   buf_ptr += strlen("Reg");
1493   while (*reg_ptr) {
1494     char ch = *(reg_ptr++);
1495     *(buf_ptr++) = toupper(ch);
1496   }
1497   *buf_ptr = '\0';
1498   for (kind = 0; kind < NaClOpKindEnumSize; ++kind) {
1499     if (0 == strcmp(NaClOpKindName(kind), buffer)) {
1500       NaClDefOp(kind, NACL_EMPTY_OPFLAGS);
1501       return;
1502     }
1503   }
1504   NaClDefFatal("Unable to find register");
1505 }
1506
1507 /* Helper function to add a define operand function into
1508  * a symbol table.
1509  */
1510 static void NaClSymbolTablePutDefOp(const char* name,
1511                                     NaClDefOperand defop,
1512                                     struct NaClSymbolTable* st) {
1513   NaClStValue value;
1514   value.kind = nacl_defop;
1515   value.value.defop_value = defop;
1516   NaClSymbolTablePut(name, &value, st);
1517 }
1518
1519 /* Given the name describing legal values for an operand,
1520  * call the corresponding function to define the corresponding
1521  * operand.
1522  */
1523 static void NaClExtractOperandForm(const char* form) {
1524   static struct NaClSymbolTable* defop_st = NULL;
1525   NaClStValue* value;
1526   if (NULL == defop_st) {
1527     defop_st = NaClSymbolTableCreate(MAX_DEFOPS, NULL);
1528     NaClSymbolTablePutDefOp("Ap",      NaClOperandForm_Ap,        defop_st);
1529     NaClSymbolTablePutDefOp("Cd/q",    NaClOperandForm_CdSlq,     defop_st);
1530     NaClSymbolTablePutDefOp("Dd/q",    NaClOperandForm_DdSlq,     defop_st);
1531     NaClSymbolTablePutDefOp("Eb",      NaClOperandForm_Eb,        defop_st);
1532     NaClSymbolTablePutDefOp("Ed",      NaClOperandForm_Ed,        defop_st);
1533     NaClSymbolTablePutDefOp("Ed/q",    NaClOperandForm_EdSlq,     defop_st);
1534     NaClSymbolTablePutDefOp("Ed/q/d",  NaClOperandForm_EdSlqSld,  defop_st);
1535     NaClSymbolTablePutDefOp("Ed/q/q",  NaClOperandForm_EdSlqSlq,  defop_st);
1536     NaClSymbolTablePutDefOp("Ev",      NaClOperandForm_Ev,        defop_st);
1537     NaClSymbolTablePutDefOp("Ew",      NaClOperandForm_Ew,        defop_st);
1538     NaClSymbolTablePutDefOp("Fvd",     NaClOperandForm_Fvd,       defop_st);
1539     NaClSymbolTablePutDefOp("Fvq",     NaClOperandForm_Fvq,       defop_st);
1540     NaClSymbolTablePutDefOp("Fvw",     NaClOperandForm_Fvw,       defop_st);
1541     NaClSymbolTablePutDefOp("Gb",      NaClOperandForm_Gb,        defop_st);
1542     NaClSymbolTablePutDefOp("Gd",      NaClOperandForm_Gd,        defop_st);
1543     NaClSymbolTablePutDefOp("Gd/q",    NaClOperandForm_GdQ,       defop_st);
1544     NaClSymbolTablePutDefOp("Gq",      NaClOperandForm_Gq,        defop_st);
1545     NaClSymbolTablePutDefOp("Gv",      NaClOperandForm_Gv,        defop_st);
1546     NaClSymbolTablePutDefOp("Gw",      NaClOperandForm_Gw,        defop_st);
1547     NaClSymbolTablePutDefOp("Gw",      NaClOperandForm_Gw,        defop_st);
1548     NaClSymbolTablePutDefOp("Ib",      NaClOperandForm_Ib,        defop_st);
1549     NaClSymbolTablePutDefOp("Iv",      NaClOperandForm_Iv,        defop_st);
1550     NaClSymbolTablePutDefOp("Iw",      NaClOperandForm_Iw,        defop_st);
1551     NaClSymbolTablePutDefOp("Iz",      NaClOperandForm_Iz,        defop_st);
1552     NaClSymbolTablePutDefOp("I2b",     NaClOperandForm_I2b,       defop_st);
1553     NaClSymbolTablePutDefOp("Jb",      NaClOperandForm_Jb,        defop_st);
1554     NaClSymbolTablePutDefOp("Jz",      NaClOperandForm_Jz,        defop_st);
1555     NaClSymbolTablePutDefOp("Jzd",     NaClOperandForm_Jzd,       defop_st);
1556     NaClSymbolTablePutDefOp("Jzw",     NaClOperandForm_Jzw,       defop_st);
1557     NaClSymbolTablePutDefOp("M",       NaClOperandForm_M,         defop_st);
1558     NaClSymbolTablePutDefOp("Ma",      NaClOperandForm_Ma,        defop_st);
1559     NaClSymbolTablePutDefOp("Mb",      NaClOperandForm_Mb,        defop_st);
1560     NaClSymbolTablePutDefOp("Md",      NaClOperandForm_Md,        defop_st);
1561     NaClSymbolTablePutDefOp("Md/q",    NaClOperandForm_MdSlq,     defop_st);
1562     NaClSymbolTablePutDefOp("Mdq",     NaClOperandForm_Mdq,       defop_st);
1563     NaClSymbolTablePutDefOp("Mf",      NaClOperandForm_Mf,        defop_st);
1564     NaClSymbolTablePutDefOp("Mp",      NaClOperandForm_Mp,        defop_st);
1565     NaClSymbolTablePutDefOp("Mq",      NaClOperandForm_Mq,        defop_st);
1566     NaClSymbolTablePutDefOp("Ms",      NaClOperandForm_Ms,        defop_st);
1567     NaClSymbolTablePutDefOp("Mv",      NaClOperandForm_Mv,        defop_st);
1568     NaClSymbolTablePutDefOp("Mw/Rv",   NaClOperandForm_MwSlRv,    defop_st);
1569     NaClSymbolTablePutDefOp("Mw",      NaClOperandForm_Mw,        defop_st);
1570     NaClSymbolTablePutDefOp("Ob",      NaClOperandForm_Ob,        defop_st);
1571     NaClSymbolTablePutDefOp("Ov",      NaClOperandForm_Ov,        defop_st);
1572     NaClSymbolTablePutDefOp("Pd/q",    NaClOperandForm_PdSlq,     defop_st);
1573     NaClSymbolTablePutDefOp("Pd/q/d",  NaClOperandForm_PdSlqSld,  defop_st);
1574     NaClSymbolTablePutDefOp("Pd/q/q",  NaClOperandForm_PdSlqSlq,  defop_st);
1575     NaClSymbolTablePutDefOp("Pq",      NaClOperandForm_Pq,        defop_st);
1576     NaClSymbolTablePutDefOp("PRq",     NaClOperandForm_PRq,       defop_st);
1577     NaClSymbolTablePutDefOp("Qd",      NaClOperandForm_Qd,        defop_st);
1578     NaClSymbolTablePutDefOp("Qq",      NaClOperandForm_Qq,        defop_st);
1579     NaClSymbolTablePutDefOp("Rd/q",    NaClOperandForm_RdSlq,     defop_st);
1580     NaClSymbolTablePutDefOp("Rd/q/Mb", NaClOperandForm_RdSlqSlMb, defop_st);
1581     NaClSymbolTablePutDefOp("Rd/q/Mw", NaClOperandForm_RdSlqSlMw, defop_st);
1582     NaClSymbolTablePutDefOp("Rd/Mb",   NaClOperandForm_RdSlMb,    defop_st);
1583     NaClSymbolTablePutDefOp("Rd/Mw",   NaClOperandForm_RdSlMw,    defop_st);
1584     NaClSymbolTablePutDefOp("rAXv",    NaClOperandForm_rAXv,      defop_st);
1585     NaClSymbolTablePutDefOp("rAXva",   NaClOperandForm_rAXva,     defop_st);
1586     NaClSymbolTablePutDefOp("rAXvd",   NaClOperandForm_rAXvd,     defop_st);
1587     NaClSymbolTablePutDefOp("rAXvq",   NaClOperandForm_rAXvq,     defop_st);
1588     NaClSymbolTablePutDefOp("rAXvw",   NaClOperandForm_rAXvw,     defop_st);
1589     NaClSymbolTablePutDefOp("rBXv",    NaClOperandForm_rBXv,      defop_st);
1590     NaClSymbolTablePutDefOp("rCXv",    NaClOperandForm_rCXv,      defop_st);
1591     NaClSymbolTablePutDefOp("rDXv",    NaClOperandForm_rDXv,      defop_st);
1592     NaClSymbolTablePutDefOp("rSPv",    NaClOperandForm_rSPv,      defop_st);
1593     NaClSymbolTablePutDefOp("rBPv",    NaClOperandForm_rBPv,      defop_st);
1594     NaClSymbolTablePutDefOp("rSIv",    NaClOperandForm_rSIv,      defop_st);
1595     NaClSymbolTablePutDefOp("rDIv",    NaClOperandForm_rDIv,      defop_st);
1596     NaClSymbolTablePutDefOp("r8b",     NaClOperandForm_r8b,       defop_st);
1597     NaClSymbolTablePutDefOp("r8v",     NaClOperandForm_r8v,       defop_st);
1598     NaClSymbolTablePutDefOp("r8vd",    NaClOperandForm_r8vd,      defop_st);
1599     NaClSymbolTablePutDefOp("r8vq",    NaClOperandForm_r8vq,      defop_st);
1600     NaClSymbolTablePutDefOp("SGz",     NaClOperandForm_SGz,       defop_st);
1601     NaClSymbolTablePutDefOp("Sw",      NaClOperandForm_Sw,        defop_st);
1602     NaClSymbolTablePutDefOp("Udq",     NaClOperandForm_Udq,       defop_st);
1603     NaClSymbolTablePutDefOp("Udq/Md",  NaClOperandForm_UdqMd,     defop_st);
1604     NaClSymbolTablePutDefOp("Udq/Mq",  NaClOperandForm_UdqMq,     defop_st);
1605     NaClSymbolTablePutDefOp("Udq/Mw",  NaClOperandForm_UdqMw,     defop_st);
1606     NaClSymbolTablePutDefOp("Vdq",     NaClOperandForm_Vdq,       defop_st);
1607     NaClSymbolTablePutDefOp("Vd/q",    NaClOperandForm_VdSlq,     defop_st);
1608     NaClSymbolTablePutDefOp("Vd/q/d",  NaClOperandForm_VdSlqSld,  defop_st);
1609     NaClSymbolTablePutDefOp("Vd/q/q",  NaClOperandForm_VdSlqSlq,  defop_st);
1610     NaClSymbolTablePutDefOp("Vpd",     NaClOperandForm_Vpd,       defop_st);
1611     NaClSymbolTablePutDefOp("Vps",     NaClOperandForm_Vps,       defop_st);
1612     NaClSymbolTablePutDefOp("Vq",      NaClOperandForm_Vq,        defop_st);
1613     NaClSymbolTablePutDefOp("Vsd",     NaClOperandForm_Vsd,       defop_st);
1614     NaClSymbolTablePutDefOp("Vss",     NaClOperandForm_Vss,       defop_st);
1615     NaClSymbolTablePutDefOp("VRdq",    NaClOperandForm_VRdq,      defop_st);
1616     NaClSymbolTablePutDefOp("VRpd",    NaClOperandForm_VRpd,      defop_st);
1617     NaClSymbolTablePutDefOp("VRps",    NaClOperandForm_VRps,      defop_st);
1618     NaClSymbolTablePutDefOp("VRq",     NaClOperandForm_VRq,       defop_st);
1619     NaClSymbolTablePutDefOp("Wdq",     NaClOperandForm_Wdq,       defop_st);
1620     NaClSymbolTablePutDefOp("Wpd",     NaClOperandForm_Wpd,       defop_st);
1621     NaClSymbolTablePutDefOp("Wps",     NaClOperandForm_Wps,       defop_st);
1622     NaClSymbolTablePutDefOp("Wq",      NaClOperandForm_Wq,        defop_st);
1623     NaClSymbolTablePutDefOp("Wsd",     NaClOperandForm_Wsd,       defop_st);
1624     NaClSymbolTablePutDefOp("Wss",     NaClOperandForm_Wss,       defop_st);
1625     NaClSymbolTablePutDefOp("Xb",      NaClOperandForm_Xb,        defop_st);
1626     NaClSymbolTablePutDefOp("Xvd",     NaClOperandForm_Xvd,       defop_st);
1627     NaClSymbolTablePutDefOp("Xvq",     NaClOperandForm_Xvq,       defop_st);
1628     NaClSymbolTablePutDefOp("Xvw",     NaClOperandForm_Xvw,       defop_st);
1629     NaClSymbolTablePutDefOp("Xzw",     NaClOperandForm_Xzw,       defop_st);
1630     NaClSymbolTablePutDefOp("Xzd",     NaClOperandForm_Xzd,       defop_st);
1631     NaClSymbolTablePutDefOp("Yb",      NaClOperandForm_Yb,        defop_st);
1632     NaClSymbolTablePutDefOp("Yvd",     NaClOperandForm_Yvd,       defop_st);
1633     NaClSymbolTablePutDefOp("Yvq",     NaClOperandForm_Yvq,       defop_st);
1634     NaClSymbolTablePutDefOp("Yvw",     NaClOperandForm_Yvw,       defop_st);
1635     NaClSymbolTablePutDefOp("Yzd",     NaClOperandForm_Yzd,       defop_st);
1636     NaClSymbolTablePutDefOp("Yzw",     NaClOperandForm_Yzw,       defop_st);
1637     NaClSymbolTablePutDefOp("Zvd",     NaClOperandForm_Zvd,       defop_st);
1638   }
1639   value = NaClSymbolTableGet(form, defop_st);
1640   if (NULL == value || (value->kind != nacl_defop)) {
1641     NaClDefFatal("Malformed $defop form");
1642   }
1643   value->value.defop_value();
1644 }
1645
1646 /* Given a string describing the operand, define the corresponding
1647  * operand. Returns the set of operand flags that must be
1648  * defined for the operand, based on the contents of the operand string.
1649  *
1650  * Note: See ??? for descriptions of legal operand strings.
1651  */
1652 static NaClOpFlags NaClExtractOperand(const char* operand) {
1653   NaClOpFlags op_flags = NACL_EMPTY_OPFLAGS;
1654   switch (*operand) {
1655     case '{':
1656       if ('}' == operand[strlen(operand) - 1]) {
1657         char buffer[BUFSIZE];
1658         strcpy(buffer, operand+1);
1659         buffer[strlen(buffer)-1] = '\0';
1660         op_flags =
1661             NaClExtractOperand(buffer) |
1662             NACL_OPFLAG(OpImplicit);
1663       } else {
1664         NaClDefFatal("Malformed implicit braces");
1665       }
1666       break;
1667     case '1':
1668       if (1 == strlen(operand)) {
1669         NaClOperandForm_One();
1670       } else {
1671         NaClDefFatal("Malformed operand argument");
1672       }
1673       break;
1674     case '%':
1675       NaClExtractRegister(operand+1);
1676       break;
1677     case '$':
1678       NaClExtractOperandForm(operand+1);
1679       break;
1680     default:
1681       NaClDefFatal("Malformed operand argument");
1682   }
1683   return op_flags;
1684 }
1685
1686 /* Given a string describing the operand, and an index corresponding
1687  * to the position of the operand in the corresponding opcode description
1688  * string, define the corresponding operand in the model being generated.
1689  */
1690 static void NaClParseOperand(const char* operand, int arg_index) {
1691   NaClAddOpFlags(arg_index, NaClExtractOperand(operand));
1692   NaClAddOpFormat(arg_index, operand);
1693 }
1694
1695 void NaClBegDef(const char* desc, NaClInstType insttype,
1696                 struct NaClSymbolTable* st) {
1697   char* name;
1698   char* arg;
1699   int num_args = 0;
1700   char buffer[BUFSIZE];
1701   char expanded_desc[BUFSIZE];
1702   char* opcode;
1703   char* assem_desc;
1704   NaClMnemonic mnemonic;
1705   char* old_kdesc = kCachedDesc;
1706   kCachedDesc = (char*) desc;
1707
1708   /* Do symbol table substitutions. */
1709   strcpy(buffer, desc);
1710   NaClStExpand(buffer, st);
1711   strcpy(expanded_desc, buffer);
1712   kCachedDesc = expanded_desc;
1713
1714   /* Separate the description into opcode sequence and
1715    * assembly description.
1716    */
1717   opcode = strtok(buffer, ":");
1718   if (NULL == opcode) {
1719     NaClDefFatal("opcode not separated from assembly description using ':'");
1720   }
1721   assem_desc = strtok(NULL, ":");
1722   if (NULL == assem_desc) {
1723     NaClDefFatal("Can't find assembly description");
1724   }
1725   if (NULL != strtok(NULL, ":")) {
1726     NaClDefFatal("Malformed assembly description");
1727   }
1728
1729   /* extract nmemonic name of instruction. */
1730   name = strtok(assem_desc, " ");
1731   if (NULL == name) {
1732     NaClDefFatal("Can't find mnemonic name");
1733   }
1734   mnemonic = NaClAssemName(name);
1735   NaClDelaySanityChecks();
1736   NaClParseOpcode(opcode, insttype, mnemonic, st);
1737
1738   /* Now extract operands. */
1739   while ((arg = strtok(NULL, ", "))) {
1740     NaClParseOperand(arg, num_args);
1741     ++num_args;
1742     if (num_args == MAX_OPERANDS) {
1743       NaClDefFatal("Too many operands");
1744     }
1745   }
1746   kCachedDesc = old_kdesc;
1747 }
1748
1749 void NaClBegD32(const char* desc, NaClInstType insttype,
1750                 struct NaClSymbolTable* st) {
1751   NaClBegDef(desc, insttype, st);
1752   NaClAddIFlags(NACL_IFLAG(Opcode32Only));
1753 }
1754
1755 void NaClBegD64(const char* desc, NaClInstType insttype,
1756                 struct NaClSymbolTable* st) {
1757   NaClBegDef(desc, insttype, st);
1758   NaClAddIFlags(NACL_IFLAG(Opcode64Only));
1759 }
1760
1761 void NaClBegDefPlatform(NaClTargetPlatform platform,
1762                         const char* desc, NaClInstType insttype,
1763                         struct NaClSymbolTable* st) {
1764   switch (platform) {
1765     case T32:
1766       NaClBegD32(desc, insttype, st);
1767       break;
1768     case T64:
1769       NaClBegD64(desc, insttype, st);
1770       break;
1771     case Tall:
1772       NaClBegDef(desc, insttype, st);
1773       break;
1774     default:
1775       /* This shouldn't happen. */
1776       NaClDefFatal("Don't understand platform");
1777   }
1778 }
1779
1780 void NaClEndDef(NaClInstCat icat) {
1781   NaClSetInstCat(icat);
1782   NaClApplySanityChecks();
1783   NaClResetToDefaultInstPrefix();
1784 }
1785
1786 void NaClDefine(const char* desc, NaClInstType insttype,
1787                 struct NaClSymbolTable* st, NaClInstCat cat) {
1788   NaClBegDef(desc, insttype, st);
1789   NaClEndDef(cat);
1790 }
1791
1792 void NaClDef_32(const char* desc, NaClInstType insttype,
1793                 struct NaClSymbolTable* st, NaClInstCat cat) {
1794   NaClBegD32(desc, insttype, st);
1795   NaClEndDef(cat);
1796 }
1797
1798 void NaClDef_64(const char* desc, NaClInstType insttype,
1799                 struct NaClSymbolTable* st, NaClInstCat cat) {
1800   NaClBegD64(desc, insttype, st);
1801   NaClEndDef(cat);
1802 }
1803
1804 void NaClDefinePlatform(NaClTargetPlatform platform,
1805                         const char* desc, NaClInstType insttype,
1806                         struct NaClSymbolTable* st, NaClInstCat cat) {
1807   switch (platform) {
1808     case T32:
1809       NaClDef_32(desc, insttype, st, cat);
1810       break;
1811     case T64:
1812       NaClDef_64(desc, insttype, st, cat);
1813       break;
1814     case Tall:
1815       NaClDefine(desc, insttype, st, cat);
1816       break;
1817     default:
1818       /* This shouldn't happen. */
1819       NaClDefFatal("Don't understand platform");
1820   }
1821 }
1822
1823 /* Generate an error message for the given instruction description,
1824  * if min <0 or max > 7.
1825  */
1826 static void NaClDefCheckRange(const char* desc, int min, int max, int cutoff) {
1827   if (min < 0) {
1828     NaClDefDescFatal(desc, "Minimum value must be >= 0");
1829   } else if (max > cutoff) {
1830     char buffer[BUF_SIZE];
1831     SNPRINTF(buffer, BUF_SIZE, "Maximum value must be <= %d", cutoff);
1832     NaClDefDescFatal(desc, buffer);
1833   }
1834 }
1835
1836 /* Define a symbol table size that can hold a small number of
1837  * symbols (i.e. limit to at most 5 definitions).
1838  */
1839 #define NACL_SMALL_ST (5)
1840
1841 void NaClDefReg(const char* desc, int min, int max,
1842                 NaClInstType insttype, struct NaClSymbolTable* context_st,
1843                 NaClInstCat cat) {
1844   int i;
1845   struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
1846   NaClDefCheckRange(desc, min, max, kMaxRegisterIndexInOpcode);
1847   for (i = min; i <= max; ++i) {
1848     NaClSymbolTablePutInt("reg", i, st);
1849     NaClDefine(desc, insttype, st, cat);
1850   }
1851   NaClSymbolTableDestroy(st);
1852 }
1853
1854 void NaClDefIter(const char* desc, int min, int max,
1855                  NaClInstType insttype, struct NaClSymbolTable* context_st,
1856                  NaClInstCat cat) {
1857   int i;
1858   struct NaClSymbolTable* st = NaClSymbolTableCreate(NACL_SMALL_ST, context_st);
1859   NaClDefCheckRange(desc, min, max, NCDTABLESIZE);
1860   NaClSymbolTablePutInt("add_reg?", 1, st);
1861   for (i = min; i <= max; ++i) {
1862     NaClSymbolTablePutInt("i", i, st);
1863     NaClDefine(desc, insttype, st, cat);
1864   }
1865   NaClSymbolTableDestroy(st);
1866 }